Merge
diff --git a/.hgtags-top-repo b/.hgtags-top-repo
index 3d22910..f74c0bc 100644
--- a/.hgtags-top-repo
+++ b/.hgtags-top-repo
@@ -211,3 +211,4 @@
 b9415faa7066a4d3b16d466556d5428446918d95 jdk8-b87
 e1a929afcfc492470d50be0b6b0e8dc77d3760b9 jdk8-b88
 892a0196d10c67f3a12f0eefb0bb536e423d8868 jdk8-b89
+69b773a221b956a3386933ecdbfeccee0edeac47 jdk8-b90
diff --git a/NewMakefile.gmk b/NewMakefile.gmk
index b02e37f..0331832 100644
--- a/NewMakefile.gmk
+++ b/NewMakefile.gmk
@@ -73,7 +73,7 @@
             grep ^.PHONY: | head -n 1 | cut -d " " -f 2-)))
 
 $(all_phony_targets):
-	@$(foreach spec,$(SPEC),($(MAKE) -f NewMakefile.gmk SPEC=$(spec) $(VERBOSE) VERBOSE=$(VERBOSE) $@) &&) true
+	@$(foreach spec,$(SPEC),($(MAKE) -f NewMakefile.gmk SPEC=$(spec) $(VERBOSE) VERBOSE=$(VERBOSE) LOG_LEVEL=$(LOG_LEVEL) $@) &&) true
 
     endif
 endif
diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in
index 2172ee8..a7e66a3 100644
--- a/common/autoconf/spec.gmk.in
+++ b/common/autoconf/spec.gmk.in
@@ -54,9 +54,9 @@
 
 MAKE:=@MAKE@
 
-# Pass along the verbosity setting.
+# Pass along the verbosity and log level settings.
 ifeq (,$(findstring VERBOSE=,$(MAKE)))
-    MAKE:=$(MAKE) $(VERBOSE) VERBOSE="$(VERBOSE)"
+    MAKE:=$(MAKE) $(VERBOSE) VERBOSE="$(VERBOSE)" LOG_LEVEL="$(LOG_LEVEL)"
 endif
 
 # No implicit variables or rules!
diff --git a/common/makefiles/Main.gmk b/common/makefiles/Main.gmk
index 145fbad..d07f3e2 100644
--- a/common/makefiles/Main.gmk
+++ b/common/makefiles/Main.gmk
@@ -240,10 +240,10 @@
 clean-test:
 	$(call CleanComponent,testoutput)
 
-.PHONY: langtools corba jaxp jaxws hotspot jdk nashorn images overlay-images install
-.PHONY: langtools-only corba-only jaxp-only jaxws-only hotspot-only jdk-only nashorn-only images-only overlay-images-only install-only
-.PHONY: all test clean dist-clean bootcycle-images start-make
-.PHONY: clean-langtools clean-corba clean-jaxp clean-jaxws clean-hotspot clean-jdk clean-nashorn clean-images clean-overlay-images clean-bootcycle-build
+.PHONY: langtools corba jaxp jaxws hotspot jdk nashorn images overlay-images install test docs
+.PHONY: langtools-only corba-only jaxp-only jaxws-only hotspot-only jdk-only nashorn-only images-only overlay-images-only install-only test-only docs-only
+.PHONY: all clean dist-clean bootcycle-images start-make
+.PHONY: clean-langtools clean-corba clean-jaxp clean-jaxws clean-hotspot clean-jdk clean-nashorn clean-images clean-docs clean-test clean-overlay-images clean-bootcycle-build
 .PHONY: profiles profiles-only profiles-oscheck
 
 FRC: # Force target
diff --git a/common/makefiles/NativeCompilation.gmk b/common/makefiles/NativeCompilation.gmk
index 2e084ea..c3b2766 100644
--- a/common/makefiles/NativeCompilation.gmk
+++ b/common/makefiles/NativeCompilation.gmk
@@ -321,11 +321,17 @@
 
     ifneq (,$$($1_DEBUG_SYMBOLS))	
         ifeq ($(ENABLE_DEBUG_SYMBOLS), true)
-            # Programs don't get the debug symbols added in the old build. It's not clear if
-            # this is intentional.
-            ifeq ($$($1_PROGRAM),)
+	    ifdef OPENJDK
+	        # Always add debug symbols
                 $1_EXTRA_CFLAGS+=$(CFLAGS_DEBUG_SYMBOLS)
                 $1_EXTRA_CXXFLAGS+=$(CXXFLAGS_DEBUG_SYMBOLS)
+	    else
+                # Programs don't get the debug symbols added in the old build. It's not clear if
+                # this is intentional.
+                ifeq ($$($1_PROGRAM),)
+                    $1_EXTRA_CFLAGS+=$(CFLAGS_DEBUG_SYMBOLS)
+                    $1_EXTRA_CXXFLAGS+=$(CXXFLAGS_DEBUG_SYMBOLS)
+                endif
             endif
         endif
     endif
diff --git a/corba/.hgtags b/corba/.hgtags
index 45d7f0a..20b78fa 100644
--- a/corba/.hgtags
+++ b/corba/.hgtags
@@ -211,3 +211,4 @@
 f1709874d55a06bc3d5dfa02dbcdfbc59f4cba34 jdk8-b87
 4e3a881ebb1ee96ce0872508b0066d74f310dbfa jdk8-b88
 fe4150590ee597f4e125fea950aa3b352622cc2d jdk8-b89
+c8286839d0df04aba819ec4bef12b86babccf30e jdk8-b90
diff --git a/hotspot/.hgtags b/hotspot/.hgtags
index fb98d2c..f202d86 100644
--- a/hotspot/.hgtags
+++ b/hotspot/.hgtags
@@ -341,3 +341,5 @@
 4ec91349972255650f97bedfd07e6423e02428cf hs25-b31
 9c1fe0b419b40a9ecdd1653cc9af1b6d67a12c46 jdk8-b89
 69494caf57908ba2c8efa9eaaa472b4d1875588a hs25-b32
+1ae0472ff3a0117b5b019d380ad59fface2fde14 jdk8-b90
+b19517cecc2e91636d7c16ba2f35e3d3dc628099 hs25-b33
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java
index 3468b0d..d50e36c 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java
@@ -97,8 +97,8 @@
                   holder.getName().asString() + " " +
                   OopUtilities.escapeString(method.getName().asString()) + " " +
                   method.getSignature().asString() + " " +
-                  method.getInvocationCounter() + " " +
-                  method.getBackedgeCounter() + " " +
+                  method.getInvocationCount() + " " +
+                  method.getBackedgeCount() + " " +
                   interpreterInvocationCount() + " " +
                   interpreterThrowoutCount() + " " +
                   instructionsSize());
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java
index c61d58d..e039470 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java
@@ -24,15 +24,21 @@
 
 package sun.jvm.hotspot.oops;
 
-import java.io.*;
-import java.util.*;
-import sun.jvm.hotspot.code.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.interpreter.*;
-import sun.jvm.hotspot.memory.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.types.*;
-import sun.jvm.hotspot.utilities.*;
+import java.io.PrintStream;
+import java.util.Observable;
+import java.util.Observer;
+
+import sun.jvm.hotspot.code.NMethod;
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.interpreter.OopMapCacheEntry;
+import sun.jvm.hotspot.runtime.SignatureConverter;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.runtime.VMObjectFactory;
+import sun.jvm.hotspot.types.AddressField;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+import sun.jvm.hotspot.types.WrongTypeException;
+import sun.jvm.hotspot.utilities.Assert;
 
 // A Method represents a Java method
 
@@ -132,11 +138,13 @@
   public long         getAccessFlags()                { return                accessFlags.getValue(this);       }
   public long         getCodeSize()                   { return                getConstMethod().getCodeSize();   }
   public long         getVtableIndex()                { return                vtableIndex.getValue(this);       }
-  public long         getInvocationCounter()          {
-    return getMethodCounters().getInvocationCounter();
+  public long         getInvocationCount()          {
+    MethodCounters mc = getMethodCounters();
+    return mc == null ? 0 : mc.getInvocationCounter();
   }
-  public long         getBackedgeCounter()          {
-    return getMethodCounters().getBackedgeCounter();
+  public long         getBackedgeCount()          {
+    MethodCounters mc = getMethodCounters();
+    return mc == null ? 0 : mc.getBackedgeCounter();
   }
 
   // get associated compiled native method, if available, else return null.
@@ -349,8 +357,8 @@
                   holder.getName().asString() + " " +
                   OopUtilities.escapeString(getName().asString()) + " " +
                   getSignature().asString() + " " +
-                  getInvocationCounter() + " " +
-                  getBackedgeCounter() + " " +
+                  getInvocationCount() + " " +
+                  getBackedgeCount() + " " +
                   interpreterInvocationCount() + " " +
                   interpreterThrowoutCount() + " " +
                   code_size);
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java
index a397ec3..eb64348 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java
@@ -316,8 +316,8 @@
     int iic = method.interpreterInvocationCount();
     if (mileage < iic)  mileage = iic;
 
-    long ic = method.getInvocationCounter();
-    long bc = method.getBackedgeCounter();
+    long ic = method.getInvocationCount();
+    long bc = method.getBackedgeCount();
 
     long icval = ic >> 3;
     if ((ic & 4) != 0) icval += CompileThreshold;
diff --git a/hotspot/make/Makefile b/hotspot/make/Makefile
index e0d9826..526ed23 100644
--- a/hotspot/make/Makefile
+++ b/hotspot/make/Makefile
@@ -151,32 +151,43 @@
 		      $(MAKE_ARGS) BUILD_FLAVOR=product docs
 endif
 
+# Output directories
+C1_DIR      =$(OUTPUTDIR)/$(VM_PLATFORM)_compiler1
+C2_DIR      =$(OUTPUTDIR)/$(VM_PLATFORM)_compiler2
+MINIMAL1_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_minimal1
+ZERO_DIR    =$(OUTPUTDIR)/$(VM_PLATFORM)_zero
+SHARK_DIR   =$(OUTPUTDIR)/$(VM_PLATFORM)_shark
+
 # Build variation of hotspot
 $(C1_VM_TARGETS):
 	$(CD) $(GAMMADIR)/make; \
-	$(MAKE) BUILD_FLAVOR=$(@:%1=%) VM_TARGET=$@ generic_build1 $(ALT_OUT)
+	$(MAKE) BUILD_DIR=$(C1_DIR) BUILD_FLAVOR=$(@:%1=%) VM_TARGET=$@ generic_build1 $(ALT_OUT)
 
 $(C2_VM_TARGETS):
 	$(CD) $(GAMMADIR)/make; \
-	$(MAKE) BUILD_FLAVOR=$@ VM_TARGET=$@ generic_build2 $(ALT_OUT)
+	$(MAKE) BUILD_DIR=$(C2_DIR) BUILD_FLAVOR=$@ VM_TARGET=$@ generic_build2 $(ALT_OUT)
 
 $(ZERO_VM_TARGETS):
 	$(CD) $(GAMMADIR)/make; \
-	$(MAKE) BUILD_FLAVOR=$(@:%zero=%) VM_TARGET=$@ \
-	  generic_buildzero $(ALT_OUT)
+	$(MAKE) BUILD_DIR=$(ZERO_DIR) BUILD_FLAVOR=$(@:%zero=%) VM_TARGET=$@ generic_buildzero $(ALT_OUT)
 
 $(SHARK_VM_TARGETS):
 	$(CD) $(GAMMADIR)/make; \
-	$(MAKE) BUILD_FLAVOR=$(@:%shark=%) VM_TARGET=$@ \
-	  generic_buildshark $(ALT_OUT)
+	$(MAKE) BUILD_DIR=$(SHARK_DIR) BUILD_FLAVOR=$(@:%shark=%) VM_TARGET=$@ generic_buildshark $(ALT_OUT)
 
 $(MINIMAL1_VM_TARGETS):
 	$(CD) $(GAMMADIR)/make; \
-	$(MAKE) BUILD_FLAVOR=$(@:%minimal1=%) VM_TARGET=$@ \
-	  generic_buildminimal1 $(ALT_OUT)
+	$(MAKE) BUILD_DIR=$(MINIMAL1_DIR) BUILD_FLAVOR=$(@:%minimal1=%) VM_TARGET=$@ generic_buildminimal1 $(ALT_OUT)
+
+# Install hotspot script in build directory
+HOTSPOT_SCRIPT=$(BUILD_DIR)/$(BUILD_FLAVOR)/hotspot
+$(HOTSPOT_SCRIPT): $(GAMMADIR)/make/hotspot.script
+	$(QUIETLY) $(MKDIR) -p $(BUILD_DIR)/$(BUILD_FLAVOR)
+	$(QUIETLY) cat $< | sed -e 's|@@LIBARCH@@|$(LIBARCH)|g' | sed -e 's|@@JDK_IMPORT_PATH@@|$(JDK_IMPORT_PATH)|g' > $@
+	$(QUIETLY) chmod +x $@
 
 # Build compiler1 (client) rule, different for platforms
-generic_build1:
+generic_build1: $(HOTSPOT_SCRIPT)
 	$(MKDIR) -p $(OUTPUTDIR)
 ifeq ($(OSNAME),windows)
   ifeq ($(ARCH_DATA_MODEL), 32)
@@ -201,7 +212,7 @@
 endif
 
 # Build compiler2 (server) rule, different for platforms
-generic_build2:
+generic_build2: $(HOTSPOT_SCRIPT)
 	$(MKDIR) -p $(OUTPUTDIR)
 ifeq ($(OSNAME),windows)
 	$(CD) $(OUTPUTDIR); \
@@ -217,19 +228,19 @@
 		      $(MAKE_ARGS) $(VM_TARGET)
 endif
 
-generic_buildzero:
+generic_buildzero: $(HOTSPOT_SCRIPT)
 	$(MKDIR) -p $(OUTPUTDIR)
 	$(CD) $(OUTPUTDIR); \
 		$(MAKE) -f $(ABS_OS_MAKEFILE) \
 			$(MAKE_ARGS) $(VM_TARGET)
 
-generic_buildshark:
+generic_buildshark: $(HOTSPOT_SCRIPT)
 	$(MKDIR) -p $(OUTPUTDIR)
 	$(CD) $(OUTPUTDIR); \
 		$(MAKE) -f $(ABS_OS_MAKEFILE) \
 			$(MAKE_ARGS) $(VM_TARGET)
 
-generic_buildminimal1:
+generic_buildminimal1: $(HOTSPOT_SCRIPT)
 ifeq ($(JVM_VARIANT_MINIMAL1),true)
 	$(MKDIR) -p $(OUTPUTDIR)
   ifeq ($(ARCH_DATA_MODEL), 32)
@@ -252,224 +263,210 @@
 
 # Export file rule
 generic_export: $(EXPORT_LIST)
+
 export_product:
-	$(MAKE) BUILD_FLAVOR=$(@:export_%=%) VM_SUBDIR=$(@:export_%=%) \
-          generic_export
+	$(MAKE) BUILD_FLAVOR=$(@:export_%=%) generic_export
 export_fastdebug:
-	$(MAKE) BUILD_FLAVOR=$(@:export_%=%) VM_SUBDIR=$(@:export_%=%) \
-	  EXPORT_SUBDIR=/$(@:export_%=%) \
-	  generic_export
+	$(MAKE) BUILD_FLAVOR=$(@:export_%=%) EXPORT_SUBDIR=/$(@:export_%=%) generic_export
 export_debug:
-	$(MAKE) BUILD_FLAVOR=$(@:export_%=%) VM_SUBDIR=$(@:export_%=%) \
-	  EXPORT_SUBDIR=/$(@:export_%=%) \
-	  generic_export
+	$(MAKE) BUILD_FLAVOR=$(@:export_%=%) EXPORT_SUBDIR=/$(@:export_%=%) generic_export
 export_optimized:
-	$(MAKE) BUILD_FLAVOR=$(@:export_%=%) VM_SUBDIR=$(@:export_%=%) \
-	  EXPORT_SUBDIR=/$(@:export_%=%) \
-	  generic_export
+	$(MAKE) BUILD_FLAVOR=$(@:export_%=%) EXPORT_SUBDIR=/$(@:export_%=%) generic_export
+
 export_product_jdk::
-	$(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) \
-	  VM_SUBDIR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) \
-	  generic_export
+	$(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) generic_export
 export_optimized_jdk::
-	$(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) \
-	  VM_SUBDIR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) \
-	  generic_export
+	$(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) generic_export
 export_fastdebug_jdk::
-	$(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) \
-	  VM_SUBDIR=$(@:export_%_jdk=%)  \
-	  ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/$(@:export_%_jdk=%) \
-	  generic_export
+	$(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/$(@:export_%_jdk=%) generic_export
 export_debug_jdk::
-	$(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) VM_SUBDIR=$(@:export_%_jdk=%) \
-	  ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/$(@:export_%_jdk=%) \
-	  generic_export
+	$(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/$(@:export_%_jdk=%) generic_export
 
 # Export file copy rules
 XUSAGE=$(HS_SRC_DIR)/share/vm/Xusage.txt
-DOCS_DIR    =$(OUTPUTDIR)/$(VM_PLATFORM)_docs
-C1_DIR      =$(OUTPUTDIR)/$(VM_PLATFORM)_compiler1/$(VM_SUBDIR)
-C2_DIR      =$(OUTPUTDIR)/$(VM_PLATFORM)_compiler2/$(VM_SUBDIR)
-MINIMAL1_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_minimal1/$(VM_SUBDIR)
-ZERO_DIR    =$(OUTPUTDIR)/$(VM_PLATFORM)_zero/$(VM_SUBDIR)
-SHARK_DIR   =$(OUTPUTDIR)/$(VM_PLATFORM)_shark/$(VM_SUBDIR)
+DOCS_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_docs
+C1_BUILD_DIR      =$(C1_DIR)/$(BUILD_FLAVOR)
+C2_BUILD_DIR      =$(C2_DIR)/$(BUILD_FLAVOR)
+MINIMAL1_BUILD_DIR=$(MINIMAL1_DIR)/$(BUILD_FLAVOR)
+ZERO_BUILD_DIR    =$(ZERO_DIR)/$(BUILD_FLAVOR)
+SHARK_BUILD_DIR   =$(SHARK_DIR)/$(BUILD_FLAVOR)
 
 # Server (C2)
 ifeq ($(JVM_VARIANT_SERVER), true)
 # Common
-$(EXPORT_SERVER_DIR)/%.diz:       		$(C2_DIR)/%.diz
+$(EXPORT_SERVER_DIR)/%.diz:       		$(C2_BUILD_DIR)/%.diz
 	$(install-file)
-$(EXPORT_LIB_DIR)/%.jar:			$(C2_DIR)/../generated/%.jar
+$(EXPORT_LIB_DIR)/%.jar:			$(C2_BUILD_DIR)/../generated/%.jar
 	$(install-file)
-$(EXPORT_INCLUDE_DIR)/%:			$(C2_DIR)/../generated/jvmtifiles/%
+$(EXPORT_INCLUDE_DIR)/%:			$(C2_BUILD_DIR)/../generated/jvmtifiles/%
 	$(install-file)
 # Windows
-$(EXPORT_SERVER_DIR)/%.dll:			$(C2_DIR)/%.dll
+$(EXPORT_SERVER_DIR)/%.dll:			$(C2_BUILD_DIR)/%.dll
 	$(install-file)
-$(EXPORT_SERVER_DIR)/%.pdb:			$(C2_DIR)/%.pdb
+$(EXPORT_SERVER_DIR)/%.pdb:			$(C2_BUILD_DIR)/%.pdb
 	$(install-file)
-$(EXPORT_SERVER_DIR)/%.map:			$(C2_DIR)/%.map
+$(EXPORT_SERVER_DIR)/%.map:			$(C2_BUILD_DIR)/%.map
 	$(install-file)
-$(EXPORT_LIB_DIR)/%.lib:			$(C2_DIR)/%.lib
+$(EXPORT_LIB_DIR)/%.lib:			$(C2_BUILD_DIR)/%.lib
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.diz:			$(C2_DIR)/%.diz
+$(EXPORT_JRE_BIN_DIR)/%.diz:			$(C2_BUILD_DIR)/%.diz
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.dll:			$(C2_DIR)/%.dll
+$(EXPORT_JRE_BIN_DIR)/%.dll:			$(C2_BUILD_DIR)/%.dll
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.pdb:			$(C2_DIR)/%.pdb
+$(EXPORT_JRE_BIN_DIR)/%.pdb:			$(C2_BUILD_DIR)/%.pdb
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.map:			$(C2_DIR)/%.map
+$(EXPORT_JRE_BIN_DIR)/%.map:			$(C2_BUILD_DIR)/%.map
 	$(install-file)
 # Unix
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C2_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(C2_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(C2_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_SERVER_DIR)/64/%.$(LIBRARY_SUFFIX):    $(C2_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_SERVER_DIR)/64/%.$(LIBRARY_SUFFIX):    $(C2_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: 	$(C2_DIR)/%.debuginfo
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: 	$(C2_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_SERVER_DIR)/%.debuginfo:       	$(C2_DIR)/%.debuginfo
+$(EXPORT_SERVER_DIR)/%.debuginfo:       	$(C2_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_SERVER_DIR)/64/%.debuginfo:    	$(C2_DIR)/%.debuginfo
+$(EXPORT_SERVER_DIR)/64/%.debuginfo:    	$(C2_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: 		$(C2_DIR)/%.diz
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: 		$(C2_BUILD_DIR)/%.diz
 	$(install-file)
-$(EXPORT_SERVER_DIR)/64/%.diz:    		$(C2_DIR)/%.diz
+$(EXPORT_SERVER_DIR)/64/%.diz:    		$(C2_BUILD_DIR)/%.diz
 	$(install-file)
 endif
 
 # Client (C1)
 ifeq ($(JVM_VARIANT_CLIENT), true)
 # Common
-$(EXPORT_CLIENT_DIR)/%.diz:       		$(C1_DIR)/%.diz
+$(EXPORT_CLIENT_DIR)/%.diz:       		$(C1_BUILD_DIR)/%.diz
 	$(install-file)
-$(EXPORT_LIB_DIR)/%.jar:			$(C1_DIR)/../generated/%.jar
+$(EXPORT_LIB_DIR)/%.jar:			$(C1_BUILD_DIR)/../generated/%.jar
 	$(install-file)
-$(EXPORT_INCLUDE_DIR)/%:			$(C1_DIR)/../generated/jvmtifiles/%
+$(EXPORT_INCLUDE_DIR)/%:			$(C1_BUILD_DIR)/../generated/jvmtifiles/%
 	$(install-file)
 # Windows
-$(EXPORT_CLIENT_DIR)/%.dll:			$(C1_DIR)/%.dll
+$(EXPORT_CLIENT_DIR)/%.dll:			$(C1_BUILD_DIR)/%.dll
 	$(install-file)
-$(EXPORT_CLIENT_DIR)/%.pdb:			$(C1_DIR)/%.pdb
+$(EXPORT_CLIENT_DIR)/%.pdb:			$(C1_BUILD_DIR)/%.pdb
 	$(install-file)
-$(EXPORT_CLIENT_DIR)/%.map:			$(C1_DIR)/%.map
+$(EXPORT_CLIENT_DIR)/%.map:			$(C1_BUILD_DIR)/%.map
 	$(install-file)
-$(EXPORT_LIB_DIR)/%.lib:			$(C1_DIR)/%.lib
+$(EXPORT_LIB_DIR)/%.lib:			$(C1_BUILD_DIR)/%.lib
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.diz:			$(C1_DIR)/%.diz
+$(EXPORT_JRE_BIN_DIR)/%.diz:			$(C1_BUILD_DIR)/%.diz
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.dll:			$(C1_DIR)/%.dll
+$(EXPORT_JRE_BIN_DIR)/%.dll:			$(C1_BUILD_DIR)/%.dll
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.pdb:			$(C1_DIR)/%.pdb
+$(EXPORT_JRE_BIN_DIR)/%.pdb:			$(C1_BUILD_DIR)/%.pdb
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.map:			$(C1_DIR)/%.map
+$(EXPORT_JRE_BIN_DIR)/%.map:			$(C1_BUILD_DIR)/%.map
 	$(install-file)
 # Unix
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_CLIENT_DIR)/%.$(LIBRARY_SUFFIX):       $(C1_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_CLIENT_DIR)/%.$(LIBRARY_SUFFIX):       $(C1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_CLIENT_DIR)/64/%.$(LIBRARY_SUFFIX):    $(C1_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_CLIENT_DIR)/64/%.$(LIBRARY_SUFFIX):    $(C1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: 	$(C1_DIR)/%.debuginfo
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: 	$(C1_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_CLIENT_DIR)/%.debuginfo:       	$(C1_DIR)/%.debuginfo
+$(EXPORT_CLIENT_DIR)/%.debuginfo:       	$(C1_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_CLIENT_DIR)/64/%.debuginfo:    	$(C1_DIR)/%.debuginfo
+$(EXPORT_CLIENT_DIR)/64/%.debuginfo:    	$(C1_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: 		$(C1_DIR)/%.diz
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: 		$(C1_BUILD_DIR)/%.diz
 	$(install-file)
-$(EXPORT_CLIENT_DIR)/64/%.diz:    		$(C1_DIR)/%.diz
+$(EXPORT_CLIENT_DIR)/64/%.diz:    		$(C1_BUILD_DIR)/%.diz
 	$(install-file)
 endif
 
 # Minimal1
 ifeq ($(JVM_VARIANT_MINIMAL1), true)
 # Common
-$(EXPORT_MINIMAL_DIR)/%.diz:			$(MINIMAL1_DIR)/%.diz
+$(EXPORT_MINIMAL_DIR)/%.diz:			$(MINIMAL1_BUILD_DIR)/%.diz
 	$(install-file)
-$(EXPORT_LIB_DIR)/%.jar:			$(MINIMAL1_DIR)/../generated/%.jar
+$(EXPORT_LIB_DIR)/%.jar:			$(MINIMAL1_BUILD_DIR)/../generated/%.jar
 	$(install-file)
-$(EXPORT_INCLUDE_DIR)/%:			$(MINIMAL1_DIR)/../generated/jvmtifiles/%
+$(EXPORT_INCLUDE_DIR)/%:			$(MINIMAL1_BUILD_DIR)/../generated/jvmtifiles/%
 	$(install-file)
 # Windows
-$(EXPORT_MINIMAL_DIR)/%.dll:			$(MINIMAL1_DIR)/%.dll
+$(EXPORT_MINIMAL_DIR)/%.dll:			$(MINIMAL1_BUILD_DIR)/%.dll
 	$(install-file)
-$(EXPORT_MINIMAL_DIR)/%.pdb:			$(MINIMAL1_DIR)/%.pdb
+$(EXPORT_MINIMAL_DIR)/%.pdb:			$(MINIMAL1_BUILD_DIR)/%.pdb
 	$(install-file)
-$(EXPORT_MINIMAL_DIR)/%.map:			$(MINIMAL1_DIR)/%.map
+$(EXPORT_MINIMAL_DIR)/%.map:			$(MINIMAL1_BUILD_DIR)/%.map
 	$(install-file)
-$(EXPORT_LIB_DIR)/%.lib:			$(MINIMAL1_DIR)/%.lib
+$(EXPORT_LIB_DIR)/%.lib:			$(MINIMAL1_BUILD_DIR)/%.lib
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.diz:			$(MINIMAL1_DIR)/%.diz
+$(EXPORT_JRE_BIN_DIR)/%.diz:			$(MINIMAL1_BUILD_DIR)/%.diz
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.dll:			$(MINIMAL1_DIR)/%.dll
+$(EXPORT_JRE_BIN_DIR)/%.dll:			$(MINIMAL1_BUILD_DIR)/%.dll
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.pdb:			$(MINIMAL1_DIR)/%.pdb
+$(EXPORT_JRE_BIN_DIR)/%.pdb:			$(MINIMAL1_BUILD_DIR)/%.pdb
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.map:			$(MINIMAL1_DIR)/%.map
+$(EXPORT_JRE_BIN_DIR)/%.map:			$(MINIMAL1_BUILD_DIR)/%.map
 	$(install-file)
 # Unix
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX):	$(MINIMAL1_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX):	$(MINIMAL1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_MINIMAL_DIR)/%.$(LIBRARY_SUFFIX):	$(MINIMAL1_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_MINIMAL_DIR)/%.$(LIBRARY_SUFFIX):	$(MINIMAL1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_MINIMAL_DIR)/64/%.$(LIBRARY_SUFFIX):	$(MINIMAL1_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_MINIMAL_DIR)/64/%.$(LIBRARY_SUFFIX):	$(MINIMAL1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo:		$(MINIMAL1_DIR)/%.debuginfo
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo:		$(MINIMAL1_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_MINIMAL_DIR)/%.debuginfo:		$(MINIMAL1_DIR)/%.debuginfo
+$(EXPORT_MINIMAL_DIR)/%.debuginfo:		$(MINIMAL1_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_MINIMAL_DIR)/64/%.debuginfo:		$(MINIMAL1_DIR)/%.debuginfo
+$(EXPORT_MINIMAL_DIR)/64/%.debuginfo:		$(MINIMAL1_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz:		$(MINIMAL1_DIR)/%.diz
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz:		$(MINIMAL1_BUILD_DIR)/%.diz
 	$(install-file)
-$(EXPORT_MINIMAL_DIR)/64/%.diz:			$(MINIMAL1_DIR)/%.diz
+$(EXPORT_MINIMAL_DIR)/64/%.diz:			$(MINIMAL1_BUILD_DIR)/%.diz
 	$(install-file)
 endif
 
 # Zero
 ifeq ($(JVM_VARIANT_ZERO), true)
 # Common
-$(EXPORT_LIB_DIR)/%.jar:			$(ZERO_DIR)/../generated/%.jar
+$(EXPORT_LIB_DIR)/%.jar:			$(ZERO_BUILD_DIR)/../generated/%.jar
 	$(install-file)
-$(EXPORT_INCLUDE_DIR)/%:			$(ZERO_DIR)/../generated/jvmtifiles/%
+$(EXPORT_INCLUDE_DIR)/%:			$(ZERO_BUILD_DIR)/../generated/jvmtifiles/%
 	$(install-file)
 # Unix
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo:		$(ZERO_DIR)/%.debuginfo
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo:		$(ZERO_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz:		$(ZERO_DIR)/%.diz
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz:		$(ZERO_BUILD_DIR)/%.diz
 	$(install-file)
-$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(ZERO_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_SERVER_DIR)/%.debuginfo:		$(ZERO_DIR)/%.debuginfo
+$(EXPORT_SERVER_DIR)/%.debuginfo:		$(ZERO_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_SERVER_DIR)/%.diz:			$(ZERO_DIR)/%.diz
+$(EXPORT_SERVER_DIR)/%.diz:			$(ZERO_BUILD_DIR)/%.diz
 	$(install-file)
 endif
 
 # Shark
 ifeq ($(JVM_VARIANT_ZEROSHARK), true)
 # Common
-$(EXPORT_LIB_DIR)/%.jar:			$(SHARK_DIR)/../generated/%.jar
+$(EXPORT_LIB_DIR)/%.jar:			$(SHARK_BUILD_DIR)/../generated/%.jar
 	$(install-file)
-$(EXPORT_INCLUDE_DIR)/%:			$(SHARK_DIR)/../generated/jvmtifiles/%
+$(EXPORT_INCLUDE_DIR)/%:			$(SHARK_BUILD_DIR)/../generated/jvmtifiles/%
 	$(install-file)
 # Unix
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo):	$(SHARK_DIR)/%.debuginfo
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo):	$(SHARK_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz:		$(SHARK_DIR)/%.diz
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz:		$(SHARK_BUILD_DIR)/%.diz
 	$(install-file)
-$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(SHARK_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_SERVER_DIR)/%.debuginfo:		$(SHARK_DIR)/%.debuginfo
+$(EXPORT_SERVER_DIR)/%.debuginfo:		$(SHARK_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_SERVER_DIR)/%.diz:			$(SHARK_DIR)/%.diz
+$(EXPORT_SERVER_DIR)/%.diz:			$(SHARK_BUILD_DIR)/%.diz
 	$(install-file)
 endif
 
diff --git a/hotspot/make/bsd/makefiles/buildtree.make b/hotspot/make/bsd/makefiles/buildtree.make
index 9d0a217..16a0f9a 100644
--- a/hotspot/make/bsd/makefiles/buildtree.make
+++ b/hotspot/make/bsd/makefiles/buildtree.make
@@ -49,7 +49,6 @@
 # adlc.make	-
 # jvmti.make	- generate JVMTI bindings from the spec (JSR-163)
 # sa.make	- generate SA jar file and natives
-# env.[ck]sh	- environment settings
 #
 # The makefiles are split this way so that "make foo" will run faster by not
 # having to read the dependency files for the vm.
@@ -129,9 +128,7 @@
 BUILDTREE_MAKE	= $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
 
 # dtrace.make is used on BSD versions that implement Dtrace (like MacOS X)
-BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make \
-	jvmti.make sa.make dtrace.make \
-        env.sh env.csh jdkpath.sh
+BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make dtrace.make
 
 BUILDTREE_VARS	= GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
 	SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
@@ -354,33 +351,6 @@
 	echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
 	) > $@
 
-env.sh: $(BUILDTREE_MAKE)
-	@echo Creating $@ ...
-	$(QUIETLY) ( \
-	$(BUILDTREE_COMMENT); \
-	{ echo "JAVA_HOME=$(JDK_IMPORT_PATH)"; }; \
-	{ \
-	echo "CLASSPATH=$${CLASSPATH:+$$CLASSPATH:}.:\$${JAVA_HOME}/jre/lib/rt.jar:\$${JAVA_HOME}/jre/lib/i18n.jar"; \
-	} | sed s:$${JAVA_HOME:--------}:\$${JAVA_HOME}:g; \
-	echo "HOTSPOT_BUILD_USER=\"$${LOGNAME:-$$USER} in `basename $(GAMMADIR)`\""; \
-	echo "export JAVA_HOME CLASSPATH HOTSPOT_BUILD_USER"; \
-	) > $@
-
-env.csh: env.sh
-	@echo Creating $@ ...
-	$(QUIETLY) ( \
-	$(BUILDTREE_COMMENT); \
-	{ echo "setenv JAVA_HOME \"$(JDK_IMPORT_PATH)\""; }; \
-	sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \
-	) > $@
-
-jdkpath.sh: $(BUILDTREE_MAKE)
-	@echo Creating $@ ...
-	$(QUIETLY) ( \
-	$(BUILDTREE_COMMENT); \
-	echo "JDK=${JAVA_HOME}"; \
-	) > $@
-
 FORCE:
 
 .PHONY:  all FORCE
diff --git a/hotspot/make/bsd/makefiles/fastdebug.make b/hotspot/make/bsd/makefiles/fastdebug.make
index d791393..f2f5dcf 100644
--- a/hotspot/make/bsd/makefiles/fastdebug.make
+++ b/hotspot/make/bsd/makefiles/fastdebug.make
@@ -58,6 +58,6 @@
 # Linker mapfile
 MAPFILE = $(GAMMADIR)/make/bsd/makefiles/mapfile-vers-debug
 
-VERSION = optimized
+VERSION = fastdebug
 SYSDEFS += -DASSERT
 PICFLAGS = DEFAULT
diff --git a/hotspot/make/bsd/makefiles/launcher.make b/hotspot/make/bsd/makefiles/launcher.make
deleted file mode 100644
index 588bf9a..0000000
--- a/hotspot/make/bsd/makefiles/launcher.make
+++ /dev/null
@@ -1,115 +0,0 @@
-#
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-#
-
-# Rules to build gamma launcher, used by vm.make
-
-
-LAUNCHER_SCRIPT = hotspot
-LAUNCHER   = gamma
-
-LAUNCHERDIR   := $(GAMMADIR)/src/os/posix/launcher
-LAUNCHERDIR_SHARE := $(GAMMADIR)/src/share/tools/launcher
-LAUNCHERFLAGS := $(ARCHFLAG) \
-                -I$(LAUNCHERDIR) -I$(GAMMADIR)/src/share/vm/prims \
-                -I$(LAUNCHERDIR_SHARE) \
-                -DFULL_VERSION=\"$(HOTSPOT_RELEASE_VERSION)\" \
-                -DJDK_MAJOR_VERSION=\"$(JDK_MAJOR_VERSION)\" \
-                -DJDK_MINOR_VERSION=\"$(JDK_MINOR_VERSION)\" \
-                -DARCH=\"$(LIBARCH)\" \
-                -DGAMMA \
-                -DLAUNCHER_TYPE=\"gamma\" \
-                -DLINK_INTO_$(LINK_INTO) \
-                $(TARGET_DEFINES)
-# Give the launcher task_for_pid() privileges so that it can be used to run JStack, JInfo, et al.
-LFLAGS_LAUNCHER += -sectcreate __TEXT __info_plist $(GAMMADIR)/src/os/bsd/launcher/Info-privileged.plist
-
-ifeq ($(LINK_INTO),AOUT)
-  LAUNCHER.o                 = launcher.o $(JVM_OBJ_FILES)
-  LAUNCHER_MAPFILE           = mapfile_reorder
-  LFLAGS_LAUNCHER$(LDNOMAP) += $(MAPFLAG:FILENAME=$(LAUNCHER_MAPFILE))
-  LFLAGS_LAUNCHER           += $(SONAMEFLAG:SONAME=$(LIBJVM)) $(STATIC_LIBGCC)
-  LIBS_LAUNCHER             += $(STATIC_STDCXX) $(LIBS)
-else
-  LAUNCHER.o                 = launcher.o
-  LFLAGS_LAUNCHER           += -L`pwd`
-
-  # The gamma launcher runs the JDK from $JAVA_HOME, overriding the JVM with a
-  # freshly built JVM at ./libjvm.{so|dylib}.  This is accomplished by setting
-  # the library searchpath using ({DY}LD_LIBRARY_PATH) to find the local JVM
-  # first.  Gamma dlopen()s libjava from $JAVA_HOME/jre/lib{/$arch}, which is
-  # statically linked with CoreFoundation framework libs. Unfortunately, gamma's
-  # unique searchpath results in some unresolved symbols in the framework
-  # libraries, because JDK libraries are inadvertently discovered first on the
-  # searchpath, e.g. libjpeg.  On Mac OS X, filenames are case *insensitive*.
-  # So, the actual filename collision is libjpeg.dylib and libJPEG.dylib.
-  # To resolve this, gamma needs to also statically link with the CoreFoundation
-  # framework libraries.
-
-  ifeq ($(OS_VENDOR),Darwin)
-    LFLAGS_LAUNCHER         += -framework CoreFoundation
-  endif
-
-  LIBS_LAUNCHER             += -l$(JVM) $(LIBS)
-endif
-
-LINK_LAUNCHER = $(LINK.CC)
-
-LINK_LAUNCHER/PRE_HOOK  = $(LINK_LIB.CXX/PRE_HOOK)
-LINK_LAUNCHER/POST_HOOK = $(LINK_LIB.CXX/POST_HOOK)
-
-LAUNCHER_OUT = launcher
-
-SUFFIXES += .d
-
-SOURCES := $(shell find $(LAUNCHERDIR) -name "*.c")
-SOURCES_SHARE := $(shell find $(LAUNCHERDIR_SHARE) -name "*.c")
-
-OBJS := $(patsubst $(LAUNCHERDIR)/%.c,$(LAUNCHER_OUT)/%.o,$(SOURCES)) $(patsubst $(LAUNCHERDIR_SHARE)/%.c,$(LAUNCHER_OUT)/%.o,$(SOURCES_SHARE))
-
-DEPFILES := $(patsubst %.o,%.d,$(OBJS))
--include $(DEPFILES)
-
-$(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR_SHARE)/%.c
-	$(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); }
-	$(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CXXFLAGS)
-
-$(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR)/%.c
-	$(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); }
-	$(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CXXFLAGS)
-
-$(LAUNCHER): $(OBJS) $(LIBJVM) $(LAUNCHER_MAPFILE)
-	$(QUIETLY) echo Linking launcher...
-	$(QUIETLY) $(LINK_LAUNCHER/PRE_HOOK)
-	$(QUIETLY) $(LINK_LAUNCHER) $(LFLAGS_LAUNCHER) -o $@ $(sort $(OBJS)) $(LIBS_LAUNCHER)
-	$(QUIETLY) $(LINK_LAUNCHER/POST_HOOK)
-	# Sign the launcher with the development certificate (if present) so that it can be used
-	# to run JStack, JInfo, et al.
-	$(QUIETLY) -codesign -s openjdk_codesign $@
-
-$(LAUNCHER): $(LAUNCHER_SCRIPT)
-
-$(LAUNCHER_SCRIPT): $(LAUNCHERDIR)/launcher.script
-	$(QUIETLY) sed -e 's/@@LIBARCH@@/$(LIBARCH)/g' $< > $@
-	$(QUIETLY) chmod +x $@
-
diff --git a/hotspot/make/bsd/makefiles/vm.make b/hotspot/make/bsd/makefiles/vm.make
index b9528e1..f668b4e 100644
--- a/hotspot/make/bsd/makefiles/vm.make
+++ b/hotspot/make/bsd/makefiles/vm.make
@@ -144,6 +144,9 @@
 ifeq ($(OS_VENDOR), Darwin)
   LIBJVM   = lib$(JVM).dylib
   CFLAGS  += -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE
+  ifeq (${VERSION}, $(filter ${VERSION}, debug fastdebug))
+    CFLAGS += -DALLOW_OPERATOR_NEW_USAGE
+  endif
 else
   LIBJVM   = lib$(JVM).so
 endif
@@ -328,9 +331,6 @@
 #----------------------------------------------------------------------
 # Other files
 
-# Gamma launcher
-include $(MAKEFILES_DIR)/launcher.make
-
 # Signal interposition library
 include $(MAKEFILES_DIR)/jsig.make
 
diff --git a/hotspot/src/os/posix/launcher/launcher.script b/hotspot/make/hotspot.script
similarity index 89%
rename from hotspot/src/os/posix/launcher/launcher.script
rename to hotspot/make/hotspot.script
index e8d4281..c6259ba 100644
--- a/hotspot/src/os/posix/launcher/launcher.script
+++ b/hotspot/make/hotspot.script
@@ -72,6 +72,7 @@
 REL_MYDIR=`dirname $0`
 MYDIR=`cd $REL_MYDIR && pwd`
 
+#
 # Look whether the user wants to run inside gdb
 case "$1" in
     -gdb)
@@ -95,16 +96,14 @@
         ;;
 esac
 
-JDK=
-if [ "${ALT_JAVA_HOME}" = "" ]; then
-    . ${MYDIR}/jdkpath.sh
+if [ "${ALT_JAVA_HOME}" != "" ]; then
+    JDK=${ALT_JAVA_HOME%%/jre}
 else
-    JDK=${ALT_JAVA_HOME%%/jre};
+    JDK=@@JDK_IMPORT_PATH@@
 fi
 
 if [ "${JDK}" = "" ]; then
-    echo Failed to find JDK. ALT_JAVA_HOME is not set or ./jdkpath.sh is empty or not found.
-    exit 1
+    echo "Failed to find JDK.  Either ALT_JAVA_HOME is not set or JDK_IMPORT_PATH is empty."
 fi
 
 # We will set the LD_LIBRARY_PATH as follows:
@@ -142,12 +141,12 @@
     export LD_LIBRARY_PATH
 fi
 
-JPARMS="$@ $JAVA_ARGS";
+JPARMS="-Dsun.java.launcher=gamma -XXaltjvm=$MYDIR $@ $JAVA_ARGS";
 
-# Locate the gamma development launcher
-LAUNCHER=${MYDIR}/gamma
+# Locate the java launcher
+LAUNCHER=$JDK/bin/java
 if [ ! -x $LAUNCHER ] ; then
-    echo Error: Cannot find the gamma development launcher \"$LAUNCHER\"
+    echo Error: Cannot find the java launcher \"$LAUNCHER\"
     exit 1
 fi
 
@@ -166,9 +165,10 @@
 file $LAUNCHER
 directory $GDBSRCDIR
 # Get us to a point where we can set breakpoints in libjvm.so
-break InitializeJVM
+set breakpoint pending on
+break JNI_CreateJavaVM
 run
-# Stop in InitializeJVM
+# Stop in JNI_CreateJavaVM
 delete 1
 # We can now set breakpoints wherever we like
 EOF
@@ -199,7 +199,7 @@
 	rm -f $GDBSCR
         ;;
     dbx)
-        $DBX -s $HOME/.dbxrc $LAUNCHER $JPARMS
+        $DBX -s $HOME/.dbxrc -c "loadobject -load libjvm.so; stop in JNI_CreateJavaVM; run $JPARMS; delete all" $LAUNCHER
         ;;
     valgrind)
         echo Warning: Defaulting to 16Mb heap to make Valgrind run faster, use -Xmx for larger heap
diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version
index a189566..ae66a04 100644
--- a/hotspot/make/hotspot_version
+++ b/hotspot/make/hotspot_version
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=25
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=32
+HS_BUILD_NUMBER=33
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=8
diff --git a/hotspot/make/jprt.properties b/hotspot/make/jprt.properties
index af7f321..5971546 100644
--- a/hotspot/make/jprt.properties
+++ b/hotspot/make/jprt.properties
@@ -134,14 +134,14 @@
 
 jprt.build.targets.standard= \
     ${jprt.my.solaris.sparc}-{product|fastdebug}, \
-    ${jprt.my.solaris.sparcv9}-{product|fastdebug}, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug|optimized}, \
     ${jprt.my.solaris.i586}-{product|fastdebug}, \
     ${jprt.my.solaris.x64}-{product|fastdebug}, \
     ${jprt.my.linux.i586}-{product|fastdebug}, \
-    ${jprt.my.linux.x64}-{product|fastdebug}, \
+    ${jprt.my.linux.x64}-{product|fastdebug|optimized}, \
     ${jprt.my.macosx.x64}-{product|fastdebug}, \
     ${jprt.my.windows.i586}-{product|fastdebug}, \
-    ${jprt.my.windows.x64}-{product|fastdebug}, \
+    ${jprt.my.windows.x64}-{product|fastdebug|optimized}, \
     ${jprt.my.linux.armvh}-{product|fastdebug}
 
 jprt.build.targets.open= \
diff --git a/hotspot/make/linux/makefiles/buildtree.make b/hotspot/make/linux/makefiles/buildtree.make
index 0b7c120..3b71577 100644
--- a/hotspot/make/linux/makefiles/buildtree.make
+++ b/hotspot/make/linux/makefiles/buildtree.make
@@ -49,7 +49,6 @@
 # adlc.make	-
 # jvmti.make	- generate JVMTI bindings from the spec (JSR-163)
 # sa.make	- generate SA jar file and natives
-# env.[ck]sh	- environment settings
 #
 # The makefiles are split this way so that "make foo" will run faster by not
 # having to read the dependency files for the vm.
@@ -123,8 +122,7 @@
 # For dependencies and recursive makes.
 BUILDTREE_MAKE	= $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
 
-BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make \
-        env.sh env.csh jdkpath.sh
+BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make
 
 BUILDTREE_VARS	= GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
 	SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
@@ -349,33 +347,6 @@
 	echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
 	) > $@
 
-env.sh: $(BUILDTREE_MAKE)
-	@echo Creating $@ ...
-	$(QUIETLY) ( \
-	$(BUILDTREE_COMMENT); \
-	{ echo "JAVA_HOME=$(JDK_IMPORT_PATH)"; }; \
-	{ \
-	echo "CLASSPATH=$${CLASSPATH:+$$CLASSPATH:}.:\$${JAVA_HOME}/jre/lib/rt.jar:\$${JAVA_HOME}/jre/lib/i18n.jar"; \
-	} | sed s:$${JAVA_HOME:--------}:\$${JAVA_HOME}:g; \
-	echo "HOTSPOT_BUILD_USER=\"$${LOGNAME:-$$USER} in `basename $(GAMMADIR)`\""; \
-	echo "export JAVA_HOME CLASSPATH HOTSPOT_BUILD_USER"; \
-	) > $@
-
-env.csh: env.sh
-	@echo Creating $@ ...
-	$(QUIETLY) ( \
-	$(BUILDTREE_COMMENT); \
-	{ echo "setenv JAVA_HOME \"$(JDK_IMPORT_PATH)\""; }; \
-	sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \
-	) > $@
-
-jdkpath.sh: $(BUILDTREE_MAKE)
-	@echo Creating $@ ...
-	$(QUIETLY) ( \
-	$(BUILDTREE_COMMENT); \
-	echo "JDK=${JAVA_HOME}"; \
-	) > $@
-
 FORCE:
 
 .PHONY:  all FORCE
diff --git a/hotspot/make/linux/makefiles/launcher.make b/hotspot/make/linux/makefiles/launcher.make
deleted file mode 100644
index 23f3eda..0000000
--- a/hotspot/make/linux/makefiles/launcher.make
+++ /dev/null
@@ -1,93 +0,0 @@
-#
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#  
-#
-
-# Rules to build gamma launcher, used by vm.make
-
-
-LAUNCHER_SCRIPT = hotspot
-LAUNCHER   = gamma
-
-LAUNCHERDIR   := $(GAMMADIR)/src/os/posix/launcher
-LAUNCHERDIR_SHARE := $(GAMMADIR)/src/share/tools/launcher
-LAUNCHERFLAGS := $(ARCHFLAG) \
-                -I$(LAUNCHERDIR) -I$(GAMMADIR)/src/share/vm/prims \
-                -I$(LAUNCHERDIR_SHARE) \
-                -DFULL_VERSION=\"$(HOTSPOT_RELEASE_VERSION)\" \
-                -DJDK_MAJOR_VERSION=\"$(JDK_MAJOR_VERSION)\" \
-                -DJDK_MINOR_VERSION=\"$(JDK_MINOR_VERSION)\" \
-                -DARCH=\"$(LIBARCH)\" \
-                -DGAMMA \
-                -DLAUNCHER_TYPE=\"gamma\" \
-                -DLINK_INTO_$(LINK_INTO) \
-                $(TARGET_DEFINES)
-
-ifeq ($(LINK_INTO),AOUT)
-  LAUNCHER.o                 = launcher.o $(JVM_OBJ_FILES)
-  LAUNCHER_MAPFILE           = mapfile_reorder
-  LFLAGS_LAUNCHER$(LDNOMAP) += $(MAPFLAG:FILENAME=$(LAUNCHER_MAPFILE))
-  LFLAGS_LAUNCHER           += $(SONAMEFLAG:SONAME=$(LIBJVM)) $(STATIC_LIBGCC)
-  LIBS_LAUNCHER             += $(STATIC_STDCXX) $(LIBS)
-else
-  LAUNCHER.o                 = launcher.o
-  LFLAGS_LAUNCHER           += -L `pwd`
-  LIBS_LAUNCHER             += -l$(JVM) $(LIBS)
-endif
-
-LINK_LAUNCHER = $(LINK.CC)
-
-LINK_LAUNCHER/PRE_HOOK  = $(LINK_LIB.CXX/PRE_HOOK)
-LINK_LAUNCHER/POST_HOOK = $(LINK_LIB.CXX/POST_HOOK)
-
-LAUNCHER_OUT = launcher
-
-SUFFIXES += .d
-
-SOURCES := $(shell find $(LAUNCHERDIR) -name "*.c")
-SOURCES_SHARE := $(shell find $(LAUNCHERDIR_SHARE) -name "*.c")
-
-OBJS := $(patsubst $(LAUNCHERDIR)/%.c,$(LAUNCHER_OUT)/%.o,$(SOURCES)) $(patsubst $(LAUNCHERDIR_SHARE)/%.c,$(LAUNCHER_OUT)/%.o,$(SOURCES_SHARE))
-
-DEPFILES := $(patsubst %.o,%.d,$(OBJS))
--include $(DEPFILES)
-
-$(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR_SHARE)/%.c
-	$(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); }
-	$(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CXXFLAGS)
-
-$(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR)/%.c
-	$(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); }
-	$(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CXXFLAGS)
-
-$(LAUNCHER): $(OBJS) $(LIBJVM) $(LAUNCHER_MAPFILE)
-	$(QUIETLY) echo Linking launcher...
-	$(QUIETLY) $(LINK_LAUNCHER/PRE_HOOK)
-	$(QUIETLY) $(LINK_LAUNCHER) $(LFLAGS_LAUNCHER) -o $@ $(sort $(OBJS)) $(LIBS_LAUNCHER)
-	$(QUIETLY) $(LINK_LAUNCHER/POST_HOOK)
-
-$(LAUNCHER): $(LAUNCHER_SCRIPT)
-
-$(LAUNCHER_SCRIPT): $(LAUNCHERDIR)/launcher.script
-	$(QUIETLY) sed -e 's/@@LIBARCH@@/$(LIBARCH)/g' $< > $@
-	$(QUIETLY) chmod +x $@
-
diff --git a/hotspot/make/linux/makefiles/vm.make b/hotspot/make/linux/makefiles/vm.make
index af060f8..79a926a 100644
--- a/hotspot/make/linux/makefiles/vm.make
+++ b/hotspot/make/linux/makefiles/vm.make
@@ -372,9 +372,6 @@
 #----------------------------------------------------------------------
 # Other files
 
-# Gamma launcher
-include $(MAKEFILES_DIR)/launcher.make
-
 # Signal interposition library
 include $(MAKEFILES_DIR)/jsig.make
 
diff --git a/hotspot/make/solaris/makefiles/buildtree.make b/hotspot/make/solaris/makefiles/buildtree.make
index 989470f..5827c4f 100644
--- a/hotspot/make/solaris/makefiles/buildtree.make
+++ b/hotspot/make/solaris/makefiles/buildtree.make
@@ -49,7 +49,6 @@
 # adlc.make	-
 # jvmti.make	- generate JVMTI bindings from the spec (JSR-163)
 # sa.make	- generate SA jar file and natives
-# env.[ck]sh	- environment settings
 #
 # The makefiles are split this way so that "make foo" will run faster by not
 # having to read the dependency files for the vm.
@@ -116,8 +115,7 @@
 # For dependencies and recursive makes.
 BUILDTREE_MAKE	= $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
 
-BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make \
-        env.sh env.csh jdkpath.sh
+BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make
 
 BUILDTREE_VARS	= GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
 	ARCH=$(ARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
@@ -339,33 +337,6 @@
 	echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
 	) > $@
 
-env.sh: $(BUILDTREE_MAKE)
-	@echo Creating $@ ...
-	$(QUIETLY) ( \
-	$(BUILDTREE_COMMENT); \
-	{ echo "JAVA_HOME=$(JDK_IMPORT_PATH)"; }; \
-	{ \
-	echo "CLASSPATH=$${CLASSPATH:+$$CLASSPATH:}.:\$${JAVA_HOME}/jre/lib/rt.jar:\$${JAVA_HOME}/jre/lib/i18n.jar"; \
-	} | sed s:$${JAVA_HOME:--------}:\$${JAVA_HOME}:g; \
-	echo "HOTSPOT_BUILD_USER=\"$${LOGNAME:-$$USER} in `basename $(GAMMADIR)`\""; \
-	echo "export JAVA_HOME LD_LIBRARY_PATH CLASSPATH HOTSPOT_BUILD_USER"; \
-	) > $@
-
-env.csh: env.sh
-	@echo Creating $@ ...
-	$(QUIETLY) ( \
-	$(BUILDTREE_COMMENT); \
-	{ echo "setenv JAVA_HOME \"$(JDK_IMPORT_PATH)\""; }; \
-	sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \
-	) > $@
-
-jdkpath.sh: $(BUILDTREE_MAKE)
-	@echo Creating $@ ...
-	$(QUIETLY) ( \
-	$(BUILDTREE_COMMENT); \
-	echo "JDK=${JAVA_HOME}"; \
-	) > $@
-
 FORCE:
 
 .PHONY:  all FORCE
diff --git a/hotspot/make/solaris/makefiles/launcher.make b/hotspot/make/solaris/makefiles/launcher.make
deleted file mode 100644
index 090ff5e..0000000
--- a/hotspot/make/solaris/makefiles/launcher.make
+++ /dev/null
@@ -1,108 +0,0 @@
-#
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#  
-#
-
-# Rules to build gamma launcher, used by vm.make
-
-LAUNCHER_SCRIPT = hotspot
-LAUNCHER   = gamma
-
-LAUNCHERDIR   = $(GAMMADIR)/src/os/posix/launcher
-LAUNCHERDIR_SHARE := $(GAMMADIR)/src/share/tools/launcher
-LAUNCHERFLAGS = $(ARCHFLAG) \
-                -I$(LAUNCHERDIR) -I$(GAMMADIR)/src/share/vm/prims \
-                -I$(LAUNCHERDIR_SHARE) \
-                -DFULL_VERSION=\"$(HOTSPOT_RELEASE_VERSION)\" \
-                -DJDK_MAJOR_VERSION=\"$(JDK_MAJOR_VERSION)\" \
-                -DJDK_MINOR_VERSION=\"$(JDK_MINOR_VERSION)\" \
-                -DARCH=\"$(LIBARCH)\" \
-                -DGAMMA \
-                -DLAUNCHER_TYPE=\"gamma\" \
-                -DLINK_INTO_$(LINK_INTO) \
-                $(TARGET_DEFINES)
-
-ifeq ($(LINK_INTO),AOUT)
-  LAUNCHER.o                 = launcher.o $(JVM_OBJ_FILES)
-  LAUNCHER_MAPFILE           = mapfile_extended
-  LFLAGS_LAUNCHER$(LDNOMAP) += $(MAPFLAG:FILENAME=$(LAUNCHER_MAPFILE))
-  LIBS_LAUNCHER             += $(LIBS)
-else
-  LAUNCHER.o                 = launcher.o
-  LFLAGS_LAUNCHER           += -L `pwd`
-  LIBS_LAUNCHER             += -l$(JVM) $(LIBS)
-endif
-
-LINK_LAUNCHER = $(LINK.CXX)
-
-LINK_LAUNCHER/PRE_HOOK  = $(LINK_LIB.CXX/PRE_HOOK)
-LINK_LAUNCHER/POST_HOOK = $(LINK_LIB.CXX/POST_HOOK)
-
-ifeq ("${Platform_compiler}", "sparcWorks")
-# Enable the following LAUNCHERFLAGS addition if you need to compare the
-# built ELF objects.
-#
-# The -g option makes static data global and the "-W0,-noglobal"
-# option tells the compiler to not globalize static data using a unique
-# globalization prefix. Instead force the use of a static globalization
-# prefix based on the source filepath so the objects from two identical
-# compilations are the same.
-#
-# Note: The blog says to use "-W0,-xglobalstatic", but that doesn't
-#       seem to work. I got "-W0,-noglobal" from Kelly and that works.
-#LAUNCHERFLAGS += -W0,-noglobal
-endif # Platform_compiler == sparcWorks
-
-LAUNCHER_OUT = launcher
-
-SUFFIXES += .d
-
-SOURCES := $(shell find $(LAUNCHERDIR) -name "*.c")
-SOURCES_SHARE := $(shell find $(LAUNCHERDIR_SHARE) -name "*.c")
-
-OBJS := $(patsubst $(LAUNCHERDIR)/%.c,$(LAUNCHER_OUT)/%.o,$(SOURCES)) $(patsubst $(LAUNCHERDIR_SHARE)/%.c,$(LAUNCHER_OUT)/%.o,$(SOURCES_SHARE))
-
-DEPFILES := $(patsubst %.o,%.d,$(OBJS))
--include $(DEPFILES)
-
-$(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR_SHARE)/%.c
-	$(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); }
-	$(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CXXFLAGS)
-
-$(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR)/%.c
-	$(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); }
-	$(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CXXFLAGS)
-
-$(LAUNCHER): $(OBJS) $(LIBJVM) $(LAUNCHER_MAPFILE)
-ifeq ($(filter -sbfast -xsbfast, $(CFLAGS_BROWSE)),)
-	$(QUIETLY) echo Linking launcher...
-	$(QUIETLY) $(LINK_LAUNCHER/PRE_HOOK)
-	$(QUIETLY) $(LINK_LAUNCHER) $(LFLAGS_LAUNCHER) -o $@ $(sort $(OBJS)) $(LIBS_LAUNCHER)
-	$(QUIETLY) $(LINK_LAUNCHER/POST_HOOK)
-endif # filter -sbfast -xsbfast
-
-$(LAUNCHER): $(LAUNCHER_SCRIPT)
-
-$(LAUNCHER_SCRIPT): $(LAUNCHERDIR)/launcher.script
-	$(QUIETLY) sed -e 's/@@LIBARCH@@/$(LIBARCH)/g' $< > $@
-	$(QUIETLY) chmod +x $@
-
diff --git a/hotspot/make/solaris/makefiles/vm.make b/hotspot/make/solaris/makefiles/vm.make
index 62146d7..855f7f1 100644
--- a/hotspot/make/solaris/makefiles/vm.make
+++ b/hotspot/make/solaris/makefiles/vm.make
@@ -338,9 +338,6 @@
 #----------------------------------------------------------------------
 # Other files
 
-# Gamma launcher
-include $(MAKEFILES_DIR)/launcher.make
-
 # Signal interposition library
 include $(MAKEFILES_DIR)/jsig.make
 
diff --git a/hotspot/make/windows/makefiles/debug.make b/hotspot/make/windows/makefiles/debug.make
index c19f175..2fca218 100644
--- a/hotspot/make/windows/makefiles/debug.make
+++ b/hotspot/make/windows/makefiles/debug.make
@@ -33,7 +33,7 @@
 BUILD_PCH_FILE=_build_pch_file.obj
 !endif
 
-default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
+default:: $(BUILD_PCH_FILE) $(AOUT) checkAndBuildSA
 
 !include ../local.make
 !include compile.make
@@ -71,4 +71,3 @@
 
 !include $(WorkSpace)/make/windows/makefiles/shared.make
 !include $(WorkSpace)/make/windows/makefiles/sa.make
-!include $(WorkSpace)/make/windows/makefiles/launcher.make
diff --git a/hotspot/make/windows/makefiles/fastdebug.make b/hotspot/make/windows/makefiles/fastdebug.make
index 0fc2329..cde98f21 100644
--- a/hotspot/make/windows/makefiles/fastdebug.make
+++ b/hotspot/make/windows/makefiles/fastdebug.make
@@ -33,7 +33,7 @@
 BUILD_PCH_FILE=_build_pch_file.obj
 !endif
 
-default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
+default:: $(BUILD_PCH_FILE) $(AOUT) checkAndBuildSA
 
 !include ../local.make
 !include compile.make
@@ -70,4 +70,3 @@
 
 !include $(WorkSpace)/make/windows/makefiles/shared.make
 !include $(WorkSpace)/make/windows/makefiles/sa.make
-!include $(WorkSpace)/make/windows/makefiles/launcher.make
diff --git a/hotspot/make/windows/makefiles/launcher.make b/hotspot/make/windows/makefiles/launcher.make
deleted file mode 100644
index 10ad009..0000000
--- a/hotspot/make/windows/makefiles/launcher.make
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#  
-#
-
-
-LAUNCHER_FLAGS=$(CXX_FLAGS) $(ARCHFLAG) \
-	/D FULL_VERSION=\"$(HOTSPOT_RELEASE_VERSION)\" \
-	/D JDK_MAJOR_VERSION=\"$(JDK_MAJOR_VERSION)\" \
-	/D JDK_MINOR_VERSION=\"$(JDK_MINOR_VERSION)\" \
-	/D GAMMA \
-	/D LAUNCHER_TYPE=\"gamma\" \
-	/D _CRT_SECURE_NO_WARNINGS \
-	/D _CRT_SECURE_NO_DEPRECATE \
-	/D LINK_INTO_LIBJVM \
-	/I $(WorkSpace)\src\os\windows\launcher \
-	/I $(WorkSpace)\src\share\tools\launcher \
-	/I $(WorkSpace)\src\share\vm\prims \
-	/I $(WorkSpace)\src\share\vm \
-	/I $(WorkSpace)\src\cpu\$(Platform_arch)\vm \
-	/I $(WorkSpace)\src\os\windows\vm
-
-LD_FLAGS=/manifest $(HS_INTERNAL_NAME).lib kernel32.lib user32.lib /nologo /machine:$(MACHINE) /map /debug /subsystem:console 
-
-!if "$(COMPILER_NAME)" == "VS2005"
-# This VS2005 compiler has /GS as a default and requires bufferoverflowU.lib
-#    on the link command line, otherwise we get missing __security_check_cookie
-#    externals at link time. Even with /GS-, you need bufferoverflowU.lib.
-BUFFEROVERFLOWLIB = bufferoverflowU.lib
-LD_FLAGS = $(LD_FLAGS) $(BUFFEROVERFLOWLIB)
-!endif
-
-!if "$(COMPILER_NAME)" == "VS2010" && "$(BUILDARCH)" == "i486"
-LD_FLAGS = /SAFESEH $(LD_FLAGS)
-!endif
-
-LAUNCHERDIR = $(WorkSpace)/src/os/windows/launcher
-LAUNCHERDIR_SHARE = $(WorkSpace)/src/share/tools/launcher
-
-OUTDIR = launcher
-
-{$(LAUNCHERDIR)}.c{$(OUTDIR)}.obj:
-	-mkdir $(OUTDIR) 2>NUL >NUL
-        $(CXX) $(LAUNCHER_FLAGS) /c /Fo$@ $<
-
-{$(LAUNCHERDIR_SHARE)}.c{$(OUTDIR)}.obj:
-	-mkdir $(OUTDIR) 2>NUL >NUL
-        $(CXX) $(LAUNCHER_FLAGS) /c /Fo$@ $<
-
-$(OUTDIR)\*.obj: $(LAUNCHERDIR)\*.c $(LAUNCHERDIR)\*.h $(LAUNCHERDIR_SHARE)\*.c $(LAUNCHERDIR_SHARE)\*.h
-
-launcher: $(OUTDIR)\java.obj $(OUTDIR)\java_md.obj $(OUTDIR)\jli_util.obj
-	echo $(JAVA_HOME) > jdkpath.txt  
-	$(LD) $(LD_FLAGS) /out:hotspot.exe $**
diff --git a/hotspot/make/windows/makefiles/product.make b/hotspot/make/windows/makefiles/product.make
index f166f73..407484cd 100644
--- a/hotspot/make/windows/makefiles/product.make
+++ b/hotspot/make/windows/makefiles/product.make
@@ -32,7 +32,7 @@
 BUILD_PCH_FILE=_build_pch_file.obj
 !endif
 
-default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
+default:: $(BUILD_PCH_FILE) $(AOUT) checkAndBuildSA
 
 !include ../local.make
 !include compile.make
@@ -73,4 +73,3 @@
 
 !include $(WorkSpace)/make/windows/makefiles/shared.make
 !include $(WorkSpace)/make/windows/makefiles/sa.make
-!include $(WorkSpace)/make/windows/makefiles/launcher.make
diff --git a/hotspot/make/windows/makefiles/projectcreator.make b/hotspot/make/windows/makefiles/projectcreator.make
index 68d098d..f142852 100644
--- a/hotspot/make/windows/makefiles/projectcreator.make
+++ b/hotspot/make/windows/makefiles/projectcreator.make
@@ -59,7 +59,6 @@
         -relativeSrcInclude src \
         -absoluteSrcInclude $(HOTSPOTBUILDSPACE) \
         -ignorePath $(HOTSPOTBUILDSPACE) \
-        -ignorePath launcher \
         -ignorePath share\vm\adlc \
         -ignorePath share\vm\shark \
         -ignorePath share\tools \
@@ -105,7 +104,6 @@
         -define ALIGN_STACK_FRAMES \
         -define VM_LITTLE_ENDIAN \
         -prelink  "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b	set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME)	set JAVA_HOME=$(HOTSPOTJDKDIST)	$(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh $(LD_VER)" \
-        -postbuild "" "Building hotspot.exe..." "cd $(HOTSPOTBUILDSPACE)\%f\%b	set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME)	nmake -f $(HOTSPOTWORKSPACE)\make\windows\projectfiles\common\Makefile LOCAL_MAKE=$(HOTSPOTBUILDSPACE)\%f\local.make JAVA_HOME=$(HOTSPOTJDKDIST) launcher" \
         -ignoreFile jsig.c \
         -ignoreFile jvmtiEnvRecommended.cpp \
         -ignoreFile jvmtiEnvStub.cpp \
diff --git a/hotspot/make/windows/projectfiles/common/Makefile b/hotspot/make/windows/projectfiles/common/Makefile
index 125923e..5556aae 100644
--- a/hotspot/make/windows/projectfiles/common/Makefile
+++ b/hotspot/make/windows/projectfiles/common/Makefile
@@ -65,7 +65,6 @@
 !endif
 
 HS_INTERNAL_NAME=jvm
-!include $(HOTSPOTWORKSPACE)/make/windows/makefiles/launcher.make
 
 default:: $(AdditionalTargets) $(JvmtiGeneratedFiles)
 
diff --git a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp
index ee330c6..35886ce 100644
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp
@@ -74,7 +74,7 @@
 define_pd_global(bool, UseMembar,            false);
 
 // GC Ergo Flags
-define_pd_global(intx, CMSYoungGenPerWorker, 16*M);  // default max size of CMS young gen, per GC worker thread
+define_pd_global(uintx, CMSYoungGenPerWorker, 16*M);  // default max size of CMS young gen, per GC worker thread
 
 #define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
                                                                             \
diff --git a/hotspot/src/cpu/x86/vm/globals_x86.hpp b/hotspot/src/cpu/x86/vm/globals_x86.hpp
index fb44e2d..978a1d6 100644
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp
@@ -77,7 +77,7 @@
 #endif
 
 // GC Ergo Flags
-define_pd_global(intx, CMSYoungGenPerWorker, 64*M);  // default max size of CMS young gen, per GC worker thread
+define_pd_global(uintx, CMSYoungGenPerWorker, 64*M);  // default max size of CMS young gen, per GC worker thread
 
 #define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
                                                                             \
diff --git a/hotspot/src/cpu/zero/vm/globals_zero.hpp b/hotspot/src/cpu/zero/vm/globals_zero.hpp
index a3c7d24..71b566f 100644
--- a/hotspot/src/cpu/zero/vm/globals_zero.hpp
+++ b/hotspot/src/cpu/zero/vm/globals_zero.hpp
@@ -55,7 +55,7 @@
 define_pd_global(bool,  UseMembar,            true);
 
 // GC Ergo Flags
-define_pd_global(intx, CMSYoungGenPerWorker, 16*M);  // default max size of CMS young gen, per GC worker thread
+define_pd_global(uintx, CMSYoungGenPerWorker, 16*M);  // default max size of CMS young gen, per GC worker thread
 
 #define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct)
 
diff --git a/hotspot/src/os/posix/launcher/java_md.c b/hotspot/src/os/posix/launcher/java_md.c
deleted file mode 100644
index b5fc949..0000000
--- a/hotspot/src/os/posix/launcher/java_md.c
+++ /dev/null
@@ -1,1936 +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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-
-#include "java.h"
-#include <dirent.h>
-#include <dlfcn.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#ifndef GAMMA
-#include "manifest_info.h"
-#include "version_comp.h"
-#endif
-
-#if defined(__linux__) || defined(_ALLBSD_SOURCE)
-#include <pthread.h>
-#else
-#include <thread.h>
-#endif
-
-#ifdef __APPLE__
-#define JVM_DLL "libjvm.dylib"
-#define JAVA_DLL "libjava.dylib"
-#define LD_LIBRARY_PATH "DYLD_LIBRARY_PATH"
-#else
-#define JVM_DLL "libjvm.so"
-#define JAVA_DLL "libjava.so"
-#define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
-#endif
-
-#ifndef GAMMA   /* launcher.make defines ARCH */
-/*
- * If a processor / os combination has the ability to run binaries of
- * two data models and cohabitation of jre/jdk bits with both data
- * models is supported, then DUAL_MODE is defined.  When DUAL_MODE is
- * defined, the architecture names for the narrow and wide version of
- * the architecture are defined in LIBARCH64NAME and LIBARCH32NAME.  Currently
- * only Solaris on sparc/sparcv9 and i586/amd64 is DUAL_MODE; linux
- * i586/amd64 could be defined as DUAL_MODE but that is not the
- * current policy.
- */
-
-#ifndef LIBARCHNAME
-#  error "The macro LIBARCHNAME was not defined on the compile line"
-#endif
-
-#ifdef __sun
-#  define DUAL_MODE
-#  ifndef LIBARCH32NAME
-#    error "The macro LIBARCH32NAME was not defined on the compile line"
-#  endif
-#  ifndef LIBARCH64NAME
-#    error "The macro LIBARCH64NAME was not defined on the compile line"
-#  endif
-#  include <sys/systeminfo.h>
-#  include <sys/elf.h>
-#  include <stdio.h>
-#endif
-
-#endif /* ifndef GAMMA */
-
-/* pointer to environment */
-extern char **environ;
-
-#ifndef GAMMA
-/*
- *      A collection of useful strings. One should think of these as #define
- *      entries, but actual strings can be more efficient (with many compilers).
- */
-#ifdef __linux__
-static const char *system_dir   = "/usr/java";
-static const char *user_dir     = "/java";
-#else /* Solaris */
-static const char *system_dir   = "/usr/jdk";
-static const char *user_dir     = "/jdk";
-#endif
-
-#endif /* ifndef GAMMA */
-
-/*
- * Flowchart of launcher execs and options processing on unix
- *
- * The selection of the proper vm shared library to open depends on
- * several classes of command line options, including vm "flavor"
- * options (-client, -server) and the data model options, -d32  and
- * -d64, as well as a version specification which may have come from
- * the command line or from the manifest of an executable jar file.
- * The vm selection options are not passed to the running
- * virtual machine; they must be screened out by the launcher.
- *
- * The version specification (if any) is processed first by the
- * platform independent routine SelectVersion.  This may result in
- * the exec of the specified launcher version.
- *
- * Typically, the launcher execs at least once to ensure a suitable
- * LD_LIBRARY_PATH is in effect for the process.  The first exec
- * screens out all the data model options; leaving the choice of data
- * model implicit in the binary selected to run.  However, in case no
- * exec is done, the data model options are screened out before the vm
- * is invoked.
- *
- *  incoming argv ------------------------------
- *  |                                          |
- * \|/                                         |
- * CheckJVMType                                |
- * (removes -client, -server, etc.)            |
- *                                            \|/
- *                                            CreateExecutionEnvironment
- *                                            (removes -d32 and -d64,
- *                                             determines desired data model,
- *                                             sets up LD_LIBRARY_PATH,
- *                                             and exec's)
- *                                             |
- *  --------------------------------------------
- *  |
- * \|/
- * exec child 1 incoming argv -----------------
- *  |                                          |
- * \|/                                         |
- * CheckJVMType                                |
- * (removes -client, -server, etc.)            |
- *  |                                         \|/
- *  |                                          CreateExecutionEnvironment
- *  |                                          (verifies desired data model
- *  |                                           is running and acceptable
- *  |                                           LD_LIBRARY_PATH;
- *  |                                           no-op in child)
- *  |
- * \|/
- * TranslateDashJArgs...
- * (Prepare to pass args to vm)
- *  |
- *  |
- *  |
- * \|/
- * ParseArguments
- * (ignores -d32 and -d64,
- *  processes version options,
- *  creates argument list for vm,
- *  etc.)
- *
- */
-
-static char *SetExecname(char **argv);
-static char * GetExecname();
-static jboolean GetJVMPath(const char *jrepath, const char *jvmtype,
-                           char *jvmpath, jint jvmpathsize, char * arch);
-static jboolean GetJREPath(char *path, jint pathsize, char * arch, jboolean speculative);
-
-#ifndef GAMMA
-const char *
-GetArch()
-{
-    return LIBARCHNAME;
-}
-#endif /* ifndef GAMMA */
-
-void
-CreateExecutionEnvironment(int *_argcp,
-                           char ***_argvp,
-                           char jrepath[],
-                           jint so_jrepath,
-                           char jvmpath[],
-                           jint so_jvmpath,
-                           char **original_argv) {
-  /*
-   * First, determine if we are running the desired data model.  If we
-   * are running the desired data model, all the error messages
-   * associated with calling GetJREPath, ReadKnownVMs, etc. should be
-   * output.  However, if we are not running the desired data model,
-   * some of the errors should be suppressed since it is more
-   * informative to issue an error message based on whether or not the
-   * os/processor combination has dual mode capabilities.
-   */
-
-    char *execname = NULL;
-    int original_argc = *_argcp;
-    jboolean jvmpathExists;
-
-    /* Compute the name of the executable */
-    execname = SetExecname(*_argvp);
-
-#ifndef GAMMA
-    /* Set the LD_LIBRARY_PATH environment variable, check data model
-       flags, and exec process, if needed */
-    {
-      char *arch        = (char *)GetArch(); /* like sparc or sparcv9 */
-      char * jvmtype    = NULL;
-      int argc          = *_argcp;
-      char **argv       = original_argv;
-
-      char *runpath     = NULL; /* existing effective LD_LIBRARY_PATH
-                                   setting */
-
-      int running       =       /* What data model is being ILP32 =>
-                                   32 bit vm; LP64 => 64 bit vm */
-#ifdef _LP64
-        64;
-#else
-      32;
-#endif
-
-      int wanted        = running;      /* What data mode is being
-                                           asked for? Current model is
-                                           fine unless another model
-                                           is asked for */
-
-      char* new_runpath = NULL; /* desired new LD_LIBRARY_PATH string */
-      char* newpath     = NULL; /* path on new LD_LIBRARY_PATH */
-      char* lastslash   = NULL;
-
-      char** newenvp    = NULL; /* current environment */
-
-      char** newargv    = NULL;
-      int    newargc    = 0;
-#ifdef __sun
-      char*  dmpath     = NULL;  /* data model specific LD_LIBRARY_PATH,
-                                    Solaris only */
-#endif
-
-      /*
-       * Starting in 1.5, all unix platforms accept the -d32 and -d64
-       * options.  On platforms where only one data-model is supported
-       * (e.g. ia-64 Linux), using the flag for the other data model is
-       * an error and will terminate the program.
-       */
-
-      { /* open new scope to declare local variables */
-        int i;
-
-        newargv = (char **)JLI_MemAlloc((argc+1) * sizeof(*newargv));
-        newargv[newargc++] = argv[0];
-
-        /* scan for data model arguments and remove from argument list;
-           last occurrence determines desired data model */
-        for (i=1; i < argc; i++) {
-
-          if (strcmp(argv[i], "-J-d64") == 0 || strcmp(argv[i], "-d64") == 0) {
-            wanted = 64;
-            continue;
-          }
-          if (strcmp(argv[i], "-J-d32") == 0 || strcmp(argv[i], "-d32") == 0) {
-            wanted = 32;
-            continue;
-          }
-          newargv[newargc++] = argv[i];
-
-#ifdef JAVA_ARGS
-          if (argv[i][0] != '-')
-            continue;
-#else
-          if (strcmp(argv[i], "-classpath") == 0 || strcmp(argv[i], "-cp") == 0) {
-            i++;
-            if (i >= argc) break;
-            newargv[newargc++] = argv[i];
-            continue;
-          }
-          if (argv[i][0] != '-') { i++; break; }
-#endif
-        }
-
-        /* copy rest of args [i .. argc) */
-        while (i < argc) {
-          newargv[newargc++] = argv[i++];
-        }
-        newargv[newargc] = NULL;
-
-        /*
-         * newargv has all proper arguments here
-         */
-
-        argc = newargc;
-        argv = newargv;
-      }
-
-      /* If the data model is not changing, it is an error if the
-         jvmpath does not exist */
-      if (wanted == running) {
-        /* Find out where the JRE is that we will be using. */
-        if (!GetJREPath(jrepath, so_jrepath, arch, JNI_FALSE) ) {
-          fprintf(stderr, "Error: could not find Java 2 Runtime Environment.\n");
-          exit(2);
-        }
-
-        /* Find the specified JVM type */
-        if (ReadKnownVMs(jrepath, arch, JNI_FALSE) < 1) {
-          fprintf(stderr, "Error: no known VMs. (check for corrupt jvm.cfg file)\n");
-          exit(1);
-        }
-
-        jvmpath[0] = '\0';
-        jvmtype = CheckJvmType(_argcp, _argvp, JNI_FALSE);
-
-        if (!GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, arch )) {
-          fprintf(stderr, "Error: no `%s' JVM at `%s'.\n", jvmtype, jvmpath);
-          exit(4);
-        }
-      } else {  /* do the same speculatively or exit */
-#ifdef DUAL_MODE
-        if (running != wanted) {
-          /* Find out where the JRE is that we will be using. */
-          if (!GetJREPath(jrepath, so_jrepath, ((wanted==64)?LIBARCH64NAME:LIBARCH32NAME), JNI_TRUE)) {
-            goto EndDataModelSpeculate;
-          }
-
-          /*
-           * Read in jvm.cfg for target data model and process vm
-           * selection options.
-           */
-          if (ReadKnownVMs(jrepath, ((wanted==64)?LIBARCH64NAME:LIBARCH32NAME), JNI_TRUE) < 1) {
-            goto EndDataModelSpeculate;
-          }
-          jvmpath[0] = '\0';
-          jvmtype = CheckJvmType(_argcp, _argvp, JNI_TRUE);
-          /* exec child can do error checking on the existence of the path */
-          jvmpathExists = GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath,
-                                     ((wanted==64)?LIBARCH64NAME:LIBARCH32NAME));
-
-        }
-      EndDataModelSpeculate: /* give up and let other code report error message */
-        ;
-#else
-        fprintf(stderr, "Running a %d-bit JVM is not supported on this platform.\n", wanted);
-        exit(1);
-#endif
-      }
-
-      /*
-       * We will set the LD_LIBRARY_PATH as follows:
-       *
-       *     o          $JVMPATH (directory portion only)
-       *     o          $JRE/lib/$LIBARCHNAME
-       *     o          $JRE/../lib/$LIBARCHNAME
-       *
-       * followed by the user's previous effective LD_LIBRARY_PATH, if
-       * any.
-       */
-
-#ifdef __sun
-      /*
-       * Starting in Solaris 7, ld.so.1 supports three LD_LIBRARY_PATH
-       * variables:
-       *
-       * 1. LD_LIBRARY_PATH -- used for 32 and 64 bit searches if
-       * data-model specific variables are not set.
-       *
-       * 2. LD_LIBRARY_PATH_64 -- overrides and replaces LD_LIBRARY_PATH
-       * for 64-bit binaries.
-       *
-       * 3. LD_LIBRARY_PATH_32 -- overrides and replaces LD_LIBRARY_PATH
-       * for 32-bit binaries.
-       *
-       * The vm uses LD_LIBRARY_PATH to set the java.library.path system
-       * property.  To shield the vm from the complication of multiple
-       * LD_LIBRARY_PATH variables, if the appropriate data model
-       * specific variable is set, we will act as if LD_LIBRARY_PATH had
-       * the value of the data model specific variant and the data model
-       * specific variant will be unset.  Note that the variable for the
-       * *wanted* data model must be used (if it is set), not simply the
-       * current running data model.
-       */
-
-      switch(wanted) {
-      case 0:
-        if(running == 32) {
-          dmpath = getenv("LD_LIBRARY_PATH_32");
-          wanted = 32;
-        }
-        else {
-          dmpath = getenv("LD_LIBRARY_PATH_64");
-          wanted = 64;
-        }
-        break;
-
-      case 32:
-        dmpath = getenv("LD_LIBRARY_PATH_32");
-        break;
-
-      case 64:
-        dmpath = getenv("LD_LIBRARY_PATH_64");
-        break;
-
-      default:
-        fprintf(stderr, "Improper value at line %d.", __LINE__);
-        exit(1); /* unknown value in wanted */
-        break;
-      }
-
-      /*
-       * If dmpath is NULL, the relevant data model specific variable is
-       * not set and normal LD_LIBRARY_PATH should be used.
-       */
-      if( dmpath == NULL) {
-        runpath = getenv("LD_LIBRARY_PATH");
-      }
-      else {
-        runpath = dmpath;
-      }
-#else
-      /*
-       * If not on Solaris, assume only a single LD_LIBRARY_PATH
-       * variable.
-       */
-      runpath = getenv(LD_LIBRARY_PATH);
-#endif /* __sun */
-
-#if defined(__linux__)
-      /*
-       * On linux, if a binary is running as sgid or suid, glibc sets
-       * LD_LIBRARY_PATH to the empty string for security purposes.  (In
-       * contrast, on Solaris the LD_LIBRARY_PATH variable for a
-       * privileged binary does not lose its settings; but the dynamic
-       * linker does apply more scrutiny to the path.) The launcher uses
-       * the value of LD_LIBRARY_PATH to prevent an exec loop.
-       * Therefore, if we are running sgid or suid, this function's
-       * setting of LD_LIBRARY_PATH will be ineffective and we should
-       * return from the function now.  Getting the right libraries to
-       * be found must be handled through other mechanisms.
-       */
-      if((getgid() != getegid()) || (getuid() != geteuid()) ) {
-        return;
-      }
-#elif defined(_ALLBSD_SOURCE)
-      /*
-       * On BSD, if a binary is running as sgid or suid, libc sets
-       * LD_LIBRARY_PATH to the empty string for security purposes.  (In
-       * contrast, on Solaris the LD_LIBRARY_PATH variable for a
-       * privileged binary does not lose its settings; but the dynamic
-       * linker does apply more scrutiny to the path.) The launcher uses
-       * the value of LD_LIBRARY_PATH to prevent an exec loop.
-       * Therefore, if we are running sgid or suid, this function's
-       * setting of LD_LIBRARY_PATH will be ineffective and we should
-       * return from the function now.  Getting the right libraries to
-       * be found must be handled through other mechanisms.
-       */
-      if(issetugid()) {
-        return;
-      }
-#endif
-
-      /* runpath contains current effective LD_LIBRARY_PATH setting */
-
-      jvmpath = JLI_StringDup(jvmpath);
-      new_runpath = JLI_MemAlloc( ((runpath!=NULL)?strlen(runpath):0) +
-                              2*strlen(jrepath) + 2*strlen(arch) +
-                              strlen(jvmpath) + 52);
-      newpath = new_runpath + strlen(LD_LIBRARY_PATH "=");
-
-
-      /*
-       * Create desired LD_LIBRARY_PATH value for target data model.
-       */
-      {
-        /* remove the name of the .so from the JVM path */
-        lastslash = strrchr(jvmpath, '/');
-        if (lastslash)
-          *lastslash = '\0';
-
-
-        /* jvmpath, ((running != wanted)?((wanted==64)?"/"LIBARCH64NAME:"/.."):""), */
-
-        sprintf(new_runpath, LD_LIBRARY_PATH "="
-                "%s:"
-                "%s/lib/%s:"
-                "%s/../lib/%s",
-                jvmpath,
-#ifdef DUAL_MODE
-                jrepath, ((wanted==64)?LIBARCH64NAME:LIBARCH32NAME),
-                jrepath, ((wanted==64)?LIBARCH64NAME:LIBARCH32NAME)
-#else
-                jrepath, arch,
-                jrepath, arch
-#endif
-                );
-
-
-        /*
-         * Check to make sure that the prefix of the current path is the
-         * desired environment variable setting.
-         */
-        if (runpath != NULL &&
-            strncmp(newpath, runpath, strlen(newpath))==0 &&
-            (runpath[strlen(newpath)] == 0 || runpath[strlen(newpath)] == ':') &&
-            (running == wanted) /* data model does not have to be changed */
-#ifdef __sun
-            && (dmpath == NULL)    /* data model specific variables not set  */
-#endif
-            ) {
-
-          return;
-
-        }
-      }
-
-      /*
-       * Place the desired environment setting onto the prefix of
-       * LD_LIBRARY_PATH.  Note that this prevents any possible infinite
-       * loop of execv() because we test for the prefix, above.
-       */
-      if (runpath != 0) {
-        strcat(new_runpath, ":");
-        strcat(new_runpath, runpath);
-      }
-
-      if( putenv(new_runpath) != 0) {
-        exit(1); /* problem allocating memory; LD_LIBRARY_PATH not set
-                    properly */
-      }
-
-      /*
-       * Unix systems document that they look at LD_LIBRARY_PATH only
-       * once at startup, so we have to re-exec the current executable
-       * to get the changed environment variable to have an effect.
-       */
-
-#ifdef __sun
-      /*
-       * If dmpath is not NULL, remove the data model specific string
-       * in the environment for the exec'ed child.
-       */
-
-      if( dmpath != NULL)
-        (void)UnsetEnv((wanted==32)?"LD_LIBRARY_PATH_32":"LD_LIBRARY_PATH_64");
-#endif
-
-      newenvp = environ;
-
-      {
-        char *newexec = execname;
-#ifdef DUAL_MODE
-        /*
-         * If the data model is being changed, the path to the
-         * executable must be updated accordingly; the executable name
-         * and directory the executable resides in are separate.  In the
-         * case of 32 => 64, the new bits are assumed to reside in, e.g.
-         * "olddir/LIBARCH64NAME/execname"; in the case of 64 => 32,
-         * the bits are assumed to be in "olddir/../execname".  For example,
-         *
-         * olddir/sparcv9/execname
-         * olddir/amd64/execname
-         *
-         * for Solaris SPARC and Linux amd64, respectively.
-         */
-
-        if (running != wanted) {
-          char *oldexec = strcpy(JLI_MemAlloc(strlen(execname) + 1), execname);
-          char *olddir = oldexec;
-          char *oldbase = strrchr(oldexec, '/');
-
-
-          newexec = JLI_MemAlloc(strlen(execname) + 20);
-          *oldbase++ = 0;
-          sprintf(newexec, "%s/%s/%s", olddir,
-                  ((wanted==64) ? LIBARCH64NAME : ".."), oldbase);
-          argv[0] = newexec;
-        }
-#endif
-
-        (void)fflush(stdout);
-        (void)fflush(stderr);
-        execve(newexec, argv, newenvp);
-        perror("execve()");
-
-        fprintf(stderr, "Error trying to exec %s.\n", newexec);
-        fprintf(stderr, "Check if file exists and permissions are set correctly.\n");
-
-#ifdef DUAL_MODE
-        if (running != wanted) {
-          fprintf(stderr, "Failed to start a %d-bit JVM process from a %d-bit JVM.\n",
-                  wanted, running);
-#  ifdef __sun
-
-#    ifdef __sparc
-          fprintf(stderr, "Verify all necessary J2SE components have been installed.\n" );
-          fprintf(stderr,
-                  "(Solaris SPARC 64-bit components must be installed after 32-bit components.)\n" );
-#    else
-          fprintf(stderr, "Either 64-bit processes are not supported by this platform\n");
-          fprintf(stderr, "or the 64-bit components have not been installed.\n");
-#    endif
-        }
-#  endif
-#endif
-
-      }
-
-      exit(1);
-    }
-
-#else  /* ifndef GAMMA */
-
-  /*
-   * gamma launcher is simpler in that it doesn't handle VM flavors, data
-   * model, LD_LIBRARY_PATH, etc. Assuming everything is set-up correctly
-   * all we need to do here is to return correct path names. See also
-   * GetJVMPath() and GetApplicationHome().
-   */
-
-  { char *arch = (char *) ARCH; /* like sparc or sparcv9 */
-    char *p;
-
-    if (!GetJREPath(jrepath, so_jrepath, arch, JNI_FALSE) ) {
-      fprintf(stderr, "Error: could not find Java 2 Runtime Environment.\n");
-      exit(2);
-    }
-
-    if (!GetJVMPath(jrepath, NULL, jvmpath, so_jvmpath, arch )) {
-      fprintf(stderr, "Error: no JVM at `%s'.\n", jvmpath);
-      exit(4);
-    }
-  }
-
-#endif  /* ifndef GAMMA */
-}
-
-
-/*
- * On Solaris VM choosing is done by the launcher (java.c).
- */
-static jboolean
-GetJVMPath(const char *jrepath, const char *jvmtype,
-           char *jvmpath, jint jvmpathsize, char * arch)
-{
-    struct stat s;
-
-#ifndef GAMMA
-    if (strchr(jvmtype, '/')) {
-        sprintf(jvmpath, "%s/" JVM_DLL, jvmtype);
-    } else {
-        sprintf(jvmpath, "%s/lib/%s/%s/" JVM_DLL, jrepath, arch, jvmtype);
-    }
-#else
-    /*
-     * For gamma launcher, JVM is either built-in or in the same directory.
-     * Either way we return "<exe_path>/libjvm.so" where <exe_path> is the
-     * directory where gamma launcher is located.
-     */
-
-    char *p;
-
-    snprintf(jvmpath, jvmpathsize, "%s", GetExecname());
-    p = strrchr(jvmpath, '/');
-    if (p) {
-       /* replace executable name with libjvm.so */
-       snprintf(p + 1, jvmpathsize - (p + 1 - jvmpath), "%s", JVM_DLL);
-    } else {
-       /* this case shouldn't happen */
-       snprintf(jvmpath, jvmpathsize, "%s", JVM_DLL);
-    }
-#endif /* ifndef GAMMA */
-
-    if (_launcher_debug)
-      printf("Does `%s' exist ... ", jvmpath);
-
-    if (stat(jvmpath, &s) == 0) {
-        if (_launcher_debug)
-          printf("yes.\n");
-        return JNI_TRUE;
-    } else {
-        if (_launcher_debug)
-          printf("no.\n");
-        return JNI_FALSE;
-    }
-}
-
-/*
- * Find path to JRE based on .exe's location or registry settings.
- */
-static jboolean
-GetJREPath(char *path, jint pathsize, char * arch, jboolean speculative)
-{
-    char libjava[MAXPATHLEN];
-
-    if (GetApplicationHome(path, pathsize)) {
-
-        /* Is the JRE universal, i.e. no arch dir? */
-        sprintf(libjava, "%s/jre/lib/" JAVA_DLL, path);
-        if (access(libjava, F_OK) == 0) {
-            strcat(path, "/jre");
-            goto found;
-        }
-
-        /* Is JRE co-located with the application? */
-        sprintf(libjava, "%s/lib/%s/" JAVA_DLL, path, arch);
-        if (access(libjava, F_OK) == 0) {
-            goto found;
-        }
-
-        /* Does the app ship a private JRE in <apphome>/jre directory? */
-        sprintf(libjava, "%s/jre/lib/%s/" JAVA_DLL, path, arch);
-        if (access(libjava, F_OK) == 0) {
-            strcat(path, "/jre");
-            goto found;
-        }
-    }
-
-    if (!speculative)
-      fprintf(stderr, "Error: could not find " JAVA_DLL "\n");
-    return JNI_FALSE;
-
- found:
-    if (_launcher_debug)
-      printf("JRE path is %s\n", path);
-    return JNI_TRUE;
-}
-
-jboolean
-LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn)
-{
-#ifdef GAMMA
-    /* JVM is directly linked with gamma launcher; no dlopen() */
-    ifn->CreateJavaVM = JNI_CreateJavaVM;
-    ifn->GetDefaultJavaVMInitArgs = JNI_GetDefaultJavaVMInitArgs;
-    return JNI_TRUE;
-#else
-    Dl_info dlinfo;
-    void *libjvm;
-
-    if (_launcher_debug) {
-        printf("JVM path is %s\n", jvmpath);
-    }
-
-    libjvm = dlopen(jvmpath, RTLD_NOW + RTLD_GLOBAL);
-    if (libjvm == NULL) {
-#if defined(__sparc) && !defined(_LP64) /* i.e. 32-bit sparc */
-      FILE * fp;
-      Elf32_Ehdr elf_head;
-      int count;
-      int location;
-
-      fp = fopen(jvmpath, "r");
-      if(fp == NULL)
-        goto error;
-
-      /* read in elf header */
-      count = fread((void*)(&elf_head), sizeof(Elf32_Ehdr), 1, fp);
-      fclose(fp);
-      if(count < 1)
-        goto error;
-
-      /*
-       * Check for running a server vm (compiled with -xarch=v8plus)
-       * on a stock v8 processor.  In this case, the machine type in
-       * the elf header would not be included the architecture list
-       * provided by the isalist command, which is turn is gotten from
-       * sysinfo.  This case cannot occur on 64-bit hardware and thus
-       * does not have to be checked for in binaries with an LP64 data
-       * model.
-       */
-      if(elf_head.e_machine == EM_SPARC32PLUS) {
-        char buf[257];  /* recommended buffer size from sysinfo man
-                           page */
-        long length;
-        char* location;
-
-        length = sysinfo(SI_ISALIST, buf, 257);
-        if(length > 0) {
-          location = strstr(buf, "sparcv8plus ");
-          if(location == NULL) {
-            fprintf(stderr, "SPARC V8 processor detected; Server compiler requires V9 or better.\n");
-            fprintf(stderr, "Use Client compiler on V8 processors.\n");
-            fprintf(stderr, "Could not create the Java virtual machine.\n");
-            return JNI_FALSE;
-          }
-        }
-      }
-#endif
-      fprintf(stderr, "dl failure on line %d", __LINE__);
-      goto error;
-    }
-
-    ifn->CreateJavaVM = (CreateJavaVM_t)
-      dlsym(libjvm, "JNI_CreateJavaVM");
-    if (ifn->CreateJavaVM == NULL)
-        goto error;
-
-    ifn->GetDefaultJavaVMInitArgs = (GetDefaultJavaVMInitArgs_t)
-        dlsym(libjvm, "JNI_GetDefaultJavaVMInitArgs");
-    if (ifn->GetDefaultJavaVMInitArgs == NULL)
-      goto error;
-
-    return JNI_TRUE;
-
-error:
-    fprintf(stderr, "Error: failed %s, because %s\n", jvmpath, dlerror());
-    return JNI_FALSE;
-#endif /* ifndef GAMMA */
-}
-
-/*
- * If app is "/foo/bin/javac", or "/foo/bin/sparcv9/javac" then put
- * "/foo" into buf.
- */
-jboolean
-GetApplicationHome(char *buf, jint bufsize)
-{
-#if defined(__linux__) || defined(_ALLBSD_SOURCE)
-    char *execname = GetExecname();
-    if (execname) {
-        strncpy(buf, execname, bufsize-1);
-        buf[bufsize-1] = '\0';
-    } else {
-        return JNI_FALSE;
-    }
-#else
-    Dl_info dlinfo;
-
-    dladdr((void *)GetApplicationHome, &dlinfo);
-    if (realpath(dlinfo.dli_fname, buf) == NULL) {
-        fprintf(stderr, "Error: realpath(`%s') failed.\n", dlinfo.dli_fname);
-        return JNI_FALSE;
-    }
-#endif
-
-#ifdef GAMMA
-    {
-       /* gamma launcher uses JAVA_HOME environment variable to find JDK/JRE */
-       char* java_home_var = getenv("JAVA_HOME");
-       if (java_home_var == NULL) {
-          printf("JAVA_HOME must point to a valid JDK/JRE to run gamma\n");
-          return JNI_FALSE;
-       }
-       snprintf(buf, bufsize, "%s", java_home_var);
-    }
-#else
-    if (strrchr(buf, '/') == 0) {
-        buf[0] = '\0';
-        return JNI_FALSE;
-    }
-    *(strrchr(buf, '/')) = '\0';        /* executable file      */
-    if (strlen(buf) < 4 || strrchr(buf, '/') == 0) {
-        buf[0] = '\0';
-        return JNI_FALSE;
-    }
-    if (strcmp("/bin", buf + strlen(buf) - 4) != 0)
-        *(strrchr(buf, '/')) = '\0';    /* sparcv9 or amd64     */
-    if (strlen(buf) < 4 || strcmp("/bin", buf + strlen(buf) - 4) != 0) {
-        buf[0] = '\0';
-        return JNI_FALSE;
-    }
-    *(strrchr(buf, '/')) = '\0';        /* bin                  */
-#endif /* ifndef GAMMA */
-
-    return JNI_TRUE;
-}
-
-
-/*
- * Return true if the named program exists
- */
-static int
-ProgramExists(char *name)
-{
-    struct stat sb;
-    if (stat(name, &sb) != 0) return 0;
-    if (S_ISDIR(sb.st_mode)) return 0;
-    return (sb.st_mode & S_IEXEC) != 0;
-}
-
-
-/*
- * Find a command in a directory, returning the path.
- */
-static char *
-Resolve(char *indir, char *cmd)
-{
-    char name[PATH_MAX + 2], *real;
-
-    if ((strlen(indir) + strlen(cmd) + 1)  > PATH_MAX) return 0;
-    sprintf(name, "%s%c%s", indir, FILE_SEPARATOR, cmd);
-    if (!ProgramExists(name)) return 0;
-    real = JLI_MemAlloc(PATH_MAX + 2);
-    if (!realpath(name, real))
-        strcpy(real, name);
-    return real;
-}
-
-
-/*
- * Find a path for the executable
- */
-static char *
-FindExecName(char *program)
-{
-    char cwdbuf[PATH_MAX+2];
-    char *path;
-    char *tmp_path;
-    char *f;
-    char *result = NULL;
-
-    /* absolute path? */
-    if (*program == FILE_SEPARATOR ||
-        (FILE_SEPARATOR=='\\' && strrchr(program, ':')))
-        return Resolve("", program+1);
-
-    /* relative path? */
-    if (strrchr(program, FILE_SEPARATOR) != 0) {
-        char buf[PATH_MAX+2];
-        return Resolve(getcwd(cwdbuf, sizeof(cwdbuf)), program);
-    }
-
-    /* from search path? */
-    path = getenv("PATH");
-    if (!path || !*path) path = ".";
-    tmp_path = JLI_MemAlloc(strlen(path) + 2);
-    strcpy(tmp_path, path);
-
-    for (f=tmp_path; *f && result==0; ) {
-        char *s = f;
-        while (*f && (*f != PATH_SEPARATOR)) ++f;
-        if (*f) *f++ = 0;
-        if (*s == FILE_SEPARATOR)
-            result = Resolve(s, program);
-        else {
-            /* relative path element */
-            char dir[2*PATH_MAX];
-            sprintf(dir, "%s%c%s", getcwd(cwdbuf, sizeof(cwdbuf)),
-                    FILE_SEPARATOR, s);
-            result = Resolve(dir, program);
-        }
-        if (result != 0) break;
-    }
-
-    JLI_MemFree(tmp_path);
-    return result;
-}
-
-
-/* Store the name of the executable once computed */
-static char *execname = NULL;
-
-/*
- * Compute the name of the executable
- *
- * In order to re-exec securely we need the absolute path of the
- * executable. On Solaris getexecname(3c) may not return an absolute
- * path so we use dladdr to get the filename of the executable and
- * then use realpath to derive an absolute path. From Solaris 9
- * onwards the filename returned in DL_info structure from dladdr is
- * an absolute pathname so technically realpath isn't required.
- * On Linux we read the executable name from /proc/self/exe.
- * As a fallback, and for platforms other than Solaris and Linux,
- * we use FindExecName to compute the executable name.
- */
-static char *
-SetExecname(char **argv)
-{
-    char* exec_path = NULL;
-
-    if (execname != NULL)       /* Already determined */
-        return (execname);
-
-#if defined(__sun)
-    {
-        Dl_info dlinfo;
-        if (dladdr((void*)&SetExecname, &dlinfo)) {
-            char *resolved = (char*)JLI_MemAlloc(PATH_MAX+1);
-            if (resolved != NULL) {
-                exec_path = realpath(dlinfo.dli_fname, resolved);
-                if (exec_path == NULL) {
-                    JLI_MemFree(resolved);
-                }
-            }
-        }
-    }
-#elif defined(__linux__)
-    {
-        const char* self = "/proc/self/exe";
-        char buf[PATH_MAX+1];
-        int len = readlink(self, buf, PATH_MAX);
-        if (len >= 0) {
-            buf[len] = '\0';            /* readlink doesn't nul terminate */
-            exec_path = JLI_StringDup(buf);
-        }
-    }
-#else /* !__sun && !__linux */
-    {
-        /* Not implemented */
-    }
-#endif
-
-    if (exec_path == NULL) {
-        exec_path = FindExecName(argv[0]);
-    }
-    execname = exec_path;
-    return exec_path;
-}
-
-/*
- * Return the name of the executable.  Used in java_md.c to find the JRE area.
- */
-static char *
-GetExecname() {
-  return execname;
-}
-
-void ReportErrorMessage(char * message, jboolean always) {
-  if (always) {
-    fprintf(stderr, "%s\n", message);
-  }
-}
-
-void ReportErrorMessage2(char * format, char * string, jboolean always) {
-  if (always) {
-    fprintf(stderr, format, string);
-    fprintf(stderr, "\n");
-  }
-}
-
-void  ReportExceptionDescription(JNIEnv * env) {
-  (*env)->ExceptionDescribe(env);
-}
-
-/*
- * Return JNI_TRUE for an option string that has no effect but should
- * _not_ be passed on to the vm; return JNI_FALSE otherwise.  On
- * Solaris SPARC, this screening needs to be done if:
- * 1) LD_LIBRARY_PATH does _not_ need to be reset and
- * 2) -d32 or -d64 is passed to a binary with a matching data model
- *    (the exec in SetLibraryPath removes -d<n> options and points the
- *    exec to the proper binary).  When this exec is not done, these options
- *    would end up getting passed onto the vm.
- */
-jboolean RemovableMachineDependentOption(char * option) {
-  /*
-   * Unconditionally remove both -d32 and -d64 options since only
-   * the last such options has an effect; e.g.
-   * java -d32 -d64 -d32 -version
-   * is equivalent to
-   * java -d32 -version
-   */
-
-  if( (strcmp(option, "-d32")  == 0 ) ||
-      (strcmp(option, "-d64")  == 0 ))
-    return JNI_TRUE;
-  else
-    return JNI_FALSE;
-}
-
-void PrintMachineDependentOptions() {
-      fprintf(stdout,
-        "    -d32          use a 32-bit data model if available\n"
-        "\n"
-        "    -d64          use a 64-bit data model if available\n");
-      return;
-}
-
-#ifndef GAMMA
-/*
- * The following methods (down to ServerClassMachine()) answer
- * the question about whether a machine is a "server-class"
- * machine.  A server-class machine is loosely defined as one
- * with 2 or more processors and 2 gigabytes or more physical
- * memory.  The definition of a processor is a physical package,
- * not a hyperthreaded chip masquerading as a multi-processor.
- * The definition of memory is also somewhat fuzzy, since x86
- * machines seem not to report all the memory in their DIMMs, we
- * think because of memory mapping of graphics cards, etc.
- *
- * This code is somewhat more confused with #ifdef's than we'd
- * like because this file is used by both Solaris and Linux
- * platforms, and so needs to be parameterized for SPARC and
- * i586 hardware.  The other Linux platforms (amd64 and ia64)
- * don't even ask this question, because they only come with
- * server JVMs.  */
-
-# define KB (1024UL)
-# define MB (1024UL * KB)
-# define GB (1024UL * MB)
-
-/* Compute physical memory by asking the OS */
-uint64_t
-physical_memory(void) {
-  const uint64_t pages     = (uint64_t) sysconf(_SC_PHYS_PAGES);
-  const uint64_t page_size = (uint64_t) sysconf(_SC_PAGESIZE);
-  const uint64_t result    = pages * page_size;
-# define UINT64_FORMAT "%" PRIu64
-
-  if (_launcher_debug) {
-    printf("pages: " UINT64_FORMAT
-           "  page_size: " UINT64_FORMAT
-           "  physical memory: " UINT64_FORMAT " (%.3fGB)\n",
-           pages, page_size, result, result / (double) GB);
-  }
-  return result;
-}
-
-#if defined(__sun) && defined(__sparc)
-
-/* Methods for solaris-sparc: these are easy. */
-
-/* Ask the OS how many processors there are. */
-unsigned long
-physical_processors(void) {
-  const unsigned long sys_processors = sysconf(_SC_NPROCESSORS_CONF);
-
-  if (_launcher_debug) {
-    printf("sysconf(_SC_NPROCESSORS_CONF): %lu\n", sys_processors);
-  }
-  return sys_processors;
-}
-
-/* The solaris-sparc version of the "server-class" predicate. */
-jboolean
-solaris_sparc_ServerClassMachine(void) {
-  jboolean            result            = JNI_FALSE;
-  /* How big is a server class machine? */
-  const unsigned long server_processors = 2UL;
-  const uint64_t      server_memory     = 2UL * GB;
-  const uint64_t      actual_memory     = physical_memory();
-
-  /* Is this a server class machine? */
-  if (actual_memory >= server_memory) {
-    const unsigned long actual_processors = physical_processors();
-    if (actual_processors >= server_processors) {
-      result = JNI_TRUE;
-    }
-  }
-  if (_launcher_debug) {
-    printf("solaris_" LIBARCHNAME "_ServerClassMachine: %s\n",
-           (result == JNI_TRUE ? "JNI_TRUE" : "JNI_FALSE"));
-  }
-  return result;
-}
-
-#endif /* __sun && __sparc */
-
-#if defined(__sun) && defined(i586)
-
-/*
- * A utility method for asking the CPU about itself.
- * There's a corresponding version of linux-i586
- * because the compilers are different.
- */
-void
-get_cpuid(uint32_t arg,
-          uint32_t* eaxp,
-          uint32_t* ebxp,
-          uint32_t* ecxp,
-          uint32_t* edxp) {
-#ifdef _LP64
-  asm(
-  /* rbx is a callee-saved register */
-      " movq    %rbx, %r11  \n"
-  /* rdx and rcx are 3rd and 4th argument registers */
-      " movq    %rdx, %r10  \n"
-      " movq    %rcx, %r9   \n"
-      " movl    %edi, %eax  \n"
-      " cpuid               \n"
-      " movl    %eax, (%rsi)\n"
-      " movl    %ebx, (%r10)\n"
-      " movl    %ecx, (%r9) \n"
-      " movl    %edx, (%r8) \n"
-  /* Restore rbx */
-      " movq    %r11, %rbx");
-#else
-  /* EBX is a callee-saved register */
-  asm(" pushl   %ebx");
-  /* Need ESI for storing through arguments */
-  asm(" pushl   %esi");
-  asm(" movl    8(%ebp), %eax   \n"
-      " cpuid                   \n"
-      " movl    12(%ebp), %esi  \n"
-      " movl    %eax, (%esi)    \n"
-      " movl    16(%ebp), %esi  \n"
-      " movl    %ebx, (%esi)    \n"
-      " movl    20(%ebp), %esi  \n"
-      " movl    %ecx, (%esi)    \n"
-      " movl    24(%ebp), %esi  \n"
-      " movl    %edx, (%esi)      ");
-  /* Restore ESI and EBX */
-  asm(" popl    %esi");
-  /* Restore EBX */
-  asm(" popl    %ebx");
-#endif
-}
-
-#endif /* __sun && i586 */
-
-#if (defined(__linux__) || defined(_ALLBSD_SOURCE)) && defined(i586)
-
-/*
- * A utility method for asking the CPU about itself.
- * There's a corresponding version of solaris-i586
- * because the compilers are different.
- */
-void
-get_cpuid(uint32_t arg,
-          uint32_t* eaxp,
-          uint32_t* ebxp,
-          uint32_t* ecxp,
-          uint32_t* edxp) {
-#ifdef _LP64
-  __asm__ volatile (/* Instructions */
-                    "   movl    %4, %%eax  \n"
-                    "   cpuid              \n"
-                    "   movl    %%eax, (%0)\n"
-                    "   movl    %%ebx, (%1)\n"
-                    "   movl    %%ecx, (%2)\n"
-                    "   movl    %%edx, (%3)\n"
-                    : /* Outputs */
-                    : /* Inputs */
-                    "r" (eaxp),
-                    "r" (ebxp),
-                    "r" (ecxp),
-                    "r" (edxp),
-                    "r" (arg)
-                    : /* Clobbers */
-                    "%rax", "%rbx", "%rcx", "%rdx", "memory"
-                    );
-#else
-  uint32_t value_of_eax = 0;
-  uint32_t value_of_ebx = 0;
-  uint32_t value_of_ecx = 0;
-  uint32_t value_of_edx = 0;
-  __asm__ volatile (/* Instructions */
-                        /* ebx is callee-save, so push it */
-                    "   pushl   %%ebx      \n"
-                    "   movl    %4, %%eax  \n"
-                    "   cpuid              \n"
-                    "   movl    %%eax, %0  \n"
-                    "   movl    %%ebx, %1  \n"
-                    "   movl    %%ecx, %2  \n"
-                    "   movl    %%edx, %3  \n"
-                        /* restore ebx */
-                    "   popl    %%ebx      \n"
-
-                    : /* Outputs */
-                    "=m" (value_of_eax),
-                    "=m" (value_of_ebx),
-                    "=m" (value_of_ecx),
-                    "=m" (value_of_edx)
-                    : /* Inputs */
-                    "m" (arg)
-                    : /* Clobbers */
-                    "%eax", "%ecx", "%edx"
-                    );
-  *eaxp = value_of_eax;
-  *ebxp = value_of_ebx;
-  *ecxp = value_of_ecx;
-  *edxp = value_of_edx;
-#endif
-}
-
-#endif /* __linux__ && i586 */
-
-#ifdef i586
-/*
- * Routines shared by solaris-i586 and linux-i586.
- */
-
-enum HyperThreadingSupport_enum {
-  hts_supported        =  1,
-  hts_too_soon_to_tell =  0,
-  hts_not_supported    = -1,
-  hts_not_pentium4     = -2,
-  hts_not_intel        = -3
-};
-typedef enum HyperThreadingSupport_enum HyperThreadingSupport;
-
-/* Determine if hyperthreading is supported */
-HyperThreadingSupport
-hyperthreading_support(void) {
-  HyperThreadingSupport result = hts_too_soon_to_tell;
-  /* Bits 11 through 8 is family processor id */
-# define FAMILY_ID_SHIFT 8
-# define FAMILY_ID_MASK 0xf
-  /* Bits 23 through 20 is extended family processor id */
-# define EXT_FAMILY_ID_SHIFT 20
-# define EXT_FAMILY_ID_MASK 0xf
-  /* Pentium 4 family processor id */
-# define PENTIUM4_FAMILY_ID 0xf
-  /* Bit 28 indicates Hyper-Threading Technology support */
-# define HT_BIT_SHIFT 28
-# define HT_BIT_MASK 1
-  uint32_t vendor_id[3] = { 0U, 0U, 0U };
-  uint32_t value_of_eax = 0U;
-  uint32_t value_of_edx = 0U;
-  uint32_t dummy        = 0U;
-
-  /* Yes, this is supposed to be [0], [2], [1] */
-  get_cpuid(0, &dummy, &vendor_id[0], &vendor_id[2], &vendor_id[1]);
-  if (_launcher_debug) {
-    printf("vendor: %c %c %c %c %c %c %c %c %c %c %c %c \n",
-           ((vendor_id[0] >>  0) & 0xff),
-           ((vendor_id[0] >>  8) & 0xff),
-           ((vendor_id[0] >> 16) & 0xff),
-           ((vendor_id[0] >> 24) & 0xff),
-           ((vendor_id[1] >>  0) & 0xff),
-           ((vendor_id[1] >>  8) & 0xff),
-           ((vendor_id[1] >> 16) & 0xff),
-           ((vendor_id[1] >> 24) & 0xff),
-           ((vendor_id[2] >>  0) & 0xff),
-           ((vendor_id[2] >>  8) & 0xff),
-           ((vendor_id[2] >> 16) & 0xff),
-           ((vendor_id[2] >> 24) & 0xff));
-  }
-  get_cpuid(1, &value_of_eax, &dummy, &dummy, &value_of_edx);
-  if (_launcher_debug) {
-    printf("value_of_eax: 0x%x  value_of_edx: 0x%x\n",
-           value_of_eax, value_of_edx);
-  }
-  if ((((value_of_eax >> FAMILY_ID_SHIFT) & FAMILY_ID_MASK) == PENTIUM4_FAMILY_ID) ||
-      (((value_of_eax >> EXT_FAMILY_ID_SHIFT) & EXT_FAMILY_ID_MASK) != 0)) {
-    if ((((vendor_id[0] >>  0) & 0xff) == 'G') &&
-        (((vendor_id[0] >>  8) & 0xff) == 'e') &&
-        (((vendor_id[0] >> 16) & 0xff) == 'n') &&
-        (((vendor_id[0] >> 24) & 0xff) == 'u') &&
-        (((vendor_id[1] >>  0) & 0xff) == 'i') &&
-        (((vendor_id[1] >>  8) & 0xff) == 'n') &&
-        (((vendor_id[1] >> 16) & 0xff) == 'e') &&
-        (((vendor_id[1] >> 24) & 0xff) == 'I') &&
-        (((vendor_id[2] >>  0) & 0xff) == 'n') &&
-        (((vendor_id[2] >>  8) & 0xff) == 't') &&
-        (((vendor_id[2] >> 16) & 0xff) == 'e') &&
-        (((vendor_id[2] >> 24) & 0xff) == 'l')) {
-      if (((value_of_edx >> HT_BIT_SHIFT) & HT_BIT_MASK) == HT_BIT_MASK) {
-        if (_launcher_debug) {
-          printf("Hyperthreading supported\n");
-        }
-        result = hts_supported;
-      } else {
-        if (_launcher_debug) {
-          printf("Hyperthreading not supported\n");
-        }
-        result = hts_not_supported;
-      }
-    } else {
-      if (_launcher_debug) {
-        printf("Not GenuineIntel\n");
-      }
-      result = hts_not_intel;
-    }
-  } else {
-    if (_launcher_debug) {
-      printf("not Pentium 4 or extended\n");
-    }
-    result = hts_not_pentium4;
-  }
-  return result;
-}
-
-/* Determine how many logical processors there are per CPU */
-unsigned int
-logical_processors_per_package(void) {
-  /*
-   * After CPUID with EAX==1, register EBX bits 23 through 16
-   * indicate the number of logical processors per package
-   */
-# define NUM_LOGICAL_SHIFT 16
-# define NUM_LOGICAL_MASK 0xff
-  unsigned int result                        = 1U;
-  const HyperThreadingSupport hyperthreading = hyperthreading_support();
-
-  if (hyperthreading == hts_supported) {
-    uint32_t value_of_ebx = 0U;
-    uint32_t dummy        = 0U;
-
-    get_cpuid(1, &dummy, &value_of_ebx, &dummy, &dummy);
-    result = (value_of_ebx >> NUM_LOGICAL_SHIFT) & NUM_LOGICAL_MASK;
-    if (_launcher_debug) {
-      printf("logical processors per package: %u\n", result);
-    }
-  }
-  return result;
-}
-
-/* Compute the number of physical processors, not logical processors */
-unsigned long
-physical_processors(void) {
-  const long sys_processors = sysconf(_SC_NPROCESSORS_CONF);
-  unsigned long result      = sys_processors;
-
-  if (_launcher_debug) {
-    printf("sysconf(_SC_NPROCESSORS_CONF): %lu\n", sys_processors);
-  }
-  if (sys_processors > 1) {
-    unsigned int logical_processors = logical_processors_per_package();
-    if (logical_processors > 1) {
-      result = (unsigned long) sys_processors / logical_processors;
-    }
-  }
-  if (_launcher_debug) {
-    printf("physical processors: %lu\n", result);
-  }
-  return result;
-}
-
-#endif /* i586 */
-
-#if defined(__sun) && defined(i586)
-
-/* The definition of a server-class machine for solaris-i586/amd64 */
-jboolean
-solaris_i586_ServerClassMachine(void) {
-  jboolean            result            = JNI_FALSE;
-  /* How big is a server class machine? */
-  const unsigned long server_processors = 2UL;
-  const uint64_t      server_memory     = 2UL * GB;
-  /*
-   * We seem not to get our full complement of memory.
-   *     We allow some part (1/8?) of the memory to be "missing",
-   *     based on the sizes of DIMMs, and maybe graphics cards.
-   */
-  const uint64_t      missing_memory    = 256UL * MB;
-  const uint64_t      actual_memory     = physical_memory();
-
-  /* Is this a server class machine? */
-  if (actual_memory >= (server_memory - missing_memory)) {
-    const unsigned long actual_processors = physical_processors();
-    if (actual_processors >= server_processors) {
-      result = JNI_TRUE;
-    }
-  }
-  if (_launcher_debug) {
-    printf("solaris_" LIBARCHNAME "_ServerClassMachine: %s\n",
-           (result == JNI_TRUE ? "true" : "false"));
-  }
-  return result;
-}
-
-#endif /* __sun && i586 */
-
-#if defined(__linux__) && defined(i586)
-
-/* The definition of a server-class machine for linux-i586 */
-jboolean
-linux_i586_ServerClassMachine(void) {
-  jboolean            result            = JNI_FALSE;
-  /* How big is a server class machine? */
-  const unsigned long server_processors = 2UL;
-  const uint64_t      server_memory     = 2UL * GB;
-  /*
-   * We seem not to get our full complement of memory.
-   *     We allow some part (1/8?) of the memory to be "missing",
-   *     based on the sizes of DIMMs, and maybe graphics cards.
-   */
-  const uint64_t      missing_memory    = 256UL * MB;
-  const uint64_t      actual_memory     = physical_memory();
-
-  /* Is this a server class machine? */
-  if (actual_memory >= (server_memory - missing_memory)) {
-    const unsigned long actual_processors = physical_processors();
-    if (actual_processors >= server_processors) {
-      result = JNI_TRUE;
-    }
-  }
-  if (_launcher_debug) {
-    printf("linux_" LIBARCHNAME "_ServerClassMachine: %s\n",
-           (result == JNI_TRUE ? "true" : "false"));
-  }
-  return result;
-}
-
-#endif /* __linux__ && i586 */
-
-#if defined(_ALLBSD_SOURCE) && defined(i586)
-
-/* The definition of a server-class machine for bsd-i586 */
-jboolean
-bsd_i586_ServerClassMachine(void) {
-  jboolean            result            = JNI_FALSE;
-  /* How big is a server class machine? */
-  const unsigned long server_processors = 2UL;
-  const uint64_t      server_memory     = 2UL * GB;
-  /*
-   * We seem not to get our full complement of memory.
-   *     We allow some part (1/8?) of the memory to be "missing",
-   *     based on the sizes of DIMMs, and maybe graphics cards.
-   */
-  const uint64_t      missing_memory    = 256UL * MB;
-  const uint64_t      actual_memory     = physical_memory();
-
-  /* Is this a server class machine? */
-  if (actual_memory >= (server_memory - missing_memory)) {
-    const unsigned long actual_processors = physical_processors();
-    if (actual_processors >= server_processors) {
-      result = JNI_TRUE;
-    }
-  }
-  if (_launcher_debug) {
-    printf("linux_" LIBARCHNAME "_ServerClassMachine: %s\n",
-           (result == JNI_TRUE ? "true" : "false"));
-  }
-  return result;
-}
-
-#endif /* _ALLBSD_SOURCE && i586 */
-
-/* Dispatch to the platform-specific definition of "server-class" */
-jboolean
-ServerClassMachine(void) {
-  jboolean result = JNI_FALSE;
-#if   defined(NEVER_ACT_AS_SERVER_CLASS_MACHINE)
-  result = JNI_FALSE;
-#elif defined(ALWAYS_ACT_AS_SERVER_CLASS_MACHINE)
-  result = JNI_TRUE;
-#elif defined(__sun) && defined(__sparc)
-  result = solaris_sparc_ServerClassMachine();
-#elif defined(__sun) && defined(i586)
-  result = solaris_i586_ServerClassMachine();
-#elif defined(__linux__) && defined(i586)
-  result = linux_i586_ServerClassMachine();
-#elif defined(_ALLBSD_SOURCE) && defined(i586)
-  result = bsd_i586_ServerClassMachine();
-#else
-  if (_launcher_debug) {
-    printf("ServerClassMachine: returns default value of %s\n",
-           (result == JNI_TRUE ? "true" : "false"));
-  }
-#endif
-  return result;
-}
-
-/*
- *      Since using the file system as a registry is a bit risky, perform
- *      additional sanity checks on the identified directory to validate
- *      it as a valid jre/sdk.
- *
- *      Return 0 if the tests fail; otherwise return non-zero (true).
- *
- *      Note that checking for anything more than the existence of an
- *      executable object at bin/java relative to the path being checked
- *      will break the regression tests.
- */
-static int
-CheckSanity(char *path, char *dir)
-{
-    char    buffer[PATH_MAX];
-
-    if (strlen(path) + strlen(dir) + 11 > PATH_MAX)
-        return (0);     /* Silently reject "impossibly" long paths */
-
-    (void)strcat(strcat(strcat(strcpy(buffer, path), "/"), dir), "/bin/java");
-    return ((access(buffer, X_OK) == 0) ? 1 : 0);
-}
-
-/*
- *      Determine if there is an acceptable JRE in the directory dirname.
- *      Upon locating the "best" one, return a fully qualified path to
- *      it. "Best" is defined as the most advanced JRE meeting the
- *      constraints contained in the manifest_info. If no JRE in this
- *      directory meets the constraints, return NULL.
- *
- *      Note that we don't check for errors in reading the directory
- *      (which would be done by checking errno).  This is because it
- *      doesn't matter if we get an error reading the directory, or
- *      we just don't find anything interesting in the directory.  We
- *      just return NULL in either case.
- *
- *      The historical names of j2sdk and j2re were changed to jdk and
- *      jre respecively as part of the 1.5 rebranding effort.  Since the
- *      former names are legacy on Linux, they must be recognized for
- *      all time.  Fortunately, this is a minor cost.
- */
-static char
-*ProcessDir(manifest_info *info, char *dirname)
-{
-    DIR     *dirp;
-    struct dirent *dp;
-    char    *best = NULL;
-    int     offset;
-    int     best_offset = 0;
-    char    *ret_str = NULL;
-    char    buffer[PATH_MAX];
-
-    if ((dirp = opendir(dirname)) == NULL)
-        return (NULL);
-
-    do {
-        if ((dp = readdir(dirp)) != NULL) {
-            offset = 0;
-            if ((strncmp(dp->d_name, "jre", 3) == 0) ||
-                (strncmp(dp->d_name, "jdk", 3) == 0))
-                offset = 3;
-            else if (strncmp(dp->d_name, "j2re", 4) == 0)
-                offset = 4;
-            else if (strncmp(dp->d_name, "j2sdk", 5) == 0)
-                offset = 5;
-            if (offset > 0) {
-                if ((JLI_AcceptableRelease(dp->d_name + offset,
-                    info->jre_version)) && CheckSanity(dirname, dp->d_name))
-                    if ((best == NULL) || (JLI_ExactVersionId(
-                      dp->d_name + offset, best + best_offset) > 0)) {
-                        if (best != NULL)
-                            JLI_MemFree(best);
-                        best = JLI_StringDup(dp->d_name);
-                        best_offset = offset;
-                    }
-            }
-        }
-    } while (dp != NULL);
-    (void) closedir(dirp);
-    if (best == NULL)
-        return (NULL);
-    else {
-        ret_str = JLI_MemAlloc(strlen(dirname) + strlen(best) + 2);
-        ret_str = strcat(strcat(strcpy(ret_str, dirname), "/"), best);
-        JLI_MemFree(best);
-        return (ret_str);
-    }
-}
-
-/*
- *      This is the global entry point. It examines the host for the optimal
- *      JRE to be used by scanning a set of directories.  The set of directories
- *      is platform dependent and can be overridden by the environment
- *      variable JAVA_VERSION_PATH.
- *
- *      This routine itself simply determines the set of appropriate
- *      directories before passing control onto ProcessDir().
- */
-char*
-LocateJRE(manifest_info* info)
-{
-    char        *path;
-    char        *home;
-    char        *target = NULL;
-    char        *dp;
-    char        *cp;
-
-    /*
-     * Start by getting JAVA_VERSION_PATH
-     */
-    if (info->jre_restrict_search)
-        path = JLI_StringDup(system_dir);
-    else if ((path = getenv("JAVA_VERSION_PATH")) != NULL)
-        path = JLI_StringDup(path);
-    else
-        if ((home = getenv("HOME")) != NULL) {
-            path = (char *)JLI_MemAlloc(strlen(home) + strlen(system_dir) +
-                strlen(user_dir) + 2);
-            path = strcat(strcat(strcat(strcpy(path, home),
-                user_dir), ":"), system_dir);
-        } else
-            path = JLI_StringDup(system_dir);
-
-    /*
-     * Step through each directory on the path. Terminate the scan with
-     * the first directory with an acceptable JRE.
-     */
-    cp = dp = path;
-    while (dp != NULL) {
-        cp = strchr(dp, (int)':');
-        if (cp != NULL)
-            *cp = (char)NULL;
-        if ((target = ProcessDir(info, dp)) != NULL)
-            break;
-        dp = cp;
-        if (dp != NULL)
-            dp++;
-    }
-    JLI_MemFree(path);
-    return (target);
-}
-
-/*
- * Given a path to a jre to execute, this routine checks if this process
- * is indeed that jre.  If not, it exec's that jre.
- *
- * We want to actually check the paths rather than just the version string
- * built into the executable, so that given version specification (and
- * JAVA_VERSION_PATH) will yield the exact same Java environment, regardless
- * of the version of the arbitrary launcher we start with.
- */
-void
-ExecJRE(char *jre, char **argv)
-{
-    char    wanted[PATH_MAX];
-    char    *execname;
-    char    *progname;
-
-    /*
-     * Resolve the real path to the directory containing the selected JRE.
-     */
-    if (realpath(jre, wanted) == NULL) {
-        fprintf(stderr, "Unable to resolve %s\n", jre);
-        exit(1);
-    }
-
-    /*
-     * Resolve the real path to the currently running launcher.
-     */
-    execname = SetExecname(argv);
-    if (execname == NULL) {
-        fprintf(stderr, "Unable to resolve current executable\n");
-        exit(1);
-    }
-
-    /*
-     * If the path to the selected JRE directory is a match to the initial
-     * portion of the path to the currently executing JRE, we have a winner!
-     * If so, just return.
-     */
-    if (strncmp(wanted, execname, strlen(wanted)) == 0)
-        return;                 /* I am the droid you were looking for */
-
-    /*
-     * If this isn't the selected version, exec the selected version.
-     */
-#ifdef JAVA_ARGS  /* javac, jar and friends. */
-    progname = "java";
-#else             /* java, oldjava, javaw and friends */
-#ifdef PROGNAME
-    progname = PROGNAME;
-#else
-    progname = *argv;
-    if ((s = strrchr(progname, FILE_SEPARATOR)) != 0) {
-        progname = s + 1;
-    }
-#endif /* PROGNAME */
-#endif /* JAVA_ARGS */
-
-    /*
-     * This should never happen (because of the selection code in SelectJRE),
-     * but check for "impossibly" long path names just because buffer overruns
-     * can be so deadly.
-     */
-    if (strlen(wanted) + strlen(progname) + 6 > PATH_MAX) {
-        fprintf(stderr, "Path length exceeds maximum length (PATH_MAX)\n");
-        exit(1);
-    }
-
-    /*
-     * Construct the path and exec it.
-     */
-    (void)strcat(strcat(wanted, "/bin/"), progname);
-    argv[0] = progname;
-    if (_launcher_debug) {
-        int i;
-        printf("ReExec Command: %s (%s)\n", wanted, argv[0]);
-        printf("ReExec Args:");
-        for (i = 1; argv[i] != NULL; i++)
-            printf(" %s", argv[i]);
-        printf("\n");
-    }
-    (void)fflush(stdout);
-    (void)fflush(stderr);
-    execv(wanted, argv);
-    perror("execv()");
-    fprintf(stderr, "Exec of %s failed\n", wanted);
-    exit(1);
-}
-#endif /* ifndef GAMMA */
-
-/*
- * "Borrowed" from Solaris 10 where the unsetenv() function is being added
- * to libc thanks to SUSv3 (Standard Unix Specification, version 3). As
- * such, in the fullness of time this will appear in libc on all relevant
- * Solaris/Linux platforms and maybe even the Windows platform.  At that
- * time, this stub can be removed.
- *
- * This implementation removes the environment locking for multithreaded
- * applications.  (We don't have access to these mutexes within libc and
- * the launcher isn't multithreaded.)  Note that what remains is platform
- * independent, because it only relies on attributes that a POSIX environment
- * defines.
- *
- * Returns 0 on success, -1 on failure.
- *
- * Also removed was the setting of errno.  The only value of errno set
- * was EINVAL ("Invalid Argument").
- */
-
-/*
- * s1(environ) is name=value
- * s2(name) is name(not the form of name=value).
- * if names match, return value of 1, else return 0
- */
-static int
-match_noeq(const char *s1, const char *s2)
-{
-        while (*s1 == *s2++) {
-                if (*s1++ == '=')
-                        return (1);
-        }
-        if (*s1 == '=' && s2[-1] == '\0')
-                return (1);
-        return (0);
-}
-
-/*
- * added for SUSv3 standard
- *
- * Delete entry from environ.
- * Do not free() memory!  Other threads may be using it.
- * Keep it around forever.
- */
-static int
-borrowed_unsetenv(const char *name)
-{
-        long    idx;            /* index into environ */
-
-        if (name == NULL || *name == '\0' ||
-            strchr(name, '=') != NULL) {
-                return (-1);
-        }
-
-        for (idx = 0; environ[idx] != NULL; idx++) {
-                if (match_noeq(environ[idx], name))
-                        break;
-        }
-        if (environ[idx] == NULL) {
-                /* name not found but still a success */
-                return (0);
-        }
-        /* squeeze up one entry */
-        do {
-                environ[idx] = environ[idx+1];
-        } while (environ[++idx] != NULL);
-
-        return (0);
-}
-/* --- End of "borrowed" code --- */
-
-/*
- * Wrapper for unsetenv() function.
- */
-int
-UnsetEnv(char *name)
-{
-    return(borrowed_unsetenv(name));
-}
-
-/* --- Splash Screen shared library support --- */
-
-static const char* SPLASHSCREEN_SO = "libsplashscreen.so";
-
-static void* hSplashLib = NULL;
-
-void* SplashProcAddress(const char* name) {
-    if (!hSplashLib) {
-        hSplashLib = dlopen(SPLASHSCREEN_SO, RTLD_LAZY | RTLD_GLOBAL);
-    }
-    if (hSplashLib) {
-        void* sym = dlsym(hSplashLib, name);
-        return sym;
-    } else {
-        return NULL;
-    }
-}
-
-void SplashFreeLibrary() {
-    if (hSplashLib) {
-        dlclose(hSplashLib);
-        hSplashLib = NULL;
-    }
-}
-
-/*
- * Block current thread and continue execution in a new thread
- */
-int
-ContinueInNewThread(int (JNICALL *continuation)(void *), jlong stack_size, void * args) {
-    int rslt;
-#if defined(__linux__) || defined(_ALLBSD_SOURCE)
-    pthread_t tid;
-    pthread_attr_t attr;
-    pthread_attr_init(&attr);
-    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
-    if (stack_size > 0) {
-      pthread_attr_setstacksize(&attr, stack_size);
-    }
-
-    if (pthread_create(&tid, &attr, (void *(*)(void*))continuation, (void*)args) == 0) {
-      void * tmp;
-      pthread_join(tid, &tmp);
-      rslt = (int)(intptr_t)tmp;
-    } else {
-     /*
-      * Continue execution in current thread if for some reason (e.g. out of
-      * memory/LWP)  a new thread can't be created. This will likely fail
-      * later in continuation as JNI_CreateJavaVM needs to create quite a
-      * few new threads, anyway, just give it a try..
-      */
-      rslt = continuation(args);
-    }
-
-    pthread_attr_destroy(&attr);
-#else
-    thread_t tid;
-    long flags = 0;
-    if (thr_create(NULL, stack_size, (void *(*)(void *))continuation, args, flags, &tid) == 0) {
-      void * tmp;
-      thr_join(tid, NULL, &tmp);
-      rslt = (int)(intptr_t)tmp;
-    } else {
-      /* See above. Continue in current thread if thr_create() failed */
-      rslt = continuation(args);
-    }
-#endif
-    return rslt;
-}
-
-/* Coarse estimation of number of digits assuming the worst case is a 64-bit pid. */
-#define MAX_PID_STR_SZ   20
-
-void SetJavaLauncherPlatformProps() {
-   /* Linux only */
-#ifdef __linux__
-    const char *substr = "-Dsun.java.launcher.pid=";
-    char *pid_prop_str = (char *)JLI_MemAlloc(strlen(substr) + MAX_PID_STR_SZ + 1);
-    sprintf(pid_prop_str, "%s%d", substr, getpid());
-    AddOption(pid_prop_str, NULL);
-#endif
-}
diff --git a/hotspot/src/os/posix/launcher/java_md.h b/hotspot/src/os/posix/launcher/java_md.h
deleted file mode 100644
index 63c449a..0000000
--- a/hotspot/src/os/posix/launcher/java_md.h
+++ /dev/null
@@ -1,82 +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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef JAVA_MD_H
-#define JAVA_MD_H
-
-#include <limits.h>
-#include <unistd.h>
-#include <sys/param.h>
-#ifndef GAMMA
-#include "manifest_info.h"
-#endif
-#include "jli_util.h"
-
-#define PATH_SEPARATOR          ':'
-#define FILESEP                 "/"
-#define FILE_SEPARATOR          '/'
-#define IS_FILE_SEPARATOR(c) ((c) == '/')
-#ifndef MAXNAMELEN
-#define MAXNAMELEN              PATH_MAX
-#endif
-
-#ifdef JAVA_ARGS
-/*
- * ApplicationHome is prepended to each of these entries; the resulting
- * strings are concatenated (separated by PATH_SEPARATOR) and used as the
- * value of -cp option to the launcher.
- */
-#ifndef APP_CLASSPATH
-#define APP_CLASSPATH        { "/lib/tools.jar", "/classes" }
-#endif
-#endif
-
-#ifdef HAVE_GETHRTIME
-/*
- * Support for doing cheap, accurate interval timing.
- */
-#include <sys/time.h>
-#define CounterGet()              (gethrtime()/1000)
-#define Counter2Micros(counts)    (counts)
-#else
-#define CounterGet()              (0)
-#define Counter2Micros(counts)    (1)
-#endif /* HAVE_GETHRTIME */
-
-#ifdef _LP64
-#define JLONG_FORMAT "%ld"
-#else
-#define JLONG_FORMAT "%lld"
-#endif
-
-/*
- * Function prototypes.
- */
-#ifndef GAMMA
-char *LocateJRE(manifest_info *info);
-void ExecJRE(char *jre, char **argv);
-#endif
-int UnsetEnv(char *name);
-
-#endif
diff --git a/hotspot/src/os/windows/launcher/java_md.c b/hotspot/src/os/windows/launcher/java_md.c
deleted file mode 100644
index 3e28755..0000000
--- a/hotspot/src/os/windows/launcher/java_md.c
+++ /dev/null
@@ -1,1507 +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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include <ctype.h>
-#include <windows.h>
-#include <io.h>
-#include <process.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <jni.h>
-#include "java.h"
-#ifndef GAMMA
-#include "version_comp.h"
-#endif
-
-#define JVM_DLL "jvm.dll"
-#define JAVA_DLL "java.dll"
-#define CRT_DLL "msvcr71.dll"
-
-/*
- * Prototypes.
- */
-static jboolean GetPublicJREHome(char *path, jint pathsize);
-static jboolean GetJVMPath(const char *jrepath, const char *jvmtype,
-                           char *jvmpath, jint jvmpathsize);
-static jboolean GetJREPath(char *path, jint pathsize);
-static void EnsureJreInstallation(const char *jrepath);
-
-/* We supports warmup for UI stack that is performed in parallel
- * to VM initialization.
- * This helps to improve startup of UI application as warmup phase
- * might be long due to initialization of OS or hardware resources.
- * It is not CPU bound and therefore it does not interfere with VM init.
- * Obviously such warmup only has sense for UI apps and therefore it needs
- * to be explicitly requested by passing -Dsun.awt.warmup=true property
- * (this is always the case for plugin/javaws).
- *
- * Implementation launches new thread after VM starts and use it to perform
- * warmup code (platform dependent).
- * This thread is later reused as AWT toolkit thread as graphics toolkit
- * often assume that they are used from the same thread they were launched on.
- *
- * At the moment we only support warmup for D3D. It only possible on windows
- * and only if other flags do not prohibit this (e.g. OpenGL support requested).
- */
-#undef ENABLE_AWT_PRELOAD
-#ifndef JAVA_ARGS /* turn off AWT preloading for javac, jar, etc */
-  #ifdef _X86_ /* for now disable AWT preloading for 64bit */
-    #define ENABLE_AWT_PRELOAD
-  #endif
-#endif
-
-#ifdef ENABLE_AWT_PRELOAD
-/* "AWT was preloaded" flag;
- * Turned on by AWTPreload().
- */
-int awtPreloaded = 0;
-
-/* Calls a function with the name specified.
- * The function must be int(*fn)(void).
- */
-int AWTPreload(const char *funcName);
-/* Stops AWT preloading. */
-void AWTPreloadStop();
-
-/* D3D preloading */
-/* -1: not initialized; 0: OFF, 1: ON */
-int awtPreloadD3D = -1;
-/* Command line parameter to swith D3D preloading on. */
-#define PARAM_PRELOAD_D3D "-Dsun.awt.warmup"
-/* D3D/OpenGL management parameters (may disable D3D preloading) */
-#define PARAM_NODDRAW "-Dsun.java2d.noddraw"
-#define PARAM_D3D "-Dsun.java2d.d3d"
-#define PARAM_OPENGL "-Dsun.java2d.opengl"
-/* funtion in awt.dll (src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp) */
-#define D3D_PRELOAD_FUNC "preloadD3D"
-
-
-/* Extracts value of a parameter with the specified name
- * from command line argument (returns pointer in the argument).
- * Returns NULL if the argument does not contains the parameter.
- * e.g.:
- * GetParamValue("theParam", "theParam=value") returns pointer to "value".
- */
-const char * GetParamValue(const char *paramName, const char *arg) {
-    int nameLen = strlen(paramName);
-    if (strncmp(paramName, arg, nameLen) == 0) {
-        // arg[nameLen] is valid (may contain final NULL)
-        if (arg[nameLen] == '=') {
-            return arg + nameLen + 1;
-        }
-    }
-    return NULL;
-}
-
-/* Checks if commandline argument contains property specified
- * and analyze it as boolean property (true/false).
- * Returns -1 if the argument does not contain the parameter;
- * Returns 1 if the argument contains the parameter and its value is "true";
- * Returns 0 if the argument contains the parameter and its value is "false".
- */
-int GetBoolParamValue(const char *paramName, const char *arg) {
-    const char * paramValue = GetParamValue(paramName, arg);
-    if (paramValue != NULL) {
-        if (stricmp(paramValue, "true") == 0) {
-            return 1;
-        }
-        if (stricmp(paramValue, "false") == 0) {
-            return 0;
-        }
-    }
-    return -1;
-}
-#endif /* ENABLE_AWT_PRELOAD */
-
-
-const char *
-GetArch()
-{
-
-#ifdef _M_AMD64
-    return "amd64";
-#elif defined(_M_IA64)
-    return "ia64";
-#else
-    return "i386";
-#endif
-}
-
-/*
- *
- */
-void
-CreateExecutionEnvironment(int *_argc,
-                           char ***_argv,
-                           char jrepath[],
-                           jint so_jrepath,
-                           char jvmpath[],
-                           jint so_jvmpath,
-                           char **original_argv) {
-#ifndef GAMMA
-   char * jvmtype;
-
-    /* Find out where the JRE is that we will be using. */
-    if (!GetJREPath(jrepath, so_jrepath)) {
-        ReportErrorMessage("Error: could not find Java SE Runtime Environment.",
-                           JNI_TRUE);
-        exit(2);
-    }
-
-    /* Do this before we read jvm.cfg */
-    EnsureJreInstallation(jrepath);
-
-    /* Find the specified JVM type */
-    if (ReadKnownVMs(jrepath, (char*)GetArch(), JNI_FALSE) < 1) {
-        ReportErrorMessage("Error: no known VMs. (check for corrupt jvm.cfg file)",
-                           JNI_TRUE);
-        exit(1);
-    }
-    jvmtype = CheckJvmType(_argc, _argv, JNI_FALSE);
-
-    jvmpath[0] = '\0';
-    if (!GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath)) {
-        char * message=NULL;
-        const char * format = "Error: no `%s' JVM at `%s'.";
-        message = (char *)JLI_MemAlloc((strlen(format)+strlen(jvmtype)+
-                                    strlen(jvmpath)) * sizeof(char));
-        sprintf(message,format, jvmtype, jvmpath);
-        ReportErrorMessage(message, JNI_TRUE);
-        exit(4);
-    }
-    /* If we got here, jvmpath has been correctly initialized. */
-
-#else  /* ifndef GAMMA */
-
-    /*
-     * gamma launcher is simpler in that it doesn't handle VM flavors, data
-     * model, etc. Assuming everything is set-up correctly
-     * all we need to do here is to return correct path names. See also
-     * GetJVMPath() and GetApplicationHome().
-     */
-
-  {
-    if (!GetJREPath(jrepath, so_jrepath) ) {
-       ReportErrorMessage("Error: could not find Java SE Runtime Environment.",
-                          JNI_TRUE);
-       exit(2);
-    }
-
-    if (!GetJVMPath(jrepath, NULL, jvmpath, so_jvmpath)) {
-       char * message=NULL;
-       const char * format = "Error: no JVM at `%s'.";
-       message = (char *)JLI_MemAlloc((strlen(format)+
-                                       strlen(jvmpath)) * sizeof(char));
-       sprintf(message, format, jvmpath);
-       ReportErrorMessage(message, JNI_TRUE);
-       exit(4);
-    }
-  }
-
-#endif  /* ifndef GAMMA */
-
-}
-
-
-static jboolean
-LoadMSVCRT()
-{
-    // Only do this once
-    static int loaded = 0;
-    char crtpath[MAXPATHLEN];
-
-    if (!loaded) {
-        /*
-         * The Microsoft C Runtime Library needs to be loaded first.  A copy is
-         * assumed to be present in the "JRE path" directory.  If it is not found
-         * there (or "JRE path" fails to resolve), skip the explicit load and let
-         * nature take its course, which is likely to be a failure to execute.
-         */
-        if (GetJREPath(crtpath, MAXPATHLEN)) {
-            (void)strcat(crtpath, "\\bin\\" CRT_DLL);   /* Add crt dll */
-            if (_launcher_debug) {
-                printf("CRT path is %s\n", crtpath);
-            }
-            if (_access(crtpath, 0) == 0) {
-                if (LoadLibrary(crtpath) == 0) {
-                    ReportErrorMessage2("Error loading: %s", crtpath, JNI_TRUE);
-                    return JNI_FALSE;
-                }
-            }
-        }
-        loaded = 1;
-    }
-    return JNI_TRUE;
-}
-
-/*
- * The preJVMStart is a function in the jkernel.dll, which
- * performs the final step of synthesizing back the decomposed
- * modules  (partial install) to the full JRE. Any tool which
- * uses the  JRE must peform this step to ensure the complete synthesis.
- * The EnsureJreInstallation function calls preJVMStart based on
- * the conditions outlined below, noting that the operation
- * will fail silently if any of conditions are not met.
- * NOTE: this call must be made before jvm.dll is loaded, or jvm.cfg
- * is read, since jvm.cfg will be modified by the preJVMStart.
- * 1. Are we on a supported platform.
- * 2. Find the location of the JRE or the Kernel JRE.
- * 3. check existence of JREHOME/lib/bundles
- * 4. check jkernel.dll and invoke the entry-point
- */
-typedef VOID (WINAPI *PREJVMSTART)();
-
-static void
-EnsureJreInstallation(const char* jrepath)
-{
-    HINSTANCE handle;
-    char tmpbuf[MAXPATHLEN];
-    PREJVMSTART PreJVMStart;
-    struct stat s;
-
-    /* 32 bit windows only please */
-    if (strcmp(GetArch(), "i386") != 0 ) {
-        if (_launcher_debug) {
-            printf("EnsureJreInstallation:unsupported platform\n");
-        }
-        return;
-    }
-    /* Does our bundle directory exist ? */
-    strcpy(tmpbuf, jrepath);
-    strcat(tmpbuf, "\\lib\\bundles");
-    if (stat(tmpbuf, &s) != 0) {
-        if (_launcher_debug) {
-            printf("EnsureJreInstallation:<%s>:not found\n", tmpbuf);
-        }
-        return;
-    }
-    /* Does our jkernel dll exist ? */
-    strcpy(tmpbuf, jrepath);
-    strcat(tmpbuf, "\\bin\\jkernel.dll");
-    if (stat(tmpbuf, &s) != 0) {
-        if (_launcher_debug) {
-            printf("EnsureJreInstallation:<%s>:not found\n", tmpbuf);
-        }
-        return;
-    }
-    /* The Microsoft C Runtime Library needs to be loaded first. */
-    if (!LoadMSVCRT()) {
-        if (_launcher_debug) {
-            printf("EnsureJreInstallation:could not load C runtime DLL\n");
-        }
-        return;
-    }
-    /* Load the jkernel.dll */
-    if ((handle = LoadLibrary(tmpbuf)) == 0) {
-        if (_launcher_debug) {
-            printf("EnsureJreInstallation:%s:load failed\n", tmpbuf);
-        }
-        return;
-    }
-    /* Get the function address */
-    PreJVMStart = (PREJVMSTART)GetProcAddress(handle, "preJVMStart");
-    if (PreJVMStart == NULL) {
-        if (_launcher_debug) {
-            printf("EnsureJreInstallation:preJVMStart:function lookup failed\n");
-        }
-        FreeLibrary(handle);
-        return;
-    }
-    PreJVMStart();
-    if (_launcher_debug) {
-        printf("EnsureJreInstallation:preJVMStart:called\n");
-    }
-    FreeLibrary(handle);
-    return;
-}
-
-/*
- * Find path to JRE based on .exe's location or registry settings.
- */
-jboolean
-GetJREPath(char *path, jint pathsize)
-{
-    char javadll[MAXPATHLEN];
-    struct stat s;
-
-    if (GetApplicationHome(path, pathsize)) {
-        /* Is JRE co-located with the application? */
-        sprintf(javadll, "%s\\bin\\" JAVA_DLL, path);
-        if (stat(javadll, &s) == 0) {
-            goto found;
-        }
-
-        /* Does this app ship a private JRE in <apphome>\jre directory? */
-        sprintf(javadll, "%s\\jre\\bin\\" JAVA_DLL, path);
-        if (stat(javadll, &s) == 0) {
-            strcat(path, "\\jre");
-            goto found;
-        }
-    }
-
-#ifndef GAMMA
-    /* Look for a public JRE on this machine. */
-    if (GetPublicJREHome(path, pathsize)) {
-        goto found;
-    }
-#endif
-
-    fprintf(stderr, "Error: could not find " JAVA_DLL "\n");
-    return JNI_FALSE;
-
- found:
-    if (_launcher_debug)
-      printf("JRE path is %s\n", path);
-    return JNI_TRUE;
-}
-
-/*
- * Given a JRE location and a JVM type, construct what the name the
- * JVM shared library will be.  Return true, if such a library
- * exists, false otherwise.
- */
-static jboolean
-GetJVMPath(const char *jrepath, const char *jvmtype,
-           char *jvmpath, jint jvmpathsize)
-{
-    struct stat s;
-
-#ifndef GAMMA
-    if (strchr(jvmtype, '/') || strchr(jvmtype, '\\')) {
-        sprintf(jvmpath, "%s\\" JVM_DLL, jvmtype);
-    } else {
-        sprintf(jvmpath, "%s\\bin\\%s\\" JVM_DLL, jrepath, jvmtype);
-    }
-#else
-    /*
-     * For gamma launcher, JVM is either built-in or in the same directory.
-     * Either way we return "<exe_path>/jvm.dll" where <exe_path> is the
-     * directory where gamma launcher is located.
-     */
-
-    char *p;
-    GetModuleFileName(0, jvmpath, jvmpathsize);
-
-    p = strrchr(jvmpath, '\\');
-    if (p) {
-       /* replace executable name with libjvm.so */
-       snprintf(p + 1, jvmpathsize - (p + 1 - jvmpath), "%s", JVM_DLL);
-    } else {
-       /* this case shouldn't happen */
-       snprintf(jvmpath, jvmpathsize, "%s", JVM_DLL);
-    }
-#endif /* ifndef GAMMA */
-
-    if (stat(jvmpath, &s) == 0) {
-        return JNI_TRUE;
-    } else {
-        return JNI_FALSE;
-    }
-}
-
-/*
- * Load a jvm from "jvmpath" and initialize the invocation functions.
- */
-jboolean
-LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn)
-{
-#ifdef GAMMA
-    /* JVM is directly linked with gamma launcher; no Loadlibrary() */
-    ifn->CreateJavaVM = JNI_CreateJavaVM;
-    ifn->GetDefaultJavaVMInitArgs = JNI_GetDefaultJavaVMInitArgs;
-    return JNI_TRUE;
-#else
-    HINSTANCE handle;
-
-    if (_launcher_debug) {
-        printf("JVM path is %s\n", jvmpath);
-    }
-
-    /* The Microsoft C Runtime Library needs to be loaded first. */
-    LoadMSVCRT();
-
-    /* Load the Java VM DLL */
-    if ((handle = LoadLibrary(jvmpath)) == 0) {
-        ReportErrorMessage2("Error loading: %s", (char *)jvmpath, JNI_TRUE);
-        return JNI_FALSE;
-    }
-
-    /* Now get the function addresses */
-    ifn->CreateJavaVM =
-        (void *)GetProcAddress(handle, "JNI_CreateJavaVM");
-    ifn->GetDefaultJavaVMInitArgs =
-        (void *)GetProcAddress(handle, "JNI_GetDefaultJavaVMInitArgs");
-    if (ifn->CreateJavaVM == 0 || ifn->GetDefaultJavaVMInitArgs == 0) {
-        ReportErrorMessage2("Error: can't find JNI interfaces in: %s",
-                            (char *)jvmpath, JNI_TRUE);
-        return JNI_FALSE;
-    }
-
-    return JNI_TRUE;
-#endif /* ifndef GAMMA */
-}
-
-/*
- * If app is "c:\foo\bin\javac", then put "c:\foo" into buf.
- */
-jboolean
-GetApplicationHome(char *buf, jint bufsize)
-{
-#ifndef GAMMA
-    char *cp;
-    GetModuleFileName(0, buf, bufsize);
-    *strrchr(buf, '\\') = '\0'; /* remove .exe file name */
-    if ((cp = strrchr(buf, '\\')) == 0) {
-        /* This happens if the application is in a drive root, and
-         * there is no bin directory. */
-        buf[0] = '\0';
-        return JNI_FALSE;
-    }
-    *cp = '\0';  /* remove the bin\ part */
-    return JNI_TRUE;
-
-#else /* ifndef GAMMA */
-
-    char env[MAXPATHLEN + 1];
-
-    /* gamma launcher uses ALT_JAVA_HOME environment variable or jdkpath.txt file to find JDK/JRE */
-
-    if (getenv("ALT_JAVA_HOME") != NULL) {
-       snprintf(buf, bufsize, "%s", getenv("ALT_JAVA_HOME"));
-    }
-    else {
-       char path[MAXPATHLEN + 1];
-       char* p;
-       int len;
-       FILE* fp;
-
-       // find the path to the currect executable
-       len = GetModuleFileName(NULL, path, MAXPATHLEN + 1);
-       if (len == 0 || len > MAXPATHLEN) {
-          printf("Could not get directory of current executable.");
-          return JNI_FALSE;
-       }
-       // remove last path component ("hotspot.exe")
-       p = strrchr(path, '\\');
-       if (p == NULL) {
-          printf("Could not parse directory of current executable.\n");
-          return JNI_FALSE;
-       }
-       *p = '\0';
-
-       // open jdkpath.txt and read JAVA_HOME from it
-       if (strlen(path) + strlen("\\jdkpath.txt") + 1 >= MAXPATHLEN) {
-          printf("Path too long: %s\n", path);
-          return JNI_FALSE;
-       }
-       strcat(path, "\\jdkpath.txt");
-       fp = fopen(path, "r");
-       if (fp == NULL) {
-          printf("Could not open file %s to get path to JDK.\n", path);
-          return JNI_FALSE;
-       }
-
-       if (fgets(buf, bufsize, fp) == NULL) {
-          printf("Could not read from file %s to get path to JDK.\n", path);
-          fclose(fp);
-          return JNI_FALSE;
-       }
-       // trim the buffer
-       p = buf + strlen(buf) - 1;
-       while(isspace(*p)) {
-          *p = '\0';
-          p--;
-       }
-       fclose(fp);
-    }
-
-    _snprintf(env, MAXPATHLEN, "JAVA_HOME=%s", buf);
-    _putenv(env);
-
-    return JNI_TRUE;
-#endif /* ifndef GAMMA */
-}
-
-#ifdef JAVAW
-__declspec(dllimport) char **__initenv;
-
-int WINAPI
-WinMain(HINSTANCE inst, HINSTANCE previnst, LPSTR cmdline, int cmdshow)
-{
-    int   ret;
-
-    __initenv = _environ;
-    ret = main(__argc, __argv);
-
-    return ret;
-}
-#endif
-
-#ifndef GAMMA
-
-/*
- * Helpers to look in the registry for a public JRE.
- */
-                    /* Same for 1.5.0, 1.5.1, 1.5.2 etc. */
-#define DOTRELEASE  JDK_MAJOR_VERSION "." JDK_MINOR_VERSION
-#define JRE_KEY     "Software\\JavaSoft\\Java Runtime Environment"
-
-static jboolean
-GetStringFromRegistry(HKEY key, const char *name, char *buf, jint bufsize)
-{
-    DWORD type, size;
-
-    if (RegQueryValueEx(key, name, 0, &type, 0, &size) == 0
-        && type == REG_SZ
-        && (size < (unsigned int)bufsize)) {
-        if (RegQueryValueEx(key, name, 0, 0, buf, &size) == 0) {
-            return JNI_TRUE;
-        }
-    }
-    return JNI_FALSE;
-}
-
-static jboolean
-GetPublicJREHome(char *buf, jint bufsize)
-{
-    HKEY key, subkey;
-    char version[MAXPATHLEN];
-
-    /*
-     * Note: There is a very similar implementation of the following
-     * registry reading code in the Windows java control panel (javacp.cpl).
-     * If there are bugs here, a similar bug probably exists there.  Hence,
-     * changes here require inspection there.
-     */
-
-    /* Find the current version of the JRE */
-    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, JRE_KEY, 0, KEY_READ, &key) != 0) {
-        fprintf(stderr, "Error opening registry key '" JRE_KEY "'\n");
-        return JNI_FALSE;
-    }
-
-    if (!GetStringFromRegistry(key, "CurrentVersion",
-                               version, sizeof(version))) {
-        fprintf(stderr, "Failed reading value of registry key:\n\t"
-                JRE_KEY "\\CurrentVersion\n");
-        RegCloseKey(key);
-        return JNI_FALSE;
-    }
-
-    if (strcmp(version, DOTRELEASE) != 0) {
-        fprintf(stderr, "Registry key '" JRE_KEY "\\CurrentVersion'\nhas "
-                "value '%s', but '" DOTRELEASE "' is required.\n", version);
-        RegCloseKey(key);
-        return JNI_FALSE;
-    }
-
-    /* Find directory where the current version is installed. */
-    if (RegOpenKeyEx(key, version, 0, KEY_READ, &subkey) != 0) {
-        fprintf(stderr, "Error opening registry key '"
-                JRE_KEY "\\%s'\n", version);
-        RegCloseKey(key);
-        return JNI_FALSE;
-    }
-
-    if (!GetStringFromRegistry(subkey, "JavaHome", buf, bufsize)) {
-        fprintf(stderr, "Failed reading value of registry key:\n\t"
-                JRE_KEY "\\%s\\JavaHome\n", version);
-        RegCloseKey(key);
-        RegCloseKey(subkey);
-        return JNI_FALSE;
-    }
-
-    if (_launcher_debug) {
-        char micro[MAXPATHLEN];
-        if (!GetStringFromRegistry(subkey, "MicroVersion", micro,
-                                   sizeof(micro))) {
-            printf("Warning: Can't read MicroVersion\n");
-            micro[0] = '\0';
-        }
-        printf("Version major.minor.micro = %s.%s\n", version, micro);
-    }
-
-    RegCloseKey(key);
-    RegCloseKey(subkey);
-    return JNI_TRUE;
-}
-
-#endif /* ifndef GAMMA */
-
-/*
- * Support for doing cheap, accurate interval timing.
- */
-static jboolean counterAvailable = JNI_FALSE;
-static jboolean counterInitialized = JNI_FALSE;
-static LARGE_INTEGER counterFrequency;
-
-jlong CounterGet()
-{
-    LARGE_INTEGER count;
-
-    if (!counterInitialized) {
-        counterAvailable = QueryPerformanceFrequency(&counterFrequency);
-        counterInitialized = JNI_TRUE;
-    }
-    if (!counterAvailable) {
-        return 0;
-    }
-    QueryPerformanceCounter(&count);
-    return (jlong)(count.QuadPart);
-}
-
-jlong Counter2Micros(jlong counts)
-{
-    if (!counterAvailable || !counterInitialized) {
-        return 0;
-    }
-    return (counts * 1000 * 1000)/counterFrequency.QuadPart;
-}
-
-void ReportErrorMessage(char * message, jboolean always) {
-#ifdef JAVAW
-  if (message != NULL) {
-    MessageBox(NULL, message, "Java Virtual Machine Launcher",
-               (MB_OK|MB_ICONSTOP|MB_APPLMODAL));
-  }
-#else
-  if (always) {
-    fprintf(stderr, "%s\n", message);
-  }
-#endif
-}
-
-void ReportErrorMessage2(char * format, char * string, jboolean always) {
-  /*
-   * The format argument must be a printf format string with one %s
-   * argument, which is passed the string argument.
-   */
-#ifdef JAVAW
-  size_t size;
-  char * message;
-  size = strlen(format) + strlen(string);
-  message = (char*)JLI_MemAlloc(size*sizeof(char));
-  sprintf(message, (const char *)format, string);
-
-  if (message != NULL) {
-    MessageBox(NULL, message, "Java Virtual Machine Launcher",
-               (MB_OK|MB_ICONSTOP|MB_APPLMODAL));
-    JLI_MemFree(message);
-  }
-#else
-  if (always) {
-    fprintf(stderr, (const char *)format, string);
-    fprintf(stderr, "\n");
-  }
-#endif
-}
-
-/*
- * As ReportErrorMessage2 (above) except the system message (if any)
- * associated with this error is written to a second %s format specifier
- * in the format argument.
- */
-void ReportSysErrorMessage2(char * format, char * string, jboolean always) {
-  int   save_errno = errno;
-  DWORD errval;
-  int   freeit = 0;
-  char  *errtext = NULL;
-
-  if ((errval = GetLastError()) != 0) {         /* Platform SDK / DOS Error */
-    int n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|
-      FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_ALLOCATE_BUFFER,
-      NULL, errval, 0, (LPTSTR)&errtext, 0, NULL);
-    if (errtext == NULL || n == 0) {            /* Paranoia check */
-      errtext = "";
-      n = 0;
-    } else {
-      freeit = 1;
-      if (n > 2) {                              /* Drop final CR, LF */
-        if (errtext[n - 1] == '\n') n--;
-        if (errtext[n - 1] == '\r') n--;
-        errtext[n] = '\0';
-      }
-    }
-  } else        /* C runtime error that has no corresponding DOS error code */
-    errtext = strerror(save_errno);
-
-#ifdef JAVAW
-  {
-    size_t size;
-    char * message;
-    size = strlen(format) + strlen(string) + strlen(errtext);
-    message = (char*)JLI_MemAlloc(size*sizeof(char));
-    sprintf(message, (const char *)format, string, errtext);
-
-    if (message != NULL) {
-      MessageBox(NULL, message, "Java Virtual Machine Launcher",
-               (MB_OK|MB_ICONSTOP|MB_APPLMODAL));
-      JLI_MemFree(message);
-    }
-  }
-#else
-  if (always) {
-    fprintf(stderr, (const char *)format, string, errtext);
-    fprintf(stderr, "\n");
-  }
-#endif
-  if (freeit)
-    (void)LocalFree((HLOCAL)errtext);
-}
-
-void  ReportExceptionDescription(JNIEnv * env) {
-#ifdef JAVAW
-  /*
-   * This code should be replaced by code which opens a window with
-   * the exception detail message.
-   */
-  (*env)->ExceptionDescribe(env);
-#else
-  (*env)->ExceptionDescribe(env);
-#endif
-}
-
-
-/*
- * Return JNI_TRUE for an option string that has no effect but should
- * _not_ be passed on to the vm; return JNI_FALSE otherwise. On
- * windows, there are no options that should be screened in this
- * manner.
- */
-jboolean RemovableMachineDependentOption(char * option) {
-#ifdef ENABLE_AWT_PRELOAD
-    if (awtPreloadD3D < 0) {
-        /* Tests the command line parameter only if not set yet. */
-        if (GetBoolParamValue(PARAM_PRELOAD_D3D, option) == 1) {
-            awtPreloadD3D = 1;
-        }
-    }
-    if (awtPreloadD3D != 0) {
-        /* Don't test the command line parameters if already disabled. */
-        if (GetBoolParamValue(PARAM_NODDRAW, option) == 1
-            || GetBoolParamValue(PARAM_D3D, option) == 0
-            || GetBoolParamValue(PARAM_OPENGL, option) == 1)
-        {
-            awtPreloadD3D = 0;
-        }
-    }
-#endif /* ENABLE_AWT_PRELOAD */
-
-    return JNI_FALSE;
-}
-
-void PrintMachineDependentOptions() {
-  return;
-}
-
-#ifndef GAMMA
-
-jboolean
-ServerClassMachine() {
-  jboolean result = JNI_FALSE;
-#if   defined(NEVER_ACT_AS_SERVER_CLASS_MACHINE)
-  result = JNI_FALSE;
-#elif defined(ALWAYS_ACT_AS_SERVER_CLASS_MACHINE)
-  result = JNI_TRUE;
-#endif
-  return result;
-}
-
-/*
- * Determine if there is an acceptable JRE in the registry directory top_key.
- * Upon locating the "best" one, return a fully qualified path to it.
- * "Best" is defined as the most advanced JRE meeting the constraints
- * contained in the manifest_info. If no JRE in this directory meets the
- * constraints, return NULL.
- *
- * It doesn't matter if we get an error reading the registry, or we just
- * don't find anything interesting in the directory.  We just return NULL
- * in either case.
- */
-static char *
-ProcessDir(manifest_info* info, HKEY top_key) {
-    DWORD   index = 0;
-    HKEY    ver_key;
-    char    name[MAXNAMELEN];
-    int     len;
-    char    *best = NULL;
-
-    /*
-     * Enumerate "<top_key>/SOFTWARE/JavaSoft/Java Runtime Environment"
-     * searching for the best available version.
-     */
-    while (RegEnumKey(top_key, index, name, MAXNAMELEN) == ERROR_SUCCESS) {
-        index++;
-        if (JLI_AcceptableRelease(name, info->jre_version))
-            if ((best == NULL) || (JLI_ExactVersionId(name, best) > 0)) {
-                if (best != NULL)
-                    JLI_MemFree(best);
-                best = JLI_StringDup(name);
-            }
-    }
-
-    /*
-     * Extract "JavaHome" from the "best" registry directory and return
-     * that path.  If no appropriate version was located, or there is an
-     * error in extracting the "JavaHome" string, return null.
-     */
-    if (best == NULL)
-        return (NULL);
-    else {
-        if (RegOpenKeyEx(top_key, best, 0, KEY_READ, &ver_key)
-          != ERROR_SUCCESS) {
-            JLI_MemFree(best);
-            if (ver_key != NULL)
-                RegCloseKey(ver_key);
-            return (NULL);
-        }
-        JLI_MemFree(best);
-        len = MAXNAMELEN;
-        if (RegQueryValueEx(ver_key, "JavaHome", NULL, NULL, (LPBYTE)name, &len)
-          != ERROR_SUCCESS) {
-            if (ver_key != NULL)
-                RegCloseKey(ver_key);
-            return (NULL);
-        }
-        if (ver_key != NULL)
-            RegCloseKey(ver_key);
-        return (JLI_StringDup(name));
-    }
-}
-
-/*
- * This is the global entry point. It examines the host for the optimal
- * JRE to be used by scanning a set of registry entries.  This set of entries
- * is hardwired on Windows as "Software\JavaSoft\Java Runtime Environment"
- * under the set of roots "{ HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }".
- *
- * This routine simply opens each of these registry directories before passing
- * control onto ProcessDir().
- */
-char *
-LocateJRE(manifest_info* info) {
-    HKEY    key = NULL;
-    char    *path;
-    int     key_index;
-    HKEY    root_keys[2] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE };
-
-    for (key_index = 0; key_index <= 1; key_index++) {
-        if (RegOpenKeyEx(root_keys[key_index], JRE_KEY, 0, KEY_READ, &key)
-          == ERROR_SUCCESS)
-            if ((path = ProcessDir(info, key)) != NULL) {
-                if (key != NULL)
-                    RegCloseKey(key);
-                return (path);
-            }
-        if (key != NULL)
-            RegCloseKey(key);
-    }
-    return NULL;
-}
-
-
-/*
- * Local helper routine to isolate a single token (option or argument)
- * from the command line.
- *
- * This routine accepts a pointer to a character pointer.  The first
- * token (as defined by MSDN command-line argument syntax) is isolated
- * from that string.
- *
- * Upon return, the input character pointer pointed to by the parameter s
- * is updated to point to the remainding, unscanned, portion of the string,
- * or to a null character if the entire string has been consummed.
- *
- * This function returns a pointer to a null-terminated string which
- * contains the isolated first token, or to the null character if no
- * token could be isolated.
- *
- * Note the side effect of modifying the input string s by the insertion
- * of a null character, making it two strings.
- *
- * See "Parsing C Command-Line Arguments" in the MSDN Library for the
- * parsing rule details.  The rule summary from that specification is:
- *
- *  * Arguments are delimited by white space, which is either a space or a tab.
- *
- *  * A string surrounded by double quotation marks is interpreted as a single
- *    argument, regardless of white space contained within. A quoted string can
- *    be embedded in an argument. Note that the caret (^) is not recognized as
- *    an escape character or delimiter.
- *
- *  * A double quotation mark preceded by a backslash, \", is interpreted as a
- *    literal double quotation mark (").
- *
- *  * Backslashes are interpreted literally, unless they immediately precede a
- *    double quotation mark.
- *
- *  * If an even number of backslashes is followed by a double quotation mark,
- *    then one backslash (\) is placed in the argv array for every pair of
- *    backslashes (\\), and the double quotation mark (") is interpreted as a
- *    string delimiter.
- *
- *  * If an odd number of backslashes is followed by a double quotation mark,
- *    then one backslash (\) is placed in the argv array for every pair of
- *    backslashes (\\) and the double quotation mark is interpreted as an
- *    escape sequence by the remaining backslash, causing a literal double
- *    quotation mark (") to be placed in argv.
- */
-static char*
-nextarg(char** s) {
-    char    *p = *s;
-    char    *head;
-    int     slashes = 0;
-    int     inquote = 0;
-
-    /*
-     * Strip leading whitespace, which MSDN defines as only space or tab.
-     * (Hence, no locale specific "isspace" here.)
-     */
-    while (*p != (char)0 && (*p == ' ' || *p == '\t'))
-        p++;
-    head = p;                   /* Save the start of the token to return */
-
-    /*
-     * Isolate a token from the command line.
-     */
-    while (*p != (char)0 && (inquote || !(*p == ' ' || *p == '\t'))) {
-        if (*p == '\\' && *(p+1) == '"' && slashes % 2 == 0)
-            p++;
-        else if (*p == '"')
-            inquote = !inquote;
-        slashes = (*p++ == '\\') ? slashes + 1 : 0;
-    }
-
-    /*
-     * If the token isolated isn't already terminated in a "char zero",
-     * then replace the whitespace character with one and move to the
-     * next character.
-     */
-    if (*p != (char)0)
-        *p++ = (char)0;
-
-    /*
-     * Update the parameter to point to the head of the remaining string
-     * reflecting the command line and return a pointer to the leading
-     * token which was isolated from the command line.
-     */
-    *s = p;
-    return (head);
-}
-
-/*
- * Local helper routine to return a string equivalent to the input string
- * s, but with quotes removed so the result is a string as would be found
- * in argv[].  The returned string should be freed by a call to JLI_MemFree().
- *
- * The rules for quoting (and escaped quotes) are:
- *
- *  1 A double quotation mark preceded by a backslash, \", is interpreted as a
- *    literal double quotation mark (").
- *
- *  2 Backslashes are interpreted literally, unless they immediately precede a
- *    double quotation mark.
- *
- *  3 If an even number of backslashes is followed by a double quotation mark,
- *    then one backslash (\) is placed in the argv array for every pair of
- *    backslashes (\\), and the double quotation mark (") is interpreted as a
- *    string delimiter.
- *
- *  4 If an odd number of backslashes is followed by a double quotation mark,
- *    then one backslash (\) is placed in the argv array for every pair of
- *    backslashes (\\) and the double quotation mark is interpreted as an
- *    escape sequence by the remaining backslash, causing a literal double
- *    quotation mark (") to be placed in argv.
- */
-static char*
-unquote(const char *s) {
-    const char *p = s;          /* Pointer to the tail of the original string */
-    char *un = (char*)JLI_MemAlloc(strlen(s) + 1);  /* Ptr to unquoted string */
-    char *pun = un;             /* Pointer to the tail of the unquoted string */
-
-    while (*p != '\0') {
-        if (*p == '"') {
-            p++;
-        } else if (*p == '\\') {
-            const char *q = p + strspn(p,"\\");
-            if (*q == '"')
-                do {
-                    *pun++ = '\\';
-                    p += 2;
-                 } while (*p == '\\' && p < q);
-            else
-                while (p < q)
-                    *pun++ = *p++;
-        } else {
-            *pun++ = *p++;
-        }
-    }
-    *pun = '\0';
-    return un;
-}
-
-/*
- * Given a path to a jre to execute, this routine checks if this process
- * is indeed that jre.  If not, it exec's that jre.
- *
- * We want to actually check the paths rather than just the version string
- * built into the executable, so that given version specification will yield
- * the exact same Java environment, regardless of the version of the arbitrary
- * launcher we start with.
- */
-void
-ExecJRE(char *jre, char **argv) {
-    int     len;
-    char    *progname;
-    char    path[MAXPATHLEN + 1];
-
-    /*
-     * Determine the executable we are building (or in the rare case, running).
-     */
-#ifdef JAVA_ARGS  /* javac, jar and friends. */
-    progname = "java";
-#else             /* java, oldjava, javaw and friends */
-#ifdef PROGNAME
-    progname = PROGNAME;
-#else
-    {
-        char *s;
-        progname = *argv;
-        if ((s = strrchr(progname, FILE_SEPARATOR)) != 0) {
-            progname = s + 1;
-        }
-    }
-#endif /* PROGNAME */
-#endif /* JAVA_ARGS */
-
-    /*
-     * Resolve the real path to the currently running launcher.
-     */
-    len = GetModuleFileName(NULL, path, MAXPATHLEN + 1);
-    if (len == 0 || len > MAXPATHLEN) {
-        ReportSysErrorMessage2(
-          "Unable to resolve path to current %s executable: %s",
-          progname, JNI_TRUE);
-        exit(1);
-    }
-
-    if (_launcher_debug) {
-        printf("ExecJRE: old: %s\n", path);
-        printf("ExecJRE: new: %s\n", jre);
-    }
-
-    /*
-     * If the path to the selected JRE directory is a match to the initial
-     * portion of the path to the currently executing JRE, we have a winner!
-     * If so, just return. (strnicmp() is the Windows equiv. of strncasecmp().)
-     */
-    if (strnicmp(jre, path, strlen(jre)) == 0)
-        return;                 /* I am the droid you were looking for */
-
-    /*
-     * If this isn't the selected version, exec the selected version.
-     */
-    (void)strcat(strcat(strcpy(path, jre), "\\bin\\"), progname);
-    (void)strcat(path, ".exe");
-
-    /*
-     * Although Windows has an execv() entrypoint, it doesn't actually
-     * overlay a process: it can only create a new process and terminate
-     * the old process.  Therefore, any processes waiting on the initial
-     * process wake up and they shouldn't.  Hence, a chain of pseudo-zombie
-     * processes must be retained to maintain the proper wait semantics.
-     * Fortunately the image size of the launcher isn't too large at this
-     * time.
-     *
-     * If it weren't for this semantic flaw, the code below would be ...
-     *
-     *     execv(path, argv);
-     *     ReportErrorMessage2("Exec of %s failed\n", path, JNI_TRUE);
-     *     exit(1);
-     *
-     * The incorrect exec semantics could be addressed by:
-     *
-     *     exit((int)spawnv(_P_WAIT, path, argv));
-     *
-     * Unfortunately, a bug in Windows spawn/exec impementation prevents
-     * this from completely working.  All the Windows POSIX process creation
-     * interfaces are implemented as wrappers around the native Windows
-     * function CreateProcess().  CreateProcess() takes a single string
-     * to specify command line options and arguments, so the POSIX routine
-     * wrappers build a single string from the argv[] array and in the
-     * process, any quoting information is lost.
-     *
-     * The solution to this to get the original command line, to process it
-     * to remove the new multiple JRE options (if any) as was done for argv
-     * in the common SelectVersion() routine and finally to pass it directly
-     * to the native CreateProcess() Windows process control interface.
-     */
-    {
-        char    *cmdline;
-        char    *p;
-        char    *np;
-        char    *ocl;
-        char    *ccl;
-        char    *unquoted;
-        DWORD   exitCode;
-        STARTUPINFO si;
-        PROCESS_INFORMATION pi;
-
-        /*
-         * The following code block gets and processes the original command
-         * line, replacing the argv[0] equivalent in the command line with
-         * the path to the new executable and removing the appropriate
-         * Multiple JRE support options. Note that similar logic exists
-         * in the platform independent SelectVersion routine, but is
-         * replicated here due to the syntax of CreateProcess().
-         *
-         * The magic "+ 4" characters added to the command line length are
-         * 2 possible quotes around the path (argv[0]), a space after the
-         * path and a terminating null character.
-         */
-        ocl = GetCommandLine();
-        np = ccl = JLI_StringDup(ocl);
-        p = nextarg(&np);               /* Discard argv[0] */
-        cmdline = (char *)JLI_MemAlloc(strlen(path) + strlen(np) + 4);
-        if (strchr(path, (int)' ') == NULL && strchr(path, (int)'\t') == NULL)
-            cmdline = strcpy(cmdline, path);
-        else
-            cmdline = strcat(strcat(strcpy(cmdline, "\""), path), "\"");
-
-        while (*np != (char)0) {                /* While more command-line */
-            p = nextarg(&np);
-            if (*p != (char)0) {                /* If a token was isolated */
-                unquoted = unquote(p);
-                if (*unquoted == '-') {         /* Looks like an option */
-                    if (strcmp(unquoted, "-classpath") == 0 ||
-                      strcmp(unquoted, "-cp") == 0) {   /* Unique cp syntax */
-                        cmdline = strcat(strcat(cmdline, " "), p);
-                        p = nextarg(&np);
-                        if (*p != (char)0)      /* If a token was isolated */
-                            cmdline = strcat(strcat(cmdline, " "), p);
-                    } else if (strncmp(unquoted, "-version:", 9) != 0 &&
-                      strcmp(unquoted, "-jre-restrict-search") != 0 &&
-                      strcmp(unquoted, "-no-jre-restrict-search") != 0) {
-                        cmdline = strcat(strcat(cmdline, " "), p);
-                    }
-                } else {                        /* End of options */
-                    cmdline = strcat(strcat(cmdline, " "), p);
-                    cmdline = strcat(strcat(cmdline, " "), np);
-                    JLI_MemFree((void *)unquoted);
-                    break;
-                }
-                JLI_MemFree((void *)unquoted);
-            }
-        }
-        JLI_MemFree((void *)ccl);
-
-        if (_launcher_debug) {
-            np = ccl = JLI_StringDup(cmdline);
-            p = nextarg(&np);
-            printf("ReExec Command: %s (%s)\n", path, p);
-            printf("ReExec Args: %s\n", np);
-            JLI_MemFree((void *)ccl);
-        }
-        (void)fflush(stdout);
-        (void)fflush(stderr);
-
-        /*
-         * The following code is modeled after a model presented in the
-         * Microsoft Technical Article "Moving Unix Applications to
-         * Windows NT" (March 6, 1994) and "Creating Processes" on MSDN
-         * (Februrary 2005).  It approximates UNIX spawn semantics with
-         * the parent waiting for termination of the child.
-         */
-        memset(&si, 0, sizeof(si));
-        si.cb =sizeof(STARTUPINFO);
-        memset(&pi, 0, sizeof(pi));
-
-        if (!CreateProcess((LPCTSTR)path,       /* executable name */
-          (LPTSTR)cmdline,                      /* command line */
-          (LPSECURITY_ATTRIBUTES)NULL,          /* process security attr. */
-          (LPSECURITY_ATTRIBUTES)NULL,          /* thread security attr. */
-          (BOOL)TRUE,                           /* inherits system handles */
-          (DWORD)0,                             /* creation flags */
-          (LPVOID)NULL,                         /* environment block */
-          (LPCTSTR)NULL,                        /* current directory */
-          (LPSTARTUPINFO)&si,                   /* (in) startup information */
-          (LPPROCESS_INFORMATION)&pi)) {        /* (out) process information */
-            ReportSysErrorMessage2("CreateProcess(%s, ...) failed: %s",
-              path, JNI_TRUE);
-              exit(1);
-        }
-
-        if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_FAILED) {
-            if (GetExitCodeProcess(pi.hProcess, &exitCode) == FALSE)
-                exitCode = 1;
-        } else {
-            ReportErrorMessage("WaitForSingleObject() failed.", JNI_TRUE);
-            exitCode = 1;
-        }
-
-        CloseHandle(pi.hThread);
-        CloseHandle(pi.hProcess);
-
-        exit(exitCode);
-    }
-
-}
-
-#endif /* ifndef GAMMA */
-
-
-/*
- * Wrapper for platform dependent unsetenv function.
- */
-int
-UnsetEnv(char *name)
-{
-    int ret;
-    char *buf = JLI_MemAlloc(strlen(name) + 2);
-    buf = strcat(strcpy(buf, name), "=");
-    ret = _putenv(buf);
-    JLI_MemFree(buf);
-    return (ret);
-}
-
-/* --- Splash Screen shared library support --- */
-
-static const char* SPLASHSCREEN_SO = "\\bin\\splashscreen.dll";
-
-static HMODULE hSplashLib = NULL;
-
-void* SplashProcAddress(const char* name) {
-    char libraryPath[MAXPATHLEN]; /* some extra space for strcat'ing SPLASHSCREEN_SO */
-
-    if (!GetJREPath(libraryPath, MAXPATHLEN)) {
-        return NULL;
-    }
-    if (strlen(libraryPath)+strlen(SPLASHSCREEN_SO) >= MAXPATHLEN) {
-        return NULL;
-    }
-    strcat(libraryPath, SPLASHSCREEN_SO);
-
-    if (!hSplashLib) {
-        hSplashLib = LoadLibrary(libraryPath);
-    }
-    if (hSplashLib) {
-        return GetProcAddress(hSplashLib, name);
-    } else {
-        return NULL;
-    }
-}
-
-void SplashFreeLibrary() {
-    if (hSplashLib) {
-        FreeLibrary(hSplashLib);
-        hSplashLib = NULL;
-    }
-}
-
-/*
- * Block current thread and continue execution in a new thread
- */
-int
-ContinueInNewThread(int (JNICALL *continuation)(void *), jlong stack_size, void * args) {
-    int rslt = 0;
-    unsigned thread_id;
-
-#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION
-#define STACK_SIZE_PARAM_IS_A_RESERVATION  (0x10000)
-#endif
-
-    /*
-     * STACK_SIZE_PARAM_IS_A_RESERVATION is what we want, but it's not
-     * supported on older version of Windows. Try first with the flag; and
-     * if that fails try again without the flag. See MSDN document or HotSpot
-     * source (os_win32.cpp) for details.
-     */
-    HANDLE thread_handle =
-      (HANDLE)_beginthreadex(NULL,
-                             (unsigned)stack_size,
-                             continuation,
-                             args,
-                             STACK_SIZE_PARAM_IS_A_RESERVATION,
-                             &thread_id);
-    if (thread_handle == NULL) {
-      thread_handle =
-      (HANDLE)_beginthreadex(NULL,
-                             (unsigned)stack_size,
-                             continuation,
-                             args,
-                             0,
-                             &thread_id);
-    }
-
-    /* AWT preloading (AFTER main thread start) */
-#ifdef ENABLE_AWT_PRELOAD
-    /* D3D preloading */
-    if (awtPreloadD3D != 0) {
-        char *envValue;
-        /* D3D routines checks env.var J2D_D3D if no appropriate
-         * command line params was specified
-         */
-        envValue = getenv("J2D_D3D");
-        if (envValue != NULL && stricmp(envValue, "false") == 0) {
-            awtPreloadD3D = 0;
-        }
-        /* Test that AWT preloading isn't disabled by J2D_D3D_PRELOAD env.var */
-        envValue = getenv("J2D_D3D_PRELOAD");
-        if (envValue != NULL && stricmp(envValue, "false") == 0) {
-            awtPreloadD3D = 0;
-        }
-        if (awtPreloadD3D < 0) {
-            /* If awtPreloadD3D is still undefined (-1), test
-             * if it is turned on by J2D_D3D_PRELOAD env.var.
-             * By default it's turned OFF.
-             */
-            awtPreloadD3D = 0;
-            if (envValue != NULL && stricmp(envValue, "true") == 0) {
-                awtPreloadD3D = 1;
-            }
-        }
-    }
-    if (awtPreloadD3D) {
-        AWTPreload(D3D_PRELOAD_FUNC);
-    }
-#endif /* ENABLE_AWT_PRELOAD */
-
-    if (thread_handle) {
-      WaitForSingleObject(thread_handle, INFINITE);
-      GetExitCodeThread(thread_handle, &rslt);
-      CloseHandle(thread_handle);
-    } else {
-      rslt = continuation(args);
-    }
-
-#ifdef ENABLE_AWT_PRELOAD
-    if (awtPreloaded) {
-        AWTPreloadStop();
-    }
-#endif /* ENABLE_AWT_PRELOAD */
-
-    return rslt;
-}
-
-/* Linux only, empty on windows. */
-void SetJavaLauncherPlatformProps() {}
-
-
-//==============================
-// AWT preloading
-#ifdef ENABLE_AWT_PRELOAD
-
-typedef int FnPreloadStart(void);
-typedef void FnPreloadStop(void);
-static FnPreloadStop *fnPreloadStop = NULL;
-static HMODULE hPreloadAwt = NULL;
-
-/*
- * Starts AWT preloading
- */
-int AWTPreload(const char *funcName)
-{
-    int result = -1;
-
-    // load AWT library once (if several preload function should be called)
-    if (hPreloadAwt == NULL) {
-        // awt.dll is not loaded yet
-        char libraryPath[MAXPATHLEN];
-        int jrePathLen = 0;
-        HMODULE hJava = NULL;
-        HMODULE hVerify = NULL;
-
-        while (1) {
-            // awt.dll depends on jvm.dll & java.dll;
-            // jvm.dll is already loaded, so we need only java.dll;
-            // java.dll depends on MSVCRT lib & verify.dll.
-            if (!GetJREPath(libraryPath, MAXPATHLEN)) {
-                break;
-            }
-
-            // save path length
-            jrePathLen = strlen(libraryPath);
-
-            // load msvcrt 1st
-            LoadMSVCRT();
-
-            // load verify.dll
-            strcat(libraryPath, "\\bin\\verify.dll");
-            hVerify = LoadLibrary(libraryPath);
-            if (hVerify == NULL) {
-                break;
-            }
-
-            // restore jrePath
-            libraryPath[jrePathLen] = 0;
-            // load java.dll
-            strcat(libraryPath, "\\bin\\" JAVA_DLL);
-            hJava = LoadLibrary(libraryPath);
-            if (hJava == NULL) {
-                break;
-            }
-
-            // restore jrePath
-            libraryPath[jrePathLen] = 0;
-            // load awt.dll
-            strcat(libraryPath, "\\bin\\awt.dll");
-            hPreloadAwt = LoadLibrary(libraryPath);
-            if (hPreloadAwt == NULL) {
-                break;
-            }
-
-            // get "preloadStop" func ptr
-            fnPreloadStop = (FnPreloadStop *)GetProcAddress(hPreloadAwt, "preloadStop");
-
-            break;
-        }
-    }
-
-    if (hPreloadAwt != NULL) {
-        FnPreloadStart *fnInit = (FnPreloadStart *)GetProcAddress(hPreloadAwt, funcName);
-        if (fnInit != NULL) {
-            // don't forget to stop preloading
-            awtPreloaded = 1;
-
-            result = fnInit();
-        }
-    }
-
-    return result;
-}
-
-/*
- * Terminates AWT preloading
- */
-void AWTPreloadStop() {
-    if (fnPreloadStop != NULL) {
-        fnPreloadStop();
-    }
-}
-
-#endif /* ENABLE_AWT_PRELOAD */
diff --git a/hotspot/src/os/windows/launcher/java_md.h b/hotspot/src/os/windows/launcher/java_md.h
deleted file mode 100644
index 763e245..0000000
--- a/hotspot/src/os/windows/launcher/java_md.h
+++ /dev/null
@@ -1,83 +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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef JAVA_MD_H
-#define JAVA_MD_H
-
-#include <jni.h>
-#include <windows.h>
-#include <io.h>
-#ifndef GAMMA
-#include "manifest_info.h"
-#endif
-#include "jli_util.h"
-
-#ifdef GAMMA
-#define stricmp _stricmp
-#define strnicmp _strnicmp
-#define snprintf _snprintf
-#define strdup _strdup
-#endif
-
-#define PATH_SEPARATOR  ';'
-#define FILESEP         "\\"
-#define FILE_SEPARATOR  '\\'
-#define IS_FILE_SEPARATOR(c) ((c) == '\\' || (c) == '/')
-#define MAXPATHLEN      MAX_PATH
-#define MAXNAMELEN      MAX_PATH
-
-#ifdef JAVA_ARGS
-/*
- * ApplicationHome is prepended to each of these entries; the resulting
- * strings are concatenated (separated by PATH_SEPARATOR) and used as the
- * value of -cp option to the launcher.
- */
-#ifndef APP_CLASSPATH
-#define APP_CLASSPATH        { "\\lib\\tools.jar", "\\classes" }
-#endif
-#endif
-
-/*
- * Support for doing cheap, accurate interval timing.
- */
-extern jlong CounterGet(void);
-extern jlong Counter2Micros(jlong counts);
-
-#ifdef JAVAW
-#define main _main
-extern int _main(int argc, char **argv);
-#endif
-
-#define JLONG_FORMAT "%I64d"
-
-/*
- * Function prototypes.
- */
-#ifndef GAMMA
-char *LocateJRE(manifest_info *info);
-void ExecJRE(char *jre, char **argv);
-#endif
-int UnsetEnv(char *name);
-
-#endif
diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp
index dfcb64d..5a05d41 100644
--- a/hotspot/src/os/windows/vm/os_windows.cpp
+++ b/hotspot/src/os/windows/vm/os_windows.cpp
@@ -3307,7 +3307,7 @@
   assert(ret != SYS_THREAD_ERROR, "StartThread failed"); // should propagate back
 }
 
-class HighResolutionInterval {
+class HighResolutionInterval : public CHeapObj<mtThread> {
   // The default timer resolution seems to be 10 milliseconds.
   // (Where is this written down?)
   // If someone wants to sleep for only a fraction of the default,
diff --git a/hotspot/src/share/tools/ProjectCreator/BuildConfig.java b/hotspot/src/share/tools/ProjectCreator/BuildConfig.java
index 953967f..f928388 100644
--- a/hotspot/src/share/tools/ProjectCreator/BuildConfig.java
+++ b/hotspot/src/share/tools/ProjectCreator/BuildConfig.java
@@ -65,6 +65,7 @@
         String sourceBase = getFieldString(null, "SourceBase");
         String buildSpace = getFieldString(null, "BuildSpace");
         String outDir = buildBase;
+        String jdkTargetRoot = getFieldString(null, "JdkTargetRoot");
 
         put("Id", flavourBuild);
         put("OutputDir", outDir);
@@ -72,6 +73,7 @@
         put("BuildBase", buildBase);
         put("BuildSpace", buildSpace);
         put("OutputDll", outDir + Util.sep + outDll);
+        put("JdkTargetRoot", jdkTargetRoot);
 
         context = new String [] {flavourBuild, flavour, build, null};
     }
diff --git a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java
index 137abdc..8d094d3 100644
--- a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java
+++ b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java
@@ -98,11 +98,6 @@
             tagV(cfg.getV("LinkerFlags"));
             endTag();
 
-            startTag("PostBuildEvent");
-            tagData("Message", BuildConfig.getFieldString(null, "PostbuildDescription"));
-            tagData("Command", cfg.expandFormat(BuildConfig.getFieldString(null, "PostbuildCommand").replace("\t", "\r\n")));
-            endTag();
-
             startTag("PreLinkEvent");
             tagData("Message", BuildConfig.getFieldString(null, "PrelinkDescription"));
             tagData("Command", cfg.expandFormat(BuildConfig.getFieldString(null, "PrelinkCommand").replace("\t", "\r\n")));
@@ -141,7 +136,9 @@
 
         for (BuildConfig cfg : allConfigs) {
             startTag(cfg, "PropertyGroup");
-            tagData("LocalDebuggerCommand", "$(TargetDir)/hotspot.exe");
+            tagData("LocalDebuggerCommand", cfg.get("JdkTargetRoot") + "\\bin\\java.exe");
+            tagData("LocalDebuggerCommandArguments", "-XXaltjvm=$(TargetDir) -Dsun.java.launcher=gamma");
+            tagData("LocalDebuggerEnvironment", "JAVA_HOME=" + cfg.get("JdkTargetRoot"));
             endTag();
         }
 
diff --git a/hotspot/src/share/tools/launcher/java.c b/hotspot/src/share/tools/launcher/java.c
deleted file mode 100644
index 63f11d7..0000000
--- a/hotspot/src/share/tools/launcher/java.c
+++ /dev/null
@@ -1,2080 +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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-/*
- * Gamma (Hotspot internal engineering test) launcher based on 6.0u22 JDK,
- * search "GAMMA" for gamma specific changes.
- *
- * GAMMA: gamma launcher is much simpler than regular java launcher in that
- *        JVM is either statically linked in or it is installed in the
- *        same directory where the launcher exists, so we don't have to
- *        worry about choosing the right JVM based on command line flag, jar
- *        file and/or ergonomics. Intead of removing unused logic from source
- *        they are commented out with #ifndef GAMMA, hopefully it'll be easier
- *        to maintain this file in sync with regular JDK launcher.
- */
-
-/*
- * Shared source for 'java' command line tool.
- *
- * If JAVA_ARGS is defined, then acts as a launcher for applications. For
- * instance, the JDK command line tools such as javac and javadoc (see
- * makefiles for more details) are built with this program.  Any arguments
- * prefixed with '-J' will be passed directly to the 'java' command.
- */
-
-#ifdef GAMMA
-#  ifdef JAVA_ARGS
-#    error Do NOT define JAVA_ARGS when building gamma launcher
-#  endif
-#  if !defined(LINK_INTO_AOUT) && !defined(LINK_INTO_LIBJVM)
-#    error Either LINK_INTO_AOUT or LINK_INTO_LIBJVM must be defined
-#  endif
-#endif
-
-/*
- * One job of the launcher is to remove command line options which the
- * vm does not understand and will not process.  These options include
- * options which select which style of vm is run (e.g. -client and
- * -server) as well as options which select the data model to use.
- * Additionally, for tools which invoke an underlying vm "-J-foo"
- * options are turned into "-foo" options to the vm.  This option
- * filtering is handled in a number of places in the launcher, some of
- * it in machine-dependent code.  In this file, the function
- * CheckJVMType removes vm style options and TranslateApplicationArgs
- * removes "-J" prefixes.  On unix platforms, the
- * CreateExecutionEnvironment function from the unix java_md.c file
- * processes and removes -d<n> options.  However, in case
- * CreateExecutionEnvironment does not need to exec because
- * LD_LIBRARY_PATH is set acceptably and the data model does not need
- * to be changed, ParseArguments will screen out the redundant -d<n>
- * options and prevent them from being passed to the vm; this is done
- * by using the machine-dependent call
- * RemovableMachineDependentOption.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <jni.h>
-#include <jvm.h>
-#include "java.h"
-#ifndef GAMMA
-#include "manifest_info.h"
-#include "version_comp.h"
-#include "splashscreen.h"
-#endif
-#include "wildcard.h"
-
-#ifndef FULL_VERSION
-#define FULL_VERSION JDK_MAJOR_VERSION "." JDK_MINOR_VERSION
-#endif
-
-/*
- * The following environment variable is used to influence the behavior
- * of the jre exec'd through the SelectVersion routine.  The command line
- * options which specify the version are not passed to the exec'd version,
- * because that jre may be an older version which wouldn't recognize them.
- * This environment variable is known to this (and later) version and serves
- * to suppress the version selection code.  This is not only for efficiency,
- * but also for correctness, since any command line options have been
- * removed which would cause any value found in the manifest to be used.
- * This would be incorrect because the command line options are defined
- * to take precedence.
- *
- * The value associated with this environment variable is the MainClass
- * name from within the executable jar file (if any). This is strictly a
- * performance enhancement to avoid re-reading the jar file manifest.
- *
- * A NOTE TO DEVELOPERS: For performance reasons it is important that
- * the program image remain relatively small until after SelectVersion
- * CreateExecutionEnvironment have finished their possibly recursive
- * processing. Watch everything, but resist all temptations to use Java
- * interfaces.
- */
-#define ENV_ENTRY "_JAVA_VERSION_SET"
-
-#ifndef GAMMA
-#define SPLASH_FILE_ENV_ENTRY "_JAVA_SPLASH_FILE"
-#define SPLASH_JAR_ENV_ENTRY "_JAVA_SPLASH_JAR"
-#endif
-
-static jboolean printVersion = JNI_FALSE; /* print and exit */
-static jboolean showVersion = JNI_FALSE;  /* print but continue */
-static char *progname;
-jboolean _launcher_debug = JNI_FALSE;
-
-#ifndef GAMMA
-/*
- * Entries for splash screen environment variables.
- * putenv is performed in SelectVersion. We need
- * them in memory until UnsetEnv, so they are made static
- * global instead of auto local.
- */
-static char* splash_file_entry = NULL;
-static char* splash_jar_entry = NULL;
-#endif
-
-/*
- * List of VM options to be specified when the VM is created.
- */
-static JavaVMOption *options;
-static int numOptions, maxOptions;
-
-/*
- * Prototypes for functions internal to launcher.
- */
-static void SetClassPath(const char *s);
-static void SelectVersion(int argc, char **argv, char **main_class);
-static jboolean ParseArguments(int *pargc, char ***pargv, char **pjarfile,
-                               char **pclassname, int *pret, const char *jvmpath);
-static jboolean InitializeJVM(JavaVM **pvm, JNIEnv **penv,
-                              InvocationFunctions *ifn);
-static jstring NewPlatformString(JNIEnv *env, char *s);
-static jobjectArray NewPlatformStringArray(JNIEnv *env, char **strv, int strc);
-static jclass LoadClass(JNIEnv *env, char *name);
-static jstring GetMainClassName(JNIEnv *env, char *jarname);
-static void SetJavaCommandLineProp(char* classname, char* jarfile, int argc, char** argv);
-static void SetJavaLauncherProp(void);
-
-#ifdef JAVA_ARGS
-static void TranslateApplicationArgs(int *pargc, char ***pargv);
-static jboolean AddApplicationOptions(void);
-#endif
-
-static void PrintJavaVersion(JNIEnv *env);
-static void PrintUsage(void);
-static jint PrintXUsage(const char *jvmpath);
-
-static void SetPaths(int argc, char **argv);
-
-#ifndef GAMMA
-
-/* Maximum supported entries from jvm.cfg. */
-#define INIT_MAX_KNOWN_VMS      10
-/* Values for vmdesc.flag */
-#define VM_UNKNOWN              -1
-#define VM_KNOWN                 0
-#define VM_ALIASED_TO            1
-#define VM_WARN                  2
-#define VM_ERROR                 3
-#define VM_IF_SERVER_CLASS       4
-#define VM_IGNORE                5
-struct vmdesc {
-    char *name;
-    int flag;
-    char *alias;
-    char *server_class;
-};
-static struct vmdesc *knownVMs = NULL;
-static int knownVMsCount = 0;
-static int knownVMsLimit = 0;
-
-static void GrowKnownVMs();
-static int  KnownVMIndex(const char* name);
-static void FreeKnownVMs();
-static void ShowSplashScreen();
-
-#endif /* ifndef GAMMA */
-
-jboolean ServerClassMachine();
-
-/* flag which if set suppresses error messages from the launcher */
-static int noExitErrorMessage = 0;
-
-/*
- * Running Java code in primordial thread caused many problems. We will
- * create a new thread to invoke JVM. See 6316197 for more information.
- */
-static jlong threadStackSize = 0;  /* stack size of the new thread */
-
-int JNICALL JavaMain(void * args); /* entry point                  */
-
-struct JavaMainArgs {
-  int     argc;
-  char ** argv;
-  char *  jarfile;
-  char *  classname;
-  InvocationFunctions ifn;
-};
-
-/*
- * Entry point.
- */
-int
-main(int argc, char ** argv)
-{
-    char *jarfile = 0;
-    char *classname = 0;
-    char *s = 0;
-    char *main_class = NULL;
-    int ret;
-    InvocationFunctions ifn;
-    jlong start, end;
-    char jrepath[MAXPATHLEN], jvmpath[MAXPATHLEN];
-    char ** original_argv = argv;
-
-    if (getenv("_JAVA_LAUNCHER_DEBUG") != 0) {
-        _launcher_debug = JNI_TRUE;
-        printf("----_JAVA_LAUNCHER_DEBUG----\n");
-    }
-
-#ifndef GAMMA
-    /*
-     * Make sure the specified version of the JRE is running.
-     *
-     * There are three things to note about the SelectVersion() routine:
-     *  1) If the version running isn't correct, this routine doesn't
-     *     return (either the correct version has been exec'd or an error
-     *     was issued).
-     *  2) Argc and Argv in this scope are *not* altered by this routine.
-     *     It is the responsibility of subsequent code to ignore the
-     *     arguments handled by this routine.
-     *  3) As a side-effect, the variable "main_class" is guaranteed to
-     *     be set (if it should ever be set).  This isn't exactly the
-     *     poster child for structured programming, but it is a small
-     *     price to pay for not processing a jar file operand twice.
-     *     (Note: This side effect has been disabled.  See comment on
-     *     bugid 5030265 below.)
-     */
-    SelectVersion(argc, argv, &main_class);
-#endif /* ifndef GAMMA */
-
-    /* copy original argv */
-    {
-      int i;
-      original_argv = (char**)JLI_MemAlloc(sizeof(char*)*(argc+1));
-      for(i = 0; i < argc+1; i++)
-        original_argv[i] = argv[i];
-    }
-
-    CreateExecutionEnvironment(&argc, &argv,
-                               jrepath, sizeof(jrepath),
-                               jvmpath, sizeof(jvmpath),
-                               original_argv);
-
-    printf("Using java runtime at: %s\n", jrepath);
-
-    ifn.CreateJavaVM = 0;
-    ifn.GetDefaultJavaVMInitArgs = 0;
-
-    if (_launcher_debug)
-      start = CounterGet();
-    if (!LoadJavaVM(jvmpath, &ifn)) {
-      exit(6);
-    }
-    if (_launcher_debug) {
-      end   = CounterGet();
-      printf("%ld micro seconds to LoadJavaVM\n",
-             (long)(jint)Counter2Micros(end-start));
-    }
-
-#ifdef JAVA_ARGS  /* javac, jar and friends. */
-    progname = "java";
-#else             /* java, oldjava, javaw and friends */
-#ifdef PROGNAME
-    progname = PROGNAME;
-#else
-    progname = *argv;
-    if ((s = strrchr(progname, FILE_SEPARATOR)) != 0) {
-        progname = s + 1;
-    }
-#endif /* PROGNAME */
-#endif /* JAVA_ARGS */
-    ++argv;
-    --argc;
-
-#ifdef JAVA_ARGS
-    /* Preprocess wrapper arguments */
-    TranslateApplicationArgs(&argc, &argv);
-    if (!AddApplicationOptions()) {
-        exit(1);
-    }
-#endif
-
-    /* Set default CLASSPATH */
-    if ((s = getenv("CLASSPATH")) == 0) {
-        s = ".";
-    }
-#ifndef JAVA_ARGS
-    SetClassPath(s);
-#endif
-
-    /*
-     *  Parse command line options; if the return value of
-     *  ParseArguments is false, the program should exit.
-     */
-    if (!ParseArguments(&argc, &argv, &jarfile, &classname, &ret, jvmpath)) {
-      exit(ret);
-    }
-
-    /* Override class path if -jar flag was specified */
-    if (jarfile != 0) {
-        SetClassPath(jarfile);
-    }
-
-    /* set the -Dsun.java.command pseudo property */
-    SetJavaCommandLineProp(classname, jarfile, argc, argv);
-
-    /* Set the -Dsun.java.launcher pseudo property */
-    SetJavaLauncherProp();
-
-    /* set the -Dsun.java.launcher.* platform properties */
-    SetJavaLauncherPlatformProps();
-
-#ifndef GAMMA
-    /* Show the splash screen if needed */
-    ShowSplashScreen();
-#endif
-
-    /*
-     * Done with all command line processing and potential re-execs so
-     * clean up the environment.
-     */
-    (void)UnsetEnv(ENV_ENTRY);
-#ifndef GAMMA
-    (void)UnsetEnv(SPLASH_FILE_ENV_ENTRY);
-    (void)UnsetEnv(SPLASH_JAR_ENV_ENTRY);
-
-    JLI_MemFree(splash_jar_entry);
-    JLI_MemFree(splash_file_entry);
-#endif
-
-    /*
-     * If user doesn't specify stack size, check if VM has a preference.
-     * Note that HotSpot no longer supports JNI_VERSION_1_1 but it will
-     * return its default stack size through the init args structure.
-     */
-    if (threadStackSize == 0) {
-      struct JDK1_1InitArgs args1_1;
-      memset((void*)&args1_1, 0, sizeof(args1_1));
-      args1_1.version = JNI_VERSION_1_1;
-      ifn.GetDefaultJavaVMInitArgs(&args1_1);  /* ignore return value */
-      if (args1_1.javaStackSize > 0) {
-         threadStackSize = args1_1.javaStackSize;
-      }
-    }
-
-    { /* Create a new thread to create JVM and invoke main method */
-      struct JavaMainArgs args;
-
-      args.argc = argc;
-      args.argv = argv;
-      args.jarfile = jarfile;
-      args.classname = classname;
-      args.ifn = ifn;
-
-      return ContinueInNewThread(JavaMain, threadStackSize, (void*)&args);
-    }
-}
-
-int JNICALL
-JavaMain(void * _args)
-{
-    struct JavaMainArgs *args = (struct JavaMainArgs *)_args;
-    int argc = args->argc;
-    char **argv = args->argv;
-    char *jarfile = args->jarfile;
-    char *classname = args->classname;
-    InvocationFunctions ifn = args->ifn;
-
-    JavaVM *vm = 0;
-    JNIEnv *env = 0;
-    jstring mainClassName;
-    jclass mainClass;
-    jmethodID mainID;
-    jobjectArray mainArgs;
-    int ret = 0;
-    jlong start, end;
-
-    /*
-     * Error message to print or display; by default the message will
-     * only be displayed in a window.
-     */
-    char * message = "Fatal exception occurred.  Program will exit.";
-    jboolean messageDest = JNI_FALSE;
-
-    /* Initialize the virtual machine */
-
-    if (_launcher_debug)
-        start = CounterGet();
-    if (!InitializeJVM(&vm, &env, &ifn)) {
-        ReportErrorMessage("Could not create the Java virtual machine.",
-                           JNI_TRUE);
-        exit(1);
-    }
-
-    if (printVersion || showVersion) {
-        PrintJavaVersion(env);
-        if ((*env)->ExceptionOccurred(env)) {
-            ReportExceptionDescription(env);
-            goto leave;
-        }
-        if (printVersion) {
-            ret = 0;
-            message = NULL;
-            goto leave;
-        }
-        if (showVersion) {
-            fprintf(stderr, "\n");
-        }
-    }
-
-    /* If the user specified neither a class name nor a JAR file */
-    if (jarfile == 0 && classname == 0) {
-        PrintUsage();
-        message = NULL;
-        goto leave;
-    }
-
-#ifndef GAMMA
-    FreeKnownVMs();  /* after last possible PrintUsage() */
-#endif
-
-    if (_launcher_debug) {
-        end   = CounterGet();
-        printf("%ld micro seconds to InitializeJVM\n",
-               (long)(jint)Counter2Micros(end-start));
-    }
-
-    /* At this stage, argc/argv have the applications' arguments */
-    if (_launcher_debug) {
-        int i = 0;
-        printf("Main-Class is '%s'\n", classname ? classname : "");
-        printf("Apps' argc is %d\n", argc);
-        for (; i < argc; i++) {
-            printf("    argv[%2d] = '%s'\n", i, argv[i]);
-        }
-    }
-
-    ret = 1;
-
-    /*
-     * Get the application's main class.
-     *
-     * See bugid 5030265.  The Main-Class name has already been parsed
-     * from the manifest, but not parsed properly for UTF-8 support.
-     * Hence the code here ignores the value previously extracted and
-     * uses the pre-existing code to reextract the value.  This is
-     * possibly an end of release cycle expedient.  However, it has
-     * also been discovered that passing some character sets through
-     * the environment has "strange" behavior on some variants of
-     * Windows.  Hence, maybe the manifest parsing code local to the
-     * launcher should never be enhanced.
-     *
-     * Hence, future work should either:
-     *     1)   Correct the local parsing code and verify that the
-     *          Main-Class attribute gets properly passed through
-     *          all environments,
-     *     2)   Remove the vestages of maintaining main_class through
-     *          the environment (and remove these comments).
-     */
-    if (jarfile != 0) {
-        mainClassName = GetMainClassName(env, jarfile);
-        if ((*env)->ExceptionOccurred(env)) {
-            ReportExceptionDescription(env);
-            goto leave;
-        }
-        if (mainClassName == NULL) {
-          const char * format = "Failed to load Main-Class manifest "
-                                "attribute from\n%s";
-          message = (char*)JLI_MemAlloc((strlen(format) + strlen(jarfile)) *
-                                    sizeof(char));
-          sprintf(message, format, jarfile);
-          messageDest = JNI_TRUE;
-          goto leave;
-        }
-        classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0);
-        if (classname == NULL) {
-            ReportExceptionDescription(env);
-            goto leave;
-        }
-        mainClass = LoadClass(env, classname);
-        if(mainClass == NULL) { /* exception occured */
-            const char * format = "Could not find the main class: %s. Program will exit.";
-            ReportExceptionDescription(env);
-            message = (char *)JLI_MemAlloc((strlen(format) +
-                                            strlen(classname)) * sizeof(char) );
-            messageDest = JNI_TRUE;
-            sprintf(message, format, classname);
-            goto leave;
-        }
-        (*env)->ReleaseStringUTFChars(env, mainClassName, classname);
-    } else {
-      mainClassName = NewPlatformString(env, classname);
-      if (mainClassName == NULL) {
-        const char * format = "Failed to load Main Class: %s";
-        message = (char *)JLI_MemAlloc((strlen(format) + strlen(classname)) *
-                                   sizeof(char) );
-        sprintf(message, format, classname);
-        messageDest = JNI_TRUE;
-        goto leave;
-      }
-      classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0);
-      if (classname == NULL) {
-        ReportExceptionDescription(env);
-        goto leave;
-      }
-      mainClass = LoadClass(env, classname);
-      if(mainClass == NULL) { /* exception occured */
-        const char * format = "Could not find the main class: %s.  Program will exit.";
-        ReportExceptionDescription(env);
-        message = (char *)JLI_MemAlloc((strlen(format) +
-                                        strlen(classname)) * sizeof(char) );
-        messageDest = JNI_TRUE;
-        sprintf(message, format, classname);
-        goto leave;
-      }
-      (*env)->ReleaseStringUTFChars(env, mainClassName, classname);
-    }
-
-    /* Get the application's main method */
-    mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
-                                       "([Ljava/lang/String;)V");
-    if (mainID == NULL) {
-        if ((*env)->ExceptionOccurred(env)) {
-            ReportExceptionDescription(env);
-        } else {
-          message = "No main method found in specified class.";
-          messageDest = JNI_TRUE;
-        }
-        goto leave;
-    }
-
-    {    /* Make sure the main method is public */
-        jint mods;
-        jmethodID mid;
-        jobject obj = (*env)->ToReflectedMethod(env, mainClass,
-                                                mainID, JNI_TRUE);
-
-        if( obj == NULL) { /* exception occurred */
-            ReportExceptionDescription(env);
-            goto leave;
-        }
-
-        mid =
-          (*env)->GetMethodID(env,
-                              (*env)->GetObjectClass(env, obj),
-                              "getModifiers", "()I");
-        if ((*env)->ExceptionOccurred(env)) {
-            ReportExceptionDescription(env);
-            goto leave;
-        }
-
-        mods = (*env)->CallIntMethod(env, obj, mid);
-        if ((mods & 1) == 0) { /* if (!Modifier.isPublic(mods)) ... */
-            message = "Main method not public.";
-            messageDest = JNI_TRUE;
-            goto leave;
-        }
-    }
-
-    /* Build argument array */
-    mainArgs = NewPlatformStringArray(env, argv, argc);
-    if (mainArgs == NULL) {
-        ReportExceptionDescription(env);
-        goto leave;
-    }
-
-    /* Invoke main method. */
-    (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
-
-    /*
-     * The launcher's exit code (in the absence of calls to
-     * System.exit) will be non-zero if main threw an exception.
-     */
-    ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1;
-
-    /*
-     * Detach the main thread so that it appears to have ended when
-     * the application's main method exits.  This will invoke the
-     * uncaught exception handler machinery if main threw an
-     * exception.  An uncaught exception handler cannot change the
-     * launcher's return code except by calling System.exit.
-     */
-    if ((*vm)->DetachCurrentThread(vm) != 0) {
-        message = "Could not detach main thread.";
-        messageDest = JNI_TRUE;
-        ret = 1;
-        goto leave;
-    }
-
-    message = NULL;
-
- leave:
-    /*
-     * Wait for all non-daemon threads to end, then destroy the VM.
-     * This will actually create a trivial new Java waiter thread
-     * named "DestroyJavaVM", but this will be seen as a different
-     * thread from the one that executed main, even though they are
-     * the same C thread.  This allows mainThread.join() and
-     * mainThread.isAlive() to work as expected.
-     */
-    (*vm)->DestroyJavaVM(vm);
-
-    if(message != NULL && !noExitErrorMessage)
-      ReportErrorMessage(message, messageDest);
-    return ret;
-}
-
-#ifndef GAMMA
-/*
- * Checks the command line options to find which JVM type was
- * specified.  If no command line option was given for the JVM type,
- * the default type is used.  The environment variable
- * JDK_ALTERNATE_VM and the command line option -XXaltjvm= are also
- * checked as ways of specifying which JVM type to invoke.
- */
-char *
-CheckJvmType(int *pargc, char ***argv, jboolean speculative) {
-    int i, argi;
-    int argc;
-    char **newArgv;
-    int newArgvIdx = 0;
-    int isVMType;
-    int jvmidx = -1;
-    char *jvmtype = getenv("JDK_ALTERNATE_VM");
-
-    argc = *pargc;
-
-    /* To make things simpler we always copy the argv array */
-    newArgv = JLI_MemAlloc((argc + 1) * sizeof(char *));
-
-    /* The program name is always present */
-    newArgv[newArgvIdx++] = (*argv)[0];
-
-    for (argi = 1; argi < argc; argi++) {
-        char *arg = (*argv)[argi];
-        isVMType = 0;
-
-#ifdef JAVA_ARGS
-        if (arg[0] != '-') {
-            newArgv[newArgvIdx++] = arg;
-            continue;
-        }
-#else
-        if (strcmp(arg, "-classpath") == 0 ||
-            strcmp(arg, "-cp") == 0) {
-            newArgv[newArgvIdx++] = arg;
-            argi++;
-            if (argi < argc) {
-                newArgv[newArgvIdx++] = (*argv)[argi];
-            }
-            continue;
-        }
-        if (arg[0] != '-') break;
-#endif
-
-        /* Did the user pass an explicit VM type? */
-        i = KnownVMIndex(arg);
-        if (i >= 0) {
-            jvmtype = knownVMs[jvmidx = i].name + 1; /* skip the - */
-            isVMType = 1;
-            *pargc = *pargc - 1;
-        }
-
-        /* Did the user specify an "alternate" VM? */
-        else if (strncmp(arg, "-XXaltjvm=", 10) == 0 || strncmp(arg, "-J-XXaltjvm=", 12) == 0) {
-            isVMType = 1;
-            jvmtype = arg+((arg[1]=='X')? 10 : 12);
-            jvmidx = -1;
-        }
-
-        if (!isVMType) {
-            newArgv[newArgvIdx++] = arg;
-        }
-    }
-
-    /*
-     * Finish copying the arguments if we aborted the above loop.
-     * NOTE that if we aborted via "break" then we did NOT copy the
-     * last argument above, and in addition argi will be less than
-     * argc.
-     */
-    while (argi < argc) {
-        newArgv[newArgvIdx++] = (*argv)[argi];
-        argi++;
-    }
-
-    /* argv is null-terminated */
-    newArgv[newArgvIdx] = 0;
-
-    /* Copy back argv */
-    *argv = newArgv;
-    *pargc = newArgvIdx;
-
-    /* use the default VM type if not specified (no alias processing) */
-    if (jvmtype == NULL) {
-      char* result = knownVMs[0].name+1;
-      /* Use a different VM type if we are on a server class machine? */
-      if ((knownVMs[0].flag == VM_IF_SERVER_CLASS) &&
-          (ServerClassMachine() == JNI_TRUE)) {
-        result = knownVMs[0].server_class+1;
-      }
-      if (_launcher_debug) {
-        printf("Default VM: %s\n", result);
-      }
-      return result;
-    }
-
-    /* if using an alternate VM, no alias processing */
-    if (jvmidx < 0)
-      return jvmtype;
-
-    /* Resolve aliases first */
-    {
-      int loopCount = 0;
-      while (knownVMs[jvmidx].flag == VM_ALIASED_TO) {
-        int nextIdx = KnownVMIndex(knownVMs[jvmidx].alias);
-
-        if (loopCount > knownVMsCount) {
-          if (!speculative) {
-            ReportErrorMessage("Error: Corrupt jvm.cfg file; cycle in alias list.",
-                               JNI_TRUE);
-            exit(1);
-          } else {
-            return "ERROR";
-            /* break; */
-          }
-        }
-
-        if (nextIdx < 0) {
-          if (!speculative) {
-            ReportErrorMessage2("Error: Unable to resolve VM alias %s",
-                                knownVMs[jvmidx].alias, JNI_TRUE);
-            exit(1);
-          } else {
-            return "ERROR";
-          }
-        }
-        jvmidx = nextIdx;
-        jvmtype = knownVMs[jvmidx].name+1;
-        loopCount++;
-      }
-    }
-
-    switch (knownVMs[jvmidx].flag) {
-    case VM_WARN:
-        if (!speculative) {
-            fprintf(stderr, "Warning: %s VM not supported; %s VM will be used\n",
-                    jvmtype, knownVMs[0].name + 1);
-        }
-        /* fall through */
-    case VM_IGNORE:
-        jvmtype = knownVMs[jvmidx=0].name + 1;
-        /* fall through */
-    case VM_KNOWN:
-        break;
-    case VM_ERROR:
-        if (!speculative) {
-            ReportErrorMessage2("Error: %s VM not supported", jvmtype, JNI_TRUE);
-            exit(1);
-        } else {
-            return "ERROR";
-        }
-    }
-
-    return jvmtype;
-}
-#endif /* ifndef GAMMA */
-
-# define KB (1024UL)
-# define MB (1024UL * KB)
-# define GB (1024UL * MB)
-
-/* copied from HotSpot function "atomll()" */
-static int
-parse_stack_size(const char *s, jlong *result) {
-  jlong n = 0;
-  int args_read = sscanf(s, JLONG_FORMAT, &n);
-  if (args_read != 1) {
-    return 0;
-  }
-  while (*s != '\0' && *s >= '0' && *s <= '9') {
-    s++;
-  }
-  // 4705540: illegal if more characters are found after the first non-digit
-  if (strlen(s) > 1) {
-    return 0;
-  }
-  switch (*s) {
-    case 'T': case 't':
-      *result = n * GB * KB;
-      return 1;
-    case 'G': case 'g':
-      *result = n * GB;
-      return 1;
-    case 'M': case 'm':
-      *result = n * MB;
-      return 1;
-    case 'K': case 'k':
-      *result = n * KB;
-      return 1;
-    case '\0':
-      *result = n;
-      return 1;
-    default:
-      /* Create JVM with default stack and let VM handle malformed -Xss string*/
-      return 0;
-  }
-}
-
-/*
- * Adds a new VM option with the given given name and value.
- */
-void
-AddOption(char *str, void *info)
-{
-    /*
-     * Expand options array if needed to accommodate at least one more
-     * VM option.
-     */
-    if (numOptions >= maxOptions) {
-        if (options == 0) {
-            maxOptions = 4;
-            options = JLI_MemAlloc(maxOptions * sizeof(JavaVMOption));
-        } else {
-            JavaVMOption *tmp;
-            maxOptions *= 2;
-            tmp = JLI_MemAlloc(maxOptions * sizeof(JavaVMOption));
-            memcpy(tmp, options, numOptions * sizeof(JavaVMOption));
-            JLI_MemFree(options);
-            options = tmp;
-        }
-    }
-    options[numOptions].optionString = str;
-    options[numOptions++].extraInfo = info;
-
-    if (strncmp(str, "-Xss", 4) == 0) {
-      jlong tmp;
-      if (parse_stack_size(str + 4, &tmp)) {
-        threadStackSize = tmp;
-      }
-    }
-}
-
-static void
-SetClassPath(const char *s)
-{
-    char *def;
-    s = JLI_WildcardExpandClasspath(s);
-    def = JLI_MemAlloc(strlen(s) + 40);
-    sprintf(def, "-Djava.class.path=%s", s);
-    AddOption(def, NULL);
-}
-
-#ifndef GAMMA
-/*
- * The SelectVersion() routine ensures that an appropriate version of
- * the JRE is running.  The specification for the appropriate version
- * is obtained from either the manifest of a jar file (preferred) or
- * from command line options.
- * The routine also parses splash screen command line options and
- * passes on their values in private environment variables.
- */
-static void
-SelectVersion(int argc, char **argv, char **main_class)
-{
-    char    *arg;
-    char    **new_argv;
-    char    **new_argp;
-    char    *operand;
-    char    *version = NULL;
-    char    *jre = NULL;
-    int     jarflag = 0;
-    int     headlessflag = 0;
-    int     restrict_search = -1;               /* -1 implies not known */
-    manifest_info info;
-    char    env_entry[MAXNAMELEN + 24] = ENV_ENTRY "=";
-    char    *splash_file_name = NULL;
-    char    *splash_jar_name = NULL;
-    char    *env_in;
-    int     res;
-
-    /*
-     * If the version has already been selected, set *main_class
-     * with the value passed through the environment (if any) and
-     * simply return.
-     */
-    if ((env_in = getenv(ENV_ENTRY)) != NULL) {
-        if (*env_in != '\0')
-            *main_class = JLI_StringDup(env_in);
-        return;
-    }
-
-    /*
-     * Scan through the arguments for options relevant to multiple JRE
-     * support.  For reference, the command line syntax is defined as:
-     *
-     * SYNOPSIS
-     *      java [options] class [argument...]
-     *
-     *      java [options] -jar file.jar [argument...]
-     *
-     * As the scan is performed, make a copy of the argument list with
-     * the version specification options (new to 1.5) removed, so that
-     * a version less than 1.5 can be exec'd.
-     *
-     * Note that due to the syntax of the native Windows interface
-     * CreateProcess(), processing similar to the following exists in
-     * the Windows platform specific routine ExecJRE (in java_md.c).
-     * Changes here should be reproduced there.
-     */
-    new_argv = JLI_MemAlloc((argc + 1) * sizeof(char*));
-    new_argv[0] = argv[0];
-    new_argp = &new_argv[1];
-    argc--;
-    argv++;
-    while ((arg = *argv) != 0 && *arg == '-') {
-        if (strncmp(arg, "-version:", 9) == 0) {
-            version = arg + 9;
-        } else if (strcmp(arg, "-jre-restrict-search") == 0) {
-            restrict_search = 1;
-        } else if (strcmp(arg, "-no-jre-restrict-search") == 0) {
-            restrict_search = 0;
-        } else {
-            if (strcmp(arg, "-jar") == 0)
-                jarflag = 1;
-            /* deal with "unfortunate" classpath syntax */
-            if ((strcmp(arg, "-classpath") == 0 || strcmp(arg, "-cp") == 0) &&
-              (argc >= 2)) {
-                *new_argp++ = arg;
-                argc--;
-                argv++;
-                arg = *argv;
-            }
-
-            /*
-             * Checking for headless toolkit option in the some way as AWT does:
-             * "true" means true and any other value means false
-             */
-            if (strcmp(arg, "-Djava.awt.headless=true") == 0) {
-                headlessflag = 1;
-            } else if (strncmp(arg, "-Djava.awt.headless=", 20) == 0) {
-                headlessflag = 0;
-            } else if (strncmp(arg, "-splash:", 8) == 0) {
-                splash_file_name = arg+8;
-            }
-            *new_argp++ = arg;
-        }
-        argc--;
-        argv++;
-    }
-    if (argc <= 0) {    /* No operand? Possibly legit with -[full]version */
-        operand = NULL;
-    } else {
-        argc--;
-        *new_argp++ = operand = *argv++;
-    }
-    while (argc-- > 0)  /* Copy over [argument...] */
-        *new_argp++ = *argv++;
-    *new_argp = NULL;
-
-    /*
-     * If there is a jar file, read the manifest. If the jarfile can't be
-     * read, the manifest can't be read from the jar file, or the manifest
-     * is corrupt, issue the appropriate error messages and exit.
-     *
-     * Even if there isn't a jar file, construct a manifest_info structure
-     * containing the command line information.  It's a convenient way to carry
-     * this data around.
-     */
-    if (jarflag && operand) {
-        if ((res = JLI_ParseManifest(operand, &info)) != 0) {
-            if (res == -1)
-                ReportErrorMessage2("Unable to access jarfile %s",
-                  operand, JNI_TRUE);
-            else
-                ReportErrorMessage2("Invalid or corrupt jarfile %s",
-                  operand, JNI_TRUE);
-            exit(1);
-        }
-
-        /*
-         * Command line splash screen option should have precedence
-         * over the manifest, so the manifest data is used only if
-         * splash_file_name has not been initialized above during command
-         * line parsing
-         */
-        if (!headlessflag && !splash_file_name && info.splashscreen_image_file_name) {
-            splash_file_name = info.splashscreen_image_file_name;
-            splash_jar_name = operand;
-        }
-    } else {
-        info.manifest_version = NULL;
-        info.main_class = NULL;
-        info.jre_version = NULL;
-        info.jre_restrict_search = 0;
-    }
-
-    /*
-     * Passing on splash screen info in environment variables
-     */
-    if (splash_file_name && !headlessflag) {
-        char* splash_file_entry = JLI_MemAlloc(strlen(SPLASH_FILE_ENV_ENTRY "=")+strlen(splash_file_name)+1);
-        strcpy(splash_file_entry, SPLASH_FILE_ENV_ENTRY "=");
-        strcat(splash_file_entry, splash_file_name);
-        putenv(splash_file_entry);
-    }
-    if (splash_jar_name && !headlessflag) {
-        char* splash_jar_entry = JLI_MemAlloc(strlen(SPLASH_JAR_ENV_ENTRY "=")+strlen(splash_jar_name)+1);
-        strcpy(splash_jar_entry, SPLASH_JAR_ENV_ENTRY "=");
-        strcat(splash_jar_entry, splash_jar_name);
-        putenv(splash_jar_entry);
-    }
-
-    /*
-     * The JRE-Version and JRE-Restrict-Search values (if any) from the
-     * manifest are overwritten by any specified on the command line.
-     */
-    if (version != NULL)
-        info.jre_version = version;
-    if (restrict_search != -1)
-        info.jre_restrict_search = restrict_search;
-
-    /*
-     * "Valid" returns (other than unrecoverable errors) follow.  Set
-     * main_class as a side-effect of this routine.
-     */
-    if (info.main_class != NULL)
-        *main_class = JLI_StringDup(info.main_class);
-
-    /*
-     * If no version selection information is found either on the command
-     * line or in the manifest, simply return.
-     */
-    if (info.jre_version == NULL) {
-        JLI_FreeManifest();
-        JLI_MemFree(new_argv);
-        return;
-    }
-
-    /*
-     * Check for correct syntax of the version specification (JSR 56).
-     */
-    if (!JLI_ValidVersionString(info.jre_version)) {
-        ReportErrorMessage2("Syntax error in version specification \"%s\"",
-          info.jre_version, JNI_TRUE);
-        exit(1);
-    }
-
-    /*
-     * Find the appropriate JVM on the system. Just to be as forgiving as
-     * possible, if the standard algorithms don't locate an appropriate
-     * jre, check to see if the one running will satisfy the requirements.
-     * This can happen on systems which haven't been set-up for multiple
-     * JRE support.
-     */
-    jre = LocateJRE(&info);
-    if (_launcher_debug)
-        printf("JRE-Version = %s, JRE-Restrict-Search = %s Selected = %s\n",
-          (info.jre_version?info.jre_version:"null"),
-          (info.jre_restrict_search?"true":"false"), (jre?jre:"null"));
-    if (jre == NULL) {
-        if (JLI_AcceptableRelease(FULL_VERSION, info.jre_version)) {
-            JLI_FreeManifest();
-            JLI_MemFree(new_argv);
-            return;
-        } else {
-            ReportErrorMessage2(
-              "Unable to locate JRE meeting specification \"%s\"",
-              info.jre_version, JNI_TRUE);
-            exit(1);
-        }
-    }
-
-    /*
-     * If I'm not the chosen one, exec the chosen one.  Returning from
-     * ExecJRE indicates that I am indeed the chosen one.
-     *
-     * The private environment variable _JAVA_VERSION_SET is used to
-     * prevent the chosen one from re-reading the manifest file and
-     * using the values found within to override the (potential) command
-     * line flags stripped from argv (because the target may not
-     * understand them).  Passing the MainClass value is an optimization
-     * to avoid locating, expanding and parsing the manifest extra
-     * times.
-     */
-    if (info.main_class != NULL) {
-        if (strlen(info.main_class) <= MAXNAMELEN) {
-            (void)strcat(env_entry, info.main_class);
-        } else {
-            ReportErrorMessage("Error: main-class: attribute exceeds system limits\n", JNI_TRUE);
-            exit(1);
-        }
-    }
-    (void)putenv(env_entry);
-    ExecJRE(jre, new_argv);
-    JLI_FreeManifest();
-    JLI_MemFree(new_argv);
-    return;
-}
-#endif /* ifndef GAMMA */
-
-/*
- * Parses command line arguments.  Returns JNI_FALSE if launcher
- * should exit without starting vm (e.g. certain version and usage
- * options); returns JNI_TRUE if vm needs to be started to process
- * given options.  *pret (the launcher process return value) is set to
- * 0 for a normal exit.
- */
-static jboolean
-ParseArguments(int *pargc, char ***pargv, char **pjarfile,
-                       char **pclassname, int *pret, const char *jvmpath)
-{
-    int argc = *pargc;
-    char **argv = *pargv;
-    jboolean jarflag = JNI_FALSE;
-    char *arg;
-
-    *pret = 1;
-    while ((arg = *argv) != 0 && *arg == '-') {
-        argv++; --argc;
-        if (strcmp(arg, "-classpath") == 0 || strcmp(arg, "-cp") == 0) {
-            if (argc < 1) {
-                ReportErrorMessage2("%s requires class path specification",
-                                    arg, JNI_TRUE);
-                PrintUsage();
-                return JNI_FALSE;
-            }
-            SetClassPath(*argv);
-            argv++; --argc;
-        } else if (strcmp(arg, "-jar") == 0) {
-            jarflag = JNI_TRUE;
-        } else if (strcmp(arg, "-help") == 0 ||
-                   strcmp(arg, "-h") == 0 ||
-                   strcmp(arg, "-?") == 0) {
-            PrintUsage();
-            *pret = 0;
-            return JNI_FALSE;
-        } else if (strcmp(arg, "-version") == 0) {
-            printVersion = JNI_TRUE;
-            return JNI_TRUE;
-        } else if (strcmp(arg, "-showversion") == 0) {
-            showVersion = JNI_TRUE;
-        } else if (strcmp(arg, "-X") == 0) {
-            *pret = PrintXUsage(jvmpath);
-            return JNI_FALSE;
-/*
- * The following case provide backward compatibility with old-style
- * command line options.
- */
-        } else if (strcmp(arg, "-fullversion") == 0) {
-            fprintf(stderr, "%s full version \"%s\"\n", progname,
-                    FULL_VERSION);
-            *pret = 0;
-            return JNI_FALSE;
-        } else if (strcmp(arg, "-verbosegc") == 0) {
-            AddOption("-verbose:gc", NULL);
-        } else if (strcmp(arg, "-t") == 0) {
-            AddOption("-Xt", NULL);
-        } else if (strcmp(arg, "-tm") == 0) {
-            AddOption("-Xtm", NULL);
-        } else if (strcmp(arg, "-debug") == 0) {
-            AddOption("-Xdebug", NULL);
-        } else if (strcmp(arg, "-noclassgc") == 0) {
-            AddOption("-Xnoclassgc", NULL);
-        } else if (strcmp(arg, "-Xfuture") == 0) {
-            AddOption("-Xverify:all", NULL);
-        } else if (strcmp(arg, "-verify") == 0) {
-            AddOption("-Xverify:all", NULL);
-        } else if (strcmp(arg, "-verifyremote") == 0) {
-            AddOption("-Xverify:remote", NULL);
-        } else if (strcmp(arg, "-noverify") == 0) {
-            AddOption("-Xverify:none", NULL);
-        } else if (strcmp(arg, "-XXsuppressExitMessage") == 0) {
-            noExitErrorMessage = 1;
-        } else if (strncmp(arg, "-prof", 5) == 0) {
-            char *p = arg + 5;
-            char *tmp = JLI_MemAlloc(strlen(arg) + 50);
-            if (*p) {
-                sprintf(tmp, "-Xrunhprof:cpu=old,file=%s", p + 1);
-            } else {
-                sprintf(tmp, "-Xrunhprof:cpu=old,file=java.prof");
-            }
-            AddOption(tmp, NULL);
-        } else if (strncmp(arg, "-ss", 3) == 0 ||
-                   strncmp(arg, "-oss", 4) == 0 ||
-                   strncmp(arg, "-ms", 3) == 0 ||
-                   strncmp(arg, "-mx", 3) == 0) {
-            char *tmp = JLI_MemAlloc(strlen(arg) + 6);
-            sprintf(tmp, "-X%s", arg + 1); /* skip '-' */
-            AddOption(tmp, NULL);
-        } else if (strcmp(arg, "-checksource") == 0 ||
-                   strcmp(arg, "-cs") == 0 ||
-                   strcmp(arg, "-noasyncgc") == 0) {
-            /* No longer supported */
-            fprintf(stderr,
-                    "Warning: %s option is no longer supported.\n",
-                    arg);
-        } else if (strncmp(arg, "-version:", 9) == 0 ||
-                   strcmp(arg, "-no-jre-restrict-search") == 0 ||
-                   strcmp(arg, "-jre-restrict-search") == 0 ||
-                   strncmp(arg, "-splash:", 8) == 0) {
-            ; /* Ignore machine independent options already handled */
-        } else if (RemovableMachineDependentOption(arg) ) {
-            ; /* Do not pass option to vm. */
-        }
-        else {
-            AddOption(arg, NULL);
-        }
-    }
-
-    if (--argc >= 0) {
-        if (jarflag) {
-            *pjarfile = *argv++;
-            *pclassname = 0;
-        } else {
-            *pjarfile = 0;
-            *pclassname = *argv++;
-        }
-        *pargc = argc;
-        *pargv = argv;
-    }
-
-    return JNI_TRUE;
-}
-
-/*
- * Initializes the Java Virtual Machine. Also frees options array when
- * finished.
- */
-static jboolean
-InitializeJVM(JavaVM **pvm, JNIEnv **penv, InvocationFunctions *ifn)
-{
-    JavaVMInitArgs args;
-    jint r;
-
-    memset(&args, 0, sizeof(args));
-    args.version  = JNI_VERSION_1_2;
-    args.nOptions = numOptions;
-    args.options  = options;
-    args.ignoreUnrecognized = JNI_FALSE;
-
-    if (_launcher_debug) {
-        int i = 0;
-        printf("JavaVM args:\n    ");
-        printf("version 0x%08lx, ", (long)args.version);
-        printf("ignoreUnrecognized is %s, ",
-               args.ignoreUnrecognized ? "JNI_TRUE" : "JNI_FALSE");
-        printf("nOptions is %ld\n", (long)args.nOptions);
-        for (i = 0; i < numOptions; i++)
-            printf("    option[%2d] = '%s'\n",
-                   i, args.options[i].optionString);
-    }
-
-    r = ifn->CreateJavaVM(pvm, (void **)penv, &args);
-    JLI_MemFree(options);
-    return r == JNI_OK;
-}
-
-
-#define NULL_CHECK0(e) if ((e) == 0) return 0
-#define NULL_CHECK(e) if ((e) == 0) return
-
-static jstring platformEncoding = NULL;
-static jstring getPlatformEncoding(JNIEnv *env) {
-    if (platformEncoding == NULL) {
-        jstring propname = (*env)->NewStringUTF(env, "sun.jnu.encoding");
-        if (propname) {
-            jclass cls;
-            jmethodID mid;
-            NULL_CHECK0 (cls = (*env)->FindClass(env, "java/lang/System"));
-            NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
-                                   env, cls,
-                                   "getProperty",
-                                   "(Ljava/lang/String;)Ljava/lang/String;"));
-            platformEncoding = (*env)->CallStaticObjectMethod (
-                                    env, cls, mid, propname);
-        }
-    }
-    return platformEncoding;
-}
-
-static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
-    jclass cls;
-    jmethodID mid;
-    NULL_CHECK0 (cls = (*env)->FindClass(env, "java/nio/charset/Charset"));
-    NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
-                           env, cls,
-                           "isSupported",
-                           "(Ljava/lang/String;)Z"));
-    return (*env)->CallStaticBooleanMethod(env, cls, mid, enc);
-}
-
-/*
- * Returns a new Java string object for the specified platform string.
- */
-static jstring
-NewPlatformString(JNIEnv *env, char *s)
-{
-    int len = (int)strlen(s);
-    jclass cls;
-    jmethodID mid;
-    jbyteArray ary;
-    jstring enc;
-
-    if (s == NULL)
-        return 0;
-    enc = getPlatformEncoding(env);
-
-    ary = (*env)->NewByteArray(env, len);
-    if (ary != 0) {
-        jstring str = 0;
-        (*env)->SetByteArrayRegion(env, ary, 0, len, (jbyte *)s);
-        if (!(*env)->ExceptionOccurred(env)) {
-            if (isEncodingSupported(env, enc) == JNI_TRUE) {
-                NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
-                NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
-                                          "([BLjava/lang/String;)V"));
-                str = (*env)->NewObject(env, cls, mid, ary, enc);
-            } else {
-                /*If the encoding specified in sun.jnu.encoding is not
-                  endorsed by "Charset.isSupported" we have to fall back
-                  to use String(byte[]) explicitly here without specifying
-                  the encoding name, in which the StringCoding class will
-                  pickup the iso-8859-1 as the fallback converter for us.
-                */
-                NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
-                NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
-                                          "([B)V"));
-                str = (*env)->NewObject(env, cls, mid, ary);
-            }
-            (*env)->DeleteLocalRef(env, ary);
-            return str;
-        }
-    }
-    return 0;
-}
-
-/*
- * Returns a new array of Java string objects for the specified
- * array of platform strings.
- */
-static jobjectArray
-NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
-{
-    jarray cls;
-    jarray ary;
-    int i;
-
-    NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
-    NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0));
-    for (i = 0; i < strc; i++) {
-        jstring str = NewPlatformString(env, *strv++);
-        NULL_CHECK0(str);
-        (*env)->SetObjectArrayElement(env, ary, i, str);
-        (*env)->DeleteLocalRef(env, str);
-    }
-    return ary;
-}
-
-/*
- * Loads a class, convert the '.' to '/'.
- */
-static jclass
-LoadClass(JNIEnv *env, char *name)
-{
-    char *buf = JLI_MemAlloc(strlen(name) + 1);
-    char *s = buf, *t = name, c;
-    jclass cls;
-    jlong start, end;
-
-    if (_launcher_debug)
-        start = CounterGet();
-
-    do {
-        c = *t++;
-        *s++ = (c == '.') ? '/' : c;
-    } while (c != '\0');
-    cls = (*env)->FindClass(env, buf);
-    JLI_MemFree(buf);
-
-    if (_launcher_debug) {
-        end   = CounterGet();
-        printf("%ld micro seconds to load main class\n",
-               (long)(jint)Counter2Micros(end-start));
-        printf("----_JAVA_LAUNCHER_DEBUG----\n");
-    }
-
-    return cls;
-}
-
-
-/*
- * Returns the main class name for the specified jar file.
- */
-static jstring
-GetMainClassName(JNIEnv *env, char *jarname)
-{
-#define MAIN_CLASS "Main-Class"
-    jclass cls;
-    jmethodID mid;
-    jobject jar, man, attr;
-    jstring str, result = 0;
-
-    NULL_CHECK0(cls = (*env)->FindClass(env, "java/util/jar/JarFile"));
-    NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
-                                          "(Ljava/lang/String;)V"));
-    NULL_CHECK0(str = NewPlatformString(env, jarname));
-    NULL_CHECK0(jar = (*env)->NewObject(env, cls, mid, str));
-    NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "getManifest",
-                                          "()Ljava/util/jar/Manifest;"));
-    man = (*env)->CallObjectMethod(env, jar, mid);
-    if (man != 0) {
-        NULL_CHECK0(mid = (*env)->GetMethodID(env,
-                                    (*env)->GetObjectClass(env, man),
-                                    "getMainAttributes",
-                                    "()Ljava/util/jar/Attributes;"));
-        attr = (*env)->CallObjectMethod(env, man, mid);
-        if (attr != 0) {
-            NULL_CHECK0(mid = (*env)->GetMethodID(env,
-                                    (*env)->GetObjectClass(env, attr),
-                                    "getValue",
-                                    "(Ljava/lang/String;)Ljava/lang/String;"));
-            NULL_CHECK0(str = NewPlatformString(env, MAIN_CLASS));
-            result = (*env)->CallObjectMethod(env, attr, mid, str);
-        }
-    }
-    return result;
-}
-
-#ifdef JAVA_ARGS
-static char *java_args[] = JAVA_ARGS;
-static char *app_classpath[] = APP_CLASSPATH;
-
-/*
- * For tools, convert command line args thus:
- *   javac -cp foo:foo/"*" -J-ms32m ...
- *   java -ms32m -cp JLI_WildcardExpandClasspath(foo:foo/"*") ...
- */
-static void
-TranslateApplicationArgs(int *pargc, char ***pargv)
-{
-    const int NUM_ARGS = (sizeof(java_args) / sizeof(char *));
-    int argc = *pargc;
-    char **argv = *pargv;
-    int nargc = argc + NUM_ARGS;
-    char **nargv = JLI_MemAlloc((nargc + 1) * sizeof(char *));
-    int i;
-
-    *pargc = nargc;
-    *pargv = nargv;
-
-    /* Copy the VM arguments (i.e. prefixed with -J) */
-    for (i = 0; i < NUM_ARGS; i++) {
-        char *arg = java_args[i];
-        if (arg[0] == '-' && arg[1] == 'J') {
-            *nargv++ = arg + 2;
-        }
-    }
-
-    for (i = 0; i < argc; i++) {
-        char *arg = argv[i];
-        if (arg[0] == '-' && arg[1] == 'J') {
-            if (arg[2] == '\0') {
-                ReportErrorMessage("Error: the -J option should not be "
-                                   "followed by a space.", JNI_TRUE);
-                exit(1);
-            }
-            *nargv++ = arg + 2;
-        }
-    }
-
-    /* Copy the rest of the arguments */
-    for (i = 0; i < NUM_ARGS; i++) {
-        char *arg = java_args[i];
-        if (arg[0] != '-' || arg[1] != 'J') {
-            *nargv++ = arg;
-        }
-    }
-    for (i = 0; i < argc; i++) {
-        char *arg = argv[i];
-        if (arg[0] == '-') {
-            if (arg[1] == 'J')
-                continue;
-#ifdef EXPAND_CLASSPATH_WILDCARDS
-            if (arg[1] == 'c'
-                && (strcmp(arg, "-cp") == 0 ||
-                    strcmp(arg, "-classpath") == 0)
-                && i < argc - 1) {
-                *nargv++ = arg;
-                *nargv++ = (char *) JLI_WildcardExpandClasspath(argv[i+1]);
-                i++;
-                continue;
-            }
-#endif
-        }
-        *nargv++ = arg;
-    }
-    *nargv = 0;
-}
-
-/*
- * For our tools, we try to add 3 VM options:
- *      -Denv.class.path=<envcp>
- *      -Dapplication.home=<apphome>
- *      -Djava.class.path=<appcp>
- * <envcp>   is the user's setting of CLASSPATH -- for instance the user
- *           tells javac where to find binary classes through this environment
- *           variable.  Notice that users will be able to compile against our
- *           tools classes (sun.tools.javac.Main) only if they explicitly add
- *           tools.jar to CLASSPATH.
- * <apphome> is the directory where the application is installed.
- * <appcp>   is the classpath to where our apps' classfiles are.
- */
-static jboolean
-AddApplicationOptions()
-{
-    const int NUM_APP_CLASSPATH = (sizeof(app_classpath) / sizeof(char *));
-    char *envcp, *appcp, *apphome;
-    char home[MAXPATHLEN]; /* application home */
-    char separator[] = { PATH_SEPARATOR, '\0' };
-    int size, i;
-    int strlenHome;
-
-    {
-        const char *s = getenv("CLASSPATH");
-        if (s) {
-            s = (char *) JLI_WildcardExpandClasspath(s);
-            /* 40 for -Denv.class.path= */
-            envcp = (char *)JLI_MemAlloc(strlen(s) + 40);
-            sprintf(envcp, "-Denv.class.path=%s", s);
-            AddOption(envcp, NULL);
-        }
-    }
-
-    if (!GetApplicationHome(home, sizeof(home))) {
-        ReportErrorMessage("Can't determine application home", JNI_TRUE);
-        return JNI_FALSE;
-    }
-
-    /* 40 for '-Dapplication.home=' */
-    apphome = (char *)JLI_MemAlloc(strlen(home) + 40);
-    sprintf(apphome, "-Dapplication.home=%s", home);
-    AddOption(apphome, NULL);
-
-    /* How big is the application's classpath? */
-    size = 40;                                 /* 40: "-Djava.class.path=" */
-    strlenHome = (int)strlen(home);
-    for (i = 0; i < NUM_APP_CLASSPATH; i++) {
-        size += strlenHome + (int)strlen(app_classpath[i]) + 1; /* 1: separator */
-    }
-    appcp = (char *)JLI_MemAlloc(size + 1);
-    strcpy(appcp, "-Djava.class.path=");
-    for (i = 0; i < NUM_APP_CLASSPATH; i++) {
-        strcat(appcp, home);                    /* c:\program files\myapp */
-        strcat(appcp, app_classpath[i]);        /* \lib\myapp.jar         */
-        strcat(appcp, separator);               /* ;                      */
-    }
-    appcp[strlen(appcp)-1] = '\0';  /* remove trailing path separator */
-    AddOption(appcp, NULL);
-    return JNI_TRUE;
-}
-#endif /* JAVA_ARGS */
-
-/*
- * inject the -Dsun.java.command pseudo property into the args structure
- * this pseudo property is used in the HotSpot VM to expose the
- * Java class name and arguments to the main method to the VM. The
- * HotSpot VM uses this pseudo property to store the Java class name
- * (or jar file name) and the arguments to the class's main method
- * to the instrumentation memory region. The sun.java.command pseudo
- * property is not exported by HotSpot to the Java layer.
- */
-void
-SetJavaCommandLineProp(char *classname, char *jarfile,
-                       int argc, char **argv)
-{
-
-    int i = 0;
-    size_t len = 0;
-    char* javaCommand = NULL;
-    char* dashDstr = "-Dsun.java.command=";
-
-    if (classname == NULL && jarfile == NULL) {
-        /* unexpected, one of these should be set. just return without
-         * setting the property
-         */
-        return;
-    }
-
-    /* if the class name is not set, then use the jarfile name */
-    if (classname == NULL) {
-        classname = jarfile;
-    }
-
-    /* determine the amount of memory to allocate assuming
-     * the individual components will be space separated
-     */
-    len = strlen(classname);
-    for (i = 0; i < argc; i++) {
-        len += strlen(argv[i]) + 1;
-    }
-
-    /* allocate the memory */
-    javaCommand = (char*) JLI_MemAlloc(len + strlen(dashDstr) + 1);
-
-    /* build the -D string */
-    *javaCommand = '\0';
-    strcat(javaCommand, dashDstr);
-    strcat(javaCommand, classname);
-
-    for (i = 0; i < argc; i++) {
-        /* the components of the string are space separated. In
-         * the case of embedded white space, the relationship of
-         * the white space separated components to their true
-         * positional arguments will be ambiguous. This issue may
-         * be addressed in a future release.
-         */
-        strcat(javaCommand, " ");
-        strcat(javaCommand, argv[i]);
-    }
-
-    AddOption(javaCommand, NULL);
-}
-
-/*
- * JVM would like to know if it's created by a standard Sun launcher, or by
- * user native application, the following property indicates the former.
- */
-void SetJavaLauncherProp() {
-  AddOption("-Dsun.java.launcher=" LAUNCHER_TYPE, NULL);
-}
-
-/*
- * Prints the version information from the java.version and other properties.
- */
-static void
-PrintJavaVersion(JNIEnv *env)
-{
-    jclass ver;
-    jmethodID print;
-
-    NULL_CHECK(ver = (*env)->FindClass(env, "sun/misc/Version"));
-    NULL_CHECK(print = (*env)->GetStaticMethodID(env, ver, "print", "()V"));
-
-    (*env)->CallStaticVoidMethod(env, ver, print);
-}
-
-/*
- * Prints default usage message.
- */
-static void
-PrintUsage(void)
-{
-#ifndef GAMMA
-    int i;
-#endif
-
-    fprintf(stdout,
-        "Usage: %s [-options] class [args...]\n"
-        "           (to execute a class)\n"
-        "   or  %s [-options] -jar jarfile [args...]\n"
-        "           (to execute a jar file)\n"
-        "\n"
-        "where options include:\n",
-        progname,
-        progname);
-
-#ifndef GAMMA
-    PrintMachineDependentOptions();
-
-    if ((knownVMs[0].flag == VM_KNOWN) ||
-        (knownVMs[0].flag == VM_IF_SERVER_CLASS)) {
-      fprintf(stdout, "    %s\t  to select the \"%s\" VM\n",
-              knownVMs[0].name, knownVMs[0].name+1);
-    }
-    for (i=1; i<knownVMsCount; i++) {
-        if (knownVMs[i].flag == VM_KNOWN)
-            fprintf(stdout, "    %s\t  to select the \"%s\" VM\n",
-                    knownVMs[i].name, knownVMs[i].name+1);
-    }
-    for (i=1; i<knownVMsCount; i++) {
-        if (knownVMs[i].flag == VM_ALIASED_TO)
-            fprintf(stdout, "    %s\t  is a synonym for "
-                    "the \"%s\" VM  [deprecated]\n",
-                    knownVMs[i].name, knownVMs[i].alias+1);
-    }
-    /* The first known VM is the default */
-    {
-      const char* defaultVM   = knownVMs[0].name+1;
-      const char* punctuation = ".";
-      const char* reason      = "";
-      if ((knownVMs[0].flag == VM_IF_SERVER_CLASS) &&
-          (ServerClassMachine() == JNI_TRUE)) {
-        defaultVM = knownVMs[0].server_class+1;
-        punctuation = ", ";
-        reason = "because you are running on a server-class machine.\n";
-      }
-      fprintf(stdout, "                  The default VM is %s%s\n",
-              defaultVM, punctuation);
-      fprintf(stdout, "                  %s\n",
-              reason);
-    }
-#endif /* ifndef GAMMA */
-
-    fprintf(stdout,
-"    -cp <class search path of directories and zip/jar files>\n"
-"    -classpath <class search path of directories and zip/jar files>\n"
-"                  A %c separated list of directories, JAR archives,\n"
-"                  and ZIP archives to search for class files.\n"
-"    -D<name>=<value>\n"
-"                  set a system property\n"
-"    -verbose[:class|gc|jni]\n"
-"                  enable verbose output\n"
-"    -version      print product version and exit\n"
-"    -version:<value>\n"
-"                  require the specified version to run\n"
-"    -showversion  print product version and continue\n"
-"    -jre-restrict-search | -jre-no-restrict-search\n"
-"                  include/exclude user private JREs in the version search\n"
-"    -? -help      print this help message\n"
-"    -X            print help on non-standard options\n"
-"    -ea[:<packagename>...|:<classname>]\n"
-"    -enableassertions[:<packagename>...|:<classname>]\n"
-"                  enable assertions\n"
-"    -da[:<packagename>...|:<classname>]\n"
-"    -disableassertions[:<packagename>...|:<classname>]\n"
-"                  disable assertions\n"
-"    -esa | -enablesystemassertions\n"
-"                  enable system assertions\n"
-"    -dsa | -disablesystemassertions\n"
-"                  disable system assertions\n"
-"    -agentlib:<libname>[=<options>]\n"
-"                  load native agent library <libname>, e.g. -agentlib:hprof\n"
-"                    see also, -agentlib:jdwp=help and -agentlib:hprof=help\n"
-"    -agentpath:<pathname>[=<options>]\n"
-"                  load native agent library by full pathname\n"
-"    -javaagent:<jarpath>[=<options>]\n"
-"                  load Java programming language agent, see java.lang.instrument\n"
-"    -splash:<imagepath>\n"
-"                  show splash screen with specified image\n"
-
-            ,PATH_SEPARATOR);
-}
-
-/*
- * Print usage message for -X options.
- */
-static jint
-PrintXUsage(const char *jvmpath)
-{
-    /*
-       A 32 bit cushion to prevent buffer overrun, noting that
-       fopen(3C) may fail if the buffer exceeds MAXPATHLEN.
-    */
-    char path[MAXPATHLEN+32];
-    char buf[128];
-    size_t n;
-    FILE *fp;
-    static const char Xusage_txt[] = "/Xusage.txt";
-
-    strcpy(path, jvmpath);
-    /* Note the FILE_SEPARATOR is platform dependent */
-    strcpy(strrchr(path, FILE_SEPARATOR), Xusage_txt);
-    fp = fopen(path, "r");
-    if (fp == 0) {
-        fprintf(stderr, "Can't open %s\n", path);
-        return 1;
-    }
-    while ((n = fread(buf, 1, sizeof(buf), fp)) != 0) {
-        fwrite(buf, 1, n, stdout);
-    }
-    fclose(fp);
-    return 0;
-}
-
-#ifndef GAMMA
-/*
- * Read the jvm.cfg file and fill the knownJVMs[] array.
- *
- * The functionality of the jvm.cfg file is subject to change without
- * notice and the mechanism will be removed in the future.
- *
- * The lexical structure of the jvm.cfg file is as follows:
- *
- *     jvmcfg         :=  { vmLine }
- *     vmLine         :=  knownLine
- *                    |   aliasLine
- *                    |   warnLine
- *                    |   ignoreLine
- *                    |   errorLine
- *                    |   predicateLine
- *                    |   commentLine
- *     knownLine      :=  flag  "KNOWN"                  EOL
- *     warnLine       :=  flag  "WARN"                   EOL
- *     ignoreLine     :=  flag  "IGNORE"                 EOL
- *     errorLine      :=  flag  "ERROR"                  EOL
- *     aliasLine      :=  flag  "ALIASED_TO"       flag  EOL
- *     predicateLine  :=  flag  "IF_SERVER_CLASS"  flag  EOL
- *     commentLine    :=  "#" text                       EOL
- *     flag           :=  "-" identifier
- *
- * The semantics are that when someone specifies a flag on the command line:
- * - if the flag appears on a knownLine, then the identifier is used as
- *   the name of the directory holding the JVM library (the name of the JVM).
- * - if the flag appears as the first flag on an aliasLine, the identifier
- *   of the second flag is used as the name of the JVM.
- * - if the flag appears on a warnLine, the identifier is used as the
- *   name of the JVM, but a warning is generated.
- * - if the flag appears on an ignoreLine, the identifier is recognized as the
- *   name of a JVM, but the identifier is ignored and the default vm used
- * - if the flag appears on an errorLine, an error is generated.
- * - if the flag appears as the first flag on a predicateLine, and
- *   the machine on which you are running passes the predicate indicated,
- *   then the identifier of the second flag is used as the name of the JVM,
- *   otherwise the identifier of the first flag is used as the name of the JVM.
- * If no flag is given on the command line, the first vmLine of the jvm.cfg
- * file determines the name of the JVM.
- * PredicateLines are only interpreted on first vmLine of a jvm.cfg file,
- * since they only make sense if someone hasn't specified the name of the
- * JVM on the command line.
- *
- * The intent of the jvm.cfg file is to allow several JVM libraries to
- * be installed in different subdirectories of a single JRE installation,
- * for space-savings and convenience in testing.
- * The intent is explicitly not to provide a full aliasing or predicate
- * mechanism.
- */
-jint
-ReadKnownVMs(const char *jrepath, char * arch, jboolean speculative)
-{
-    FILE *jvmCfg;
-    char jvmCfgName[MAXPATHLEN+20];
-    char line[MAXPATHLEN+20];
-    int cnt = 0;
-    int lineno = 0;
-    jlong start, end;
-    int vmType;
-    char *tmpPtr;
-    char *altVMName = NULL;
-    char *serverClassVMName = NULL;
-    static char *whiteSpace = " \t";
-    if (_launcher_debug) {
-        start = CounterGet();
-    }
-
-    strcpy(jvmCfgName, jrepath);
-    strcat(jvmCfgName, FILESEP "lib" FILESEP);
-    strcat(jvmCfgName, arch);
-    strcat(jvmCfgName, FILESEP "jvm.cfg");
-
-    jvmCfg = fopen(jvmCfgName, "r");
-    if (jvmCfg == NULL) {
-      if (!speculative) {
-        ReportErrorMessage2("Error: could not open `%s'", jvmCfgName,
-                            JNI_TRUE);
-        exit(1);
-      } else {
-        return -1;
-      }
-    }
-    while (fgets(line, sizeof(line), jvmCfg) != NULL) {
-        vmType = VM_UNKNOWN;
-        lineno++;
-        if (line[0] == '#')
-            continue;
-        if (line[0] != '-') {
-            fprintf(stderr, "Warning: no leading - on line %d of `%s'\n",
-                    lineno, jvmCfgName);
-        }
-        if (cnt >= knownVMsLimit) {
-            GrowKnownVMs(cnt);
-        }
-        line[strlen(line)-1] = '\0'; /* remove trailing newline */
-        tmpPtr = line + strcspn(line, whiteSpace);
-        if (*tmpPtr == 0) {
-            fprintf(stderr, "Warning: missing VM type on line %d of `%s'\n",
-                    lineno, jvmCfgName);
-        } else {
-            /* Null-terminate this string for JLI_StringDup below */
-            *tmpPtr++ = 0;
-            tmpPtr += strspn(tmpPtr, whiteSpace);
-            if (*tmpPtr == 0) {
-                fprintf(stderr, "Warning: missing VM type on line %d of `%s'\n",
-                        lineno, jvmCfgName);
-            } else {
-                if (!strncmp(tmpPtr, "KNOWN", strlen("KNOWN"))) {
-                    vmType = VM_KNOWN;
-                } else if (!strncmp(tmpPtr, "ALIASED_TO", strlen("ALIASED_TO"))) {
-                    tmpPtr += strcspn(tmpPtr, whiteSpace);
-                    if (*tmpPtr != 0) {
-                        tmpPtr += strspn(tmpPtr, whiteSpace);
-                    }
-                    if (*tmpPtr == 0) {
-                        fprintf(stderr, "Warning: missing VM alias on line %d of `%s'\n",
-                                lineno, jvmCfgName);
-                    } else {
-                        /* Null terminate altVMName */
-                        altVMName = tmpPtr;
-                        tmpPtr += strcspn(tmpPtr, whiteSpace);
-                        *tmpPtr = 0;
-                        vmType = VM_ALIASED_TO;
-                    }
-                } else if (!strncmp(tmpPtr, "WARN", strlen("WARN"))) {
-                    vmType = VM_WARN;
-                } else if (!strncmp(tmpPtr, "IGNORE", strlen("IGNORE"))) {
-                    vmType = VM_IGNORE;
-                } else if (!strncmp(tmpPtr, "ERROR", strlen("ERROR"))) {
-                    vmType = VM_ERROR;
-                } else if (!strncmp(tmpPtr,
-                                    "IF_SERVER_CLASS",
-                                    strlen("IF_SERVER_CLASS"))) {
-                    tmpPtr += strcspn(tmpPtr, whiteSpace);
-                    if (*tmpPtr != 0) {
-                        tmpPtr += strspn(tmpPtr, whiteSpace);
-                    }
-                    if (*tmpPtr == 0) {
-                        fprintf(stderr, "Warning: missing server class VM on line %d of `%s'\n",
-                                lineno, jvmCfgName);
-                    } else {
-                        /* Null terminate server class VM name */
-                        serverClassVMName = tmpPtr;
-                        tmpPtr += strcspn(tmpPtr, whiteSpace);
-                        *tmpPtr = 0;
-                        vmType = VM_IF_SERVER_CLASS;
-                    }
-                } else {
-                    fprintf(stderr, "Warning: unknown VM type on line %d of `%s'\n",
-                            lineno, &jvmCfgName[0]);
-                    vmType = VM_KNOWN;
-                }
-            }
-        }
-
-        if (_launcher_debug)
-            printf("jvm.cfg[%d] = ->%s<-\n", cnt, line);
-        if (vmType != VM_UNKNOWN) {
-            knownVMs[cnt].name = JLI_StringDup(line);
-            knownVMs[cnt].flag = vmType;
-            switch (vmType) {
-            default:
-                break;
-            case VM_ALIASED_TO:
-                knownVMs[cnt].alias = JLI_StringDup(altVMName);
-                if (_launcher_debug) {
-                    printf("    name: %s  vmType: %s  alias: %s\n",
-                           knownVMs[cnt].name, "VM_ALIASED_TO", knownVMs[cnt].alias);
-                }
-                break;
-            case VM_IF_SERVER_CLASS:
-                knownVMs[cnt].server_class = JLI_StringDup(serverClassVMName);
-                if (_launcher_debug) {
-                    printf("    name: %s  vmType: %s  server_class: %s\n",
-                           knownVMs[cnt].name, "VM_IF_SERVER_CLASS", knownVMs[cnt].server_class);
-                }
-                break;
-            }
-            cnt++;
-        }
-    }
-    fclose(jvmCfg);
-    knownVMsCount = cnt;
-
-    if (_launcher_debug) {
-        end   = CounterGet();
-        printf("%ld micro seconds to parse jvm.cfg\n",
-               (long)(jint)Counter2Micros(end-start));
-    }
-
-    return cnt;
-}
-
-
-static void
-GrowKnownVMs(int minimum)
-{
-    struct vmdesc* newKnownVMs;
-    int newMax;
-
-    newMax = (knownVMsLimit == 0 ? INIT_MAX_KNOWN_VMS : (2 * knownVMsLimit));
-    if (newMax <= minimum) {
-        newMax = minimum;
-    }
-    newKnownVMs = (struct vmdesc*) JLI_MemAlloc(newMax * sizeof(struct vmdesc));
-    if (knownVMs != NULL) {
-        memcpy(newKnownVMs, knownVMs, knownVMsLimit * sizeof(struct vmdesc));
-    }
-    JLI_MemFree(knownVMs);
-    knownVMs = newKnownVMs;
-    knownVMsLimit = newMax;
-}
-
-
-/* Returns index of VM or -1 if not found */
-static int
-KnownVMIndex(const char* name)
-{
-    int i;
-    if (strncmp(name, "-J", 2) == 0) name += 2;
-    for (i = 0; i < knownVMsCount; i++) {
-        if (!strcmp(name, knownVMs[i].name)) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-static void
-FreeKnownVMs()
-{
-    int i;
-    for (i = 0; i < knownVMsCount; i++) {
-        JLI_MemFree(knownVMs[i].name);
-        knownVMs[i].name = NULL;
-    }
-    JLI_MemFree(knownVMs);
-}
-
-
-/*
- * Displays the splash screen according to the jar file name
- * and image file names stored in environment variables
- */
-static void
-ShowSplashScreen()
-{
-    const char *jar_name = getenv(SPLASH_JAR_ENV_ENTRY);
-    const char *file_name = getenv(SPLASH_FILE_ENV_ENTRY);
-    int data_size;
-    void *image_data;
-    if (jar_name) {
-        image_data = JLI_JarUnpackFile(jar_name, file_name, &data_size);
-        if (image_data) {
-            DoSplashInit();
-            DoSplashLoadMemory(image_data, data_size);
-            JLI_MemFree(image_data);
-        }
-    } else if (file_name) {
-        DoSplashInit();
-        DoSplashLoadFile(file_name);
-    } else {
-        return;
-    }
-    DoSplashSetFileJarName(file_name, jar_name);
-}
-
-#endif /* ifndef GAMMA */
diff --git a/hotspot/src/share/tools/launcher/java.h b/hotspot/src/share/tools/launcher/java.h
deleted file mode 100644
index 1dd7961..0000000
--- a/hotspot/src/share/tools/launcher/java.h
+++ /dev/null
@@ -1,110 +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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-
-#ifndef _JAVA_H_
-#define _JAVA_H_
-
-/*
- * Get system specific defines.
- */
-#include "jni.h"
-#include "java_md.h"
-#include "jli_util.h"
-
-/*
- * Pointers to the needed JNI invocation API, initialized by LoadJavaVM.
- */
-typedef jint (JNICALL *CreateJavaVM_t)(JavaVM **pvm, void **env, void *args);
-typedef jint (JNICALL *GetDefaultJavaVMInitArgs_t)(void *args);
-
-typedef struct {
-    CreateJavaVM_t CreateJavaVM;
-    GetDefaultJavaVMInitArgs_t GetDefaultJavaVMInitArgs;
-} InvocationFunctions;
-
-/*
- * Prototypes for launcher functions in the system specific java_md.c.
- */
-
-jboolean
-LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn);
-
-void
-GetXUsagePath(char *buf, jint bufsize);
-
-jboolean
-GetApplicationHome(char *buf, jint bufsize);
-
-const char *
-GetArch();
-
-void CreateExecutionEnvironment(int *_argc,
-                                       char ***_argv,
-                                       char jrepath[],
-                                       jint so_jrepath,
-                                       char jvmpath[],
-                                       jint so_jvmpath,
-                                       char **original_argv);
-
-/*
- * Report an error message to stderr or a window as appropriate.  The
- * flag always is set to JNI_TRUE if message is to be reported to both
- * strerr and windows and set to JNI_FALSE if the message should only
- * be sent to a window.
- */
-void ReportErrorMessage(char * message, jboolean always);
-void ReportErrorMessage2(char * format, char * string, jboolean always);
-
-/*
- * Report an exception which terminates the vm to stderr or a window
- * as appropriate.
- */
-void ReportExceptionDescription(JNIEnv * env);
-
-jboolean RemovableMachineDependentOption(char * option);
-void PrintMachineDependentOptions();
-
-/*
- * Block current thread and continue execution in new thread
- */
-int ContinueInNewThread(int (JNICALL *continuation)(void *),
-                        jlong stack_size, void * args);
-
-/* sun.java.launcher.* platform properties. */
-void SetJavaLauncherPlatformProps(void);
-
-/*
- * Functions defined in java.c and used in java_md.c.
- */
-jint ReadKnownVMs(const char *jrepath, char * arch, jboolean speculative);
-char *CheckJvmType(int *argc, char ***argv, jboolean speculative);
-void AddOption(char *str, void *info);
-
-/*
- * Make launcher spit debug output.
- */
-extern jboolean _launcher_debug;
-
-#endif /* _JAVA_H_ */
diff --git a/hotspot/src/share/tools/launcher/jli_util.c b/hotspot/src/share/tools/launcher/jli_util.c
deleted file mode 100644
index 36b164e..0000000
--- a/hotspot/src/share/tools/launcher/jli_util.c
+++ /dev/null
@@ -1,89 +0,0 @@
-
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "jli_util.h"
-
-#ifdef GAMMA
-#ifdef TARGET_OS_FAMILY_windows
-#define strdup _strdup
-#endif
-#endif
-
-/*
- * Returns a pointer to a block of at least 'size' bytes of memory.
- * Prints error message and exits if the memory could not be allocated.
- */
-void *
-JLI_MemAlloc(size_t size)
-{
-    void *p = malloc(size);
-    if (p == 0) {
-        perror("malloc");
-        exit(1);
-    }
-    return p;
-}
-
-/*
- * Equivalent to realloc(size).
- * Prints error message and exits if the memory could not be reallocated.
- */
-void *
-JLI_MemRealloc(void *ptr, size_t size)
-{
-    void *p = realloc(ptr, size);
-    if (p == 0) {
-        perror("realloc");
-        exit(1);
-    }
-    return p;
-}
-
-/*
- * Wrapper over strdup(3C) which prints an error message and exits if memory
- * could not be allocated.
- */
-char *
-JLI_StringDup(const char *s1)
-{
-    char *s = strdup(s1);
-    if (s == NULL) {
-        perror("strdup");
-        exit(1);
-    }
-    return s;
-}
-
-/*
- * Very equivalent to free(ptr).
- * Here to maintain pairing with the above routines.
- */
-void
-JLI_MemFree(void *ptr)
-{
-    free(ptr);
-}
diff --git a/hotspot/src/share/tools/launcher/wildcard.c b/hotspot/src/share/tools/launcher/wildcard.c
deleted file mode 100644
index 8b3cbcd..0000000
--- a/hotspot/src/share/tools/launcher/wildcard.c
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-/*
- * Class-Path Wildcards
- *
- * The syntax for wildcards is a single asterisk. The class path
- * foo/"*", e.g., loads all jar files in the directory named foo.
- * (This requires careful quotation when used in shell scripts.)
- *
- * Only files whose names end in .jar or .JAR are matched.
- * Files whose names end in .zip, or which have a particular
- * magic number, regardless of filename extension, are not
- * matched.
- *
- * Files are considered regardless of whether or not they are
- * "hidden" in the UNIX sense, i.e., have names beginning with '.'.
- *
- * A wildcard only matches jar files, not class files in the same
- * directory.  If you want to load both class files and jar files from
- * a single directory foo then you can say foo:foo/"*", or foo/"*":foo
- * if you want the jar files to take precedence.
- *
- * Subdirectories are not searched recursively, i.e., foo/"*" only
- * looks for jar files in foo, not in foo/bar, foo/baz, etc.
- *
- * Expansion of wildcards is done early, prior to the invocation of a
- * program's main method, rather than late, during the class-loading
- * process itself.  Each element of the input class path containing a
- * wildcard is replaced by the (possibly empty) sequence of elements
- * generated by enumerating the jar files in the named directory.  If
- * the directory foo contains a.jar, b.jar, and c.jar,
- * e.g., then the class path foo/"*" is expanded into
- * foo/a.jar:foo/b.jar:foo/c.jar, and that string would be the value
- * of the system property java.class.path.
- *
- * The order in which the jar files in a directory are enumerated in
- * the expanded class path is not specified and may vary from platform
- * to platform and even from moment to moment on the same machine.  A
- * well-constructed application should not depend upon any particular
- * order.  If a specific order is required then the jar files can be
- * enumerated explicitly in the class path.
- *
- * The CLASSPATH environment variable is not treated any differently
- * from the -classpath (equiv. -cp) command-line option,
- * i.e. wildcards are honored in all these cases.
- *
- * Class-path wildcards are not honored in the Class-Path jar-manifest
- * header.
- *
- * Class-path wildcards are honored not only by the Java launcher but
- * also by most other command-line tools that accept class paths, and
- * in particular by javac and javadoc.
- *
- * Class-path wildcards are not honored in any other kind of path, and
- * especially not in the bootstrap class path, which is a mere
- * artifact of our implementation and not something that developers
- * should use.
- *
- * Classpath wildcards are only expanded in the Java launcher code,
- * supporting the use of wildcards on the command line and in the
- * CLASSPATH environment variable.  We do not support the use of
- * wildcards by applications that embed the JVM.
- */
-
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include "java.h"       /* Strictly for PATH_SEPARATOR/FILE_SEPARATOR */
-#include "jli_util.h"
-
-#ifdef _WIN32
-#include <windows.h>
-#else /* Unix */
-#include <unistd.h>
-#include <dirent.h>
-#endif /* Unix */
-
-static int
-exists(const char* filename)
-{
-#ifdef _WIN32
-    return _access(filename, 0) == 0;
-#else
-    return access(filename, F_OK) == 0;
-#endif
-}
-
-#define NEW_(TYPE) ((TYPE) JLI_MemAlloc(sizeof(struct TYPE##_)))
-
-/*
- * Wildcard directory iteration.
- * WildcardIterator_for(wildcard) returns an iterator.
- * Each call to that iterator's next() method returns the basename
- * of an entry in the wildcard's directory.  The basename's memory
- * belongs to the iterator.  The caller is responsible for prepending
- * the directory name and file separator, if necessary.
- * When done with the iterator, call the close method to clean up.
- */
-typedef struct WildcardIterator_* WildcardIterator;
-
-#ifdef _WIN32
-struct WildcardIterator_
-{
-    HANDLE handle;
-    char *firstFile; /* Stupid FindFirstFile...FindNextFile */
-};
-
-static WildcardIterator
-WildcardIterator_for(const char *wildcard)
-{
-    WIN32_FIND_DATA find_data;
-    WildcardIterator it = NEW_(WildcardIterator);
-    HANDLE handle = FindFirstFile(wildcard, &find_data);
-    if (handle == INVALID_HANDLE_VALUE)
-        return NULL;
-    it->handle = handle;
-    it->firstFile = find_data.cFileName;
-    return it;
-}
-
-static char *
-WildcardIterator_next(WildcardIterator it)
-{
-    WIN32_FIND_DATA find_data;
-    if (it->firstFile != NULL) {
-        char *firstFile = it->firstFile;
-        it->firstFile = NULL;
-        return firstFile;
-    }
-    return FindNextFile(it->handle, &find_data)
-        ? find_data.cFileName : NULL;
-}
-
-static void
-WildcardIterator_close(WildcardIterator it)
-{
-    if (it) {
-        FindClose(it->handle);
-        JLI_MemFree(it->firstFile);
-        JLI_MemFree(it);
-    }
-}
-
-#else /* Unix */
-struct WildcardIterator_
-{
-    DIR *dir;
-};
-
-static WildcardIterator
-WildcardIterator_for(const char *wildcard)
-{
-    DIR *dir;
-    int wildlen = strlen(wildcard);
-    if (wildlen < 2) {
-        dir = opendir(".");
-    } else {
-        char *dirname = JLI_StringDup(wildcard);
-        dirname[wildlen - 1] = '\0';
-        dir = opendir(dirname);
-        JLI_MemFree(dirname);
-    }
-    if (dir == NULL)
-        return NULL;
-    else {
-        WildcardIterator it = NEW_(WildcardIterator);
-        it->dir = dir;
-        return it;
-    }
-}
-
-static char *
-WildcardIterator_next(WildcardIterator it)
-{
-    struct dirent* dirp = readdir(it->dir);
-    return dirp ? dirp->d_name : NULL;
-}
-
-static void
-WildcardIterator_close(WildcardIterator it)
-{
-    if (it) {
-        closedir(it->dir);
-        JLI_MemFree(it);
-    }
-}
-#endif /* Unix */
-
-static int
-equal(const char *s1, const char *s2)
-{
-    return strcmp(s1, s2) == 0;
-}
-
-/*
- * FileList ADT - a dynamic list of C filenames
- */
-struct FileList_
-{
-    char **files;
-    int size;
-    int capacity;
-};
-typedef struct FileList_ *FileList;
-
-static FileList
-FileList_new(int capacity)
-{
-    FileList fl = NEW_(FileList);
-    fl->capacity = capacity;
-    fl->files = (char **) JLI_MemAlloc(capacity * sizeof(fl->files[0]));
-    fl->size = 0;
-    return fl;
-}
-
-#ifdef DEBUG_WILDCARD
-static void
-FileList_print(FileList fl)
-{
-    int i;
-    putchar('[');
-    for (i = 0; i < fl->size; i++) {
-        if (i > 0) printf(", ");
-        printf("\"%s\"",fl->files[i]);
-    }
-    putchar(']');
-}
-#endif
-
-static void
-FileList_free(FileList fl)
-{
-    if (fl) {
-        if (fl->files) {
-            int i;
-            for (i = 0; i < fl->size; i++)
-                JLI_MemFree(fl->files[i]);
-            JLI_MemFree(fl->files);
-        }
-        JLI_MemFree(fl);
-    }
-}
-
-static void
-FileList_ensureCapacity(FileList fl, int capacity)
-{
-    if (fl->capacity < capacity) {
-        while (fl->capacity < capacity)
-            fl->capacity *= 2;
-        fl->files = JLI_MemRealloc(fl->files,
-                               fl->capacity * sizeof(fl->files[0]));
-    }
-}
-
-static void
-FileList_add(FileList fl, char *file)
-{
-    FileList_ensureCapacity(fl, fl->size+1);
-    fl->files[fl->size++] = file;
-}
-
-static void
-FileList_addSubstring(FileList fl, const char *beg, int len)
-{
-    char *filename = (char *) JLI_MemAlloc(len+1);
-    memcpy(filename, beg, len);
-    filename[len] = '\0';
-    FileList_ensureCapacity(fl, fl->size+1);
-    fl->files[fl->size++] = filename;
-}
-
-static char *
-FileList_join(FileList fl, char sep)
-{
-    int i;
-    int size;
-    char *path;
-    char *p;
-    for (i = 0, size = 1; i < fl->size; i++)
-        size += strlen(fl->files[i]) + 1;
-
-    path = JLI_MemAlloc(size);
-
-    for (i = 0, p = path; i < fl->size; i++) {
-        int len = strlen(fl->files[i]);
-        if (i > 0) *p++ = sep;
-        memcpy(p, fl->files[i], len);
-        p += len;
-    }
-    *p = '\0';
-
-    return path;
-}
-
-static FileList
-FileList_split(const char *path, char sep)
-{
-    const char *p, *q;
-    int len = strlen(path);
-    int count;
-    FileList fl;
-    for (count = 1, p = path; p < path + len; p++)
-        count += (*p == sep);
-    fl = FileList_new(count);
-    for (p = path;;) {
-        for (q = p; q <= path + len; q++) {
-            if (*q == sep || *q == '\0') {
-                FileList_addSubstring(fl, p, q - p);
-                if (*q == '\0')
-                    return fl;
-                p = q + 1;
-            }
-        }
-    }
-}
-
-static int
-isJarFileName(const char *filename)
-{
-    int len = strlen(filename);
-    return (len >= 4) &&
-        (filename[len - 4] == '.') &&
-        (equal(filename + len - 3, "jar") ||
-         equal(filename + len - 3, "JAR")) &&
-        /* Paranoia: Maybe filename is "DIR:foo.jar" */
-        (strchr(filename, PATH_SEPARATOR) == NULL);
-}
-
-static char *
-wildcardConcat(const char *wildcard, const char *basename)
-{
-    int wildlen = strlen(wildcard);
-    int baselen = strlen(basename);
-    char *filename = (char *) JLI_MemAlloc(wildlen + baselen);
-    /* Replace the trailing '*' with basename */
-    memcpy(filename, wildcard, wildlen-1);
-    memcpy(filename+wildlen-1, basename, baselen+1);
-    return filename;
-}
-
-static FileList
-wildcardFileList(const char *wildcard)
-{
-    const char *basename;
-    FileList fl = FileList_new(16);
-    WildcardIterator it = WildcardIterator_for(wildcard);
-    if (it == NULL) {
-        FileList_free(fl);
-        return NULL;
-    }
-    while ((basename = WildcardIterator_next(it)) != NULL)
-        if (isJarFileName(basename))
-            FileList_add(fl, wildcardConcat(wildcard, basename));
-    WildcardIterator_close(it);
-    return fl;
-}
-
-static int
-isWildcard(const char *filename)
-{
-    int len = strlen(filename);
-    return (len > 0) &&
-        (filename[len - 1] == '*') &&
-        (len == 1 || IS_FILE_SEPARATOR(filename[len - 2])) &&
-        (! exists(filename));
-}
-
-static void
-FileList_expandWildcards(FileList fl)
-{
-    int i, j;
-    for (i = 0; i < fl->size; i++) {
-        if (isWildcard(fl->files[i])) {
-            FileList expanded = wildcardFileList(fl->files[i]);
-            if (expanded != NULL && expanded->size > 0) {
-                JLI_MemFree(fl->files[i]);
-                FileList_ensureCapacity(fl, fl->size + expanded->size);
-                for (j = fl->size - 1; j >= i+1; j--)
-                    fl->files[j+expanded->size-1] = fl->files[j];
-                for (j = 0; j < expanded->size; j++)
-                    fl->files[i+j] = expanded->files[j];
-                i += expanded->size - 1;
-                fl->size += expanded->size - 1;
-                /* fl expropriates expanded's elements. */
-                expanded->size = 0;
-            }
-            FileList_free(expanded);
-        }
-    }
-}
-
-const char *
-JLI_WildcardExpandClasspath(const char *classpath)
-{
-    char *expanded;
-    FileList fl;
-
-    if (strchr(classpath, '*') == NULL)
-        return classpath;
-    fl = FileList_split(classpath, PATH_SEPARATOR);
-    FileList_expandWildcards(fl);
-    expanded = FileList_join(fl, PATH_SEPARATOR);
-    FileList_free(fl);
-    if (getenv("_JAVA_LAUNCHER_DEBUG") != 0)
-        printf("Expanded wildcards:\n"
-               "    before: \"%s\"\n"
-               "    after : \"%s\"\n",
-               classpath, expanded);
-    return expanded;
-}
-
-#ifdef DEBUG_WILDCARD
-static void
-wildcardExpandArgv(const char ***argv)
-{
-    int i;
-    for (i = 0; (*argv)[i]; i++) {
-        if (equal((*argv)[i], "-cp") ||
-            equal((*argv)[i], "-classpath")) {
-            i++;
-            (*argv)[i] = wildcardExpandClasspath((*argv)[i]);
-        }
-    }
-}
-
-static void
-debugPrintArgv(char *argv[])
-{
-    int i;
-    putchar('[');
-    for (i = 0; argv[i]; i++) {
-        if (i > 0) printf(", ");
-        printf("\"%s\"", argv[i]);
-    }
-    printf("]\n");
-}
-
-int
-main(int argc, char *argv[])
-{
-    argv[0] = "java";
-    wildcardExpandArgv((const char***)&argv);
-    debugPrintArgv(argv);
-    /* execvp("java", argv); */
-    return 0;
-}
-#endif /* DEBUG_WILDCARD */
-
-/* Cute little perl prototype implementation....
-
-my $sep = ($^O =~ /^(Windows|cygwin)/) ? ";" : ":";
-
-sub expand($) {
-  opendir DIR, $_[0] or return $_[0];
-  join $sep, map {"$_[0]/$_"} grep {/\.(jar|JAR)$/} readdir DIR;
-}
-
-sub munge($) {
-  join $sep,
-    map {(! -r $_ and s/[\/\\]+\*$//) ? expand $_ : $_} split $sep, $_[0];
-}
-
-for (my $i = 0; $i < @ARGV - 1; $i++) {
-  $ARGV[$i+1] = munge $ARGV[$i+1] if $ARGV[$i] =~ /^-c(p|lasspath)$/;
-}
-
-$ENV{CLASSPATH} = munge $ENV{CLASSPATH} if exists $ENV{CLASSPATH};
-@ARGV = ("java", @ARGV);
-print "@ARGV\n";
-exec @ARGV;
-
-*/
diff --git a/hotspot/src/share/tools/launcher/wildcard.h b/hotspot/src/share/tools/launcher/wildcard.h
deleted file mode 100644
index 5cdd931..0000000
--- a/hotspot/src/share/tools/launcher/wildcard.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef WILDCARD_H_
-#define WILDCARD_H_
-
-#ifdef EXPAND_CLASSPATH_WILDCARDS
-const char *JLI_WildcardExpandClasspath(const char *classpath);
-#else
-#define JLI_WildcardExpandClasspath(s) (s)
-#endif
-
-#endif /* include guard */
diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp
index e274076..53d1f53 100644
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -1261,7 +1261,7 @@
 
   if (length == 0) return ac_ok;
   if (src->is_typeArray()) {
-    Klass* const klass_oop = src->klass();
+    Klass* klass_oop = src->klass();
     if (klass_oop != dst->klass()) return ac_failed;
     TypeArrayKlass* klass = TypeArrayKlass::cast(klass_oop);
     const int l2es = klass->log2_element_size();
diff --git a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp
index d74e369..d74e484 100644
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp
@@ -211,13 +211,42 @@
 
 // ------------------------------------------------------------------
 // ciInstanceKlass::uses_default_loader
-bool ciInstanceKlass::uses_default_loader() {
+bool ciInstanceKlass::uses_default_loader() const {
   // Note:  We do not need to resolve the handle or enter the VM
   // in order to test null-ness.
   return _loader == NULL;
 }
 
 // ------------------------------------------------------------------
+
+/**
+ * Return basic type of boxed value for box klass or T_OBJECT if not.
+ */
+BasicType ciInstanceKlass::box_klass_type() const {
+  if (uses_default_loader() && is_loaded()) {
+    return SystemDictionary::box_klass_type(get_Klass());
+  } else {
+    return T_OBJECT;
+  }
+}
+
+/**
+ * Is this boxing klass?
+ */
+bool ciInstanceKlass::is_box_klass() const {
+  return is_java_primitive(box_klass_type());
+}
+
+/**
+ *  Is this boxed value offset?
+ */
+bool ciInstanceKlass::is_boxed_value_offset(int offset) const {
+  BasicType bt = box_klass_type();
+  return is_java_primitive(bt) &&
+         (offset == java_lang_boxing_object::value_offset_in_bytes(bt));
+}
+
+// ------------------------------------------------------------------
 // ciInstanceKlass::is_in_package
 //
 // Is this klass in the given package?
diff --git a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp
index f7aeba2..0b244a2 100644
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp
@@ -217,10 +217,14 @@
   ciInstanceKlass* implementor();
 
   // Is the defining class loader of this class the default loader?
-  bool uses_default_loader();
+  bool uses_default_loader() const;
 
   bool is_java_lang_Object() const;
 
+  BasicType box_klass_type() const;
+  bool is_box_klass() const;
+  bool is_boxed_value_offset(int offset) const;
+
   // Is this klass in the given package?
   bool is_in_package(const char* packagename) {
     return is_in_package(packagename, (int) strlen(packagename));
diff --git a/hotspot/src/share/vm/ci/ciMethod.cpp b/hotspot/src/share/vm/ci/ciMethod.cpp
index 780f4ad..d036325 100644
--- a/hotspot/src/share/vm/ci/ciMethod.cpp
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp
@@ -1179,6 +1179,44 @@
 bool ciMethod::is_accessor    () const {         FETCH_FLAG_FROM_VM(is_accessor); }
 bool ciMethod::is_initializer () const {         FETCH_FLAG_FROM_VM(is_initializer); }
 
+bool ciMethod::is_boxing_method() const {
+  if (holder()->is_box_klass()) {
+    switch (intrinsic_id()) {
+      case vmIntrinsics::_Boolean_valueOf:
+      case vmIntrinsics::_Byte_valueOf:
+      case vmIntrinsics::_Character_valueOf:
+      case vmIntrinsics::_Short_valueOf:
+      case vmIntrinsics::_Integer_valueOf:
+      case vmIntrinsics::_Long_valueOf:
+      case vmIntrinsics::_Float_valueOf:
+      case vmIntrinsics::_Double_valueOf:
+        return true;
+      default:
+        return false;
+    }
+  }
+  return false;
+}
+
+bool ciMethod::is_unboxing_method() const {
+  if (holder()->is_box_klass()) {
+    switch (intrinsic_id()) {
+      case vmIntrinsics::_booleanValue:
+      case vmIntrinsics::_byteValue:
+      case vmIntrinsics::_charValue:
+      case vmIntrinsics::_shortValue:
+      case vmIntrinsics::_intValue:
+      case vmIntrinsics::_longValue:
+      case vmIntrinsics::_floatValue:
+      case vmIntrinsics::_doubleValue:
+        return true;
+      default:
+        return false;
+    }
+  }
+  return false;
+}
+
 BCEscapeAnalyzer  *ciMethod::get_bcea() {
 #ifdef COMPILER2
   if (_bcea == NULL) {
diff --git a/hotspot/src/share/vm/ci/ciMethod.hpp b/hotspot/src/share/vm/ci/ciMethod.hpp
index 46ea500..8305547 100644
--- a/hotspot/src/share/vm/ci/ciMethod.hpp
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp
@@ -298,6 +298,8 @@
   bool is_initializer () const;
   bool can_be_statically_bound() const           { return _can_be_statically_bound; }
   void dump_replay_data(outputStream* st);
+  bool is_boxing_method() const;
+  bool is_unboxing_method() const;
 
   // Print the bytecodes of this method.
   void print_codes_on(outputStream* st);
diff --git a/hotspot/src/share/vm/ci/ciReplay.cpp b/hotspot/src/share/vm/ci/ciReplay.cpp
index a314f35..71813b8 100644
--- a/hotspot/src/share/vm/ci/ciReplay.cpp
+++ b/hotspot/src/share/vm/ci/ciReplay.cpp
@@ -492,7 +492,9 @@
       }
       Klass* k = parse_klass(CHECK);
       rec->oops_offsets[i] = offset;
-      rec->oops_handles[i] = (jobject)(new KlassHandle(THREAD, k));
+      KlassHandle *kh = NEW_C_HEAP_OBJ(KlassHandle, mtCompiler);
+      ::new ((void*)kh) KlassHandle(THREAD, k);
+      rec->oops_handles[i] = (jobject)kh;
     }
   }
 
diff --git a/hotspot/src/share/vm/classfile/altHashing.cpp b/hotspot/src/share/vm/classfile/altHashing.cpp
index df2c53e..8dfc315 100644
--- a/hotspot/src/share/vm/classfile/altHashing.cpp
+++ b/hotspot/src/share/vm/classfile/altHashing.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -242,8 +242,8 @@
 void AltHashing::testMurmur3_32_ByteArray() {
   // printf("testMurmur3_32_ByteArray\n");
 
-  jbyte* vector = new jbyte[256];
-  jbyte* hashes = new jbyte[4 * 256];
+  jbyte vector[256];
+  jbyte hashes[4 * 256];
 
   for (int i = 0; i < 256; i++) {
     vector[i] = (jbyte) i;
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
index c93d72d..19aaa8b 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
@@ -3028,7 +3028,7 @@
 }
 
 
-#ifndef PRODUCT
+#ifdef ASSERT
 static void parseAndPrintGenericSignatures(
     instanceKlassHandle this_klass, TRAPS) {
   assert(ParseAllGenericSignatures == true, "Shouldn't call otherwise");
@@ -3053,7 +3053,7 @@
     }
   }
 }
-#endif // ndef PRODUCT
+#endif // def ASSERT
 
 
 instanceKlassHandle ClassFileParser::parse_super_class(int super_class_index,
@@ -3114,9 +3114,6 @@
 
   // Field size and offset computation
   int nonstatic_field_size = _super_klass() == NULL ? 0 : _super_klass()->nonstatic_field_size();
-#ifndef PRODUCT
-  int orig_nonstatic_field_size = 0;
-#endif
   int next_static_oop_offset;
   int next_static_double_offset;
   int next_static_word_offset;
@@ -3201,25 +3198,6 @@
 
   first_nonstatic_oop_offset = 0; // will be set for first oop field
 
-#ifndef PRODUCT
-  if( PrintCompactFieldsSavings ) {
-    next_nonstatic_double_offset = next_nonstatic_field_offset +
-                                   (nonstatic_oop_count * heapOopSize);
-    if ( nonstatic_double_count > 0 ) {
-      next_nonstatic_double_offset = align_size_up(next_nonstatic_double_offset, BytesPerLong);
-    }
-    next_nonstatic_word_offset  = next_nonstatic_double_offset +
-                                  (nonstatic_double_count * BytesPerLong);
-    next_nonstatic_short_offset = next_nonstatic_word_offset +
-                                  (nonstatic_word_count * BytesPerInt);
-    next_nonstatic_byte_offset  = next_nonstatic_short_offset +
-                                  (nonstatic_short_count * BytesPerShort);
-    next_nonstatic_type_offset  = align_size_up((next_nonstatic_byte_offset +
-                                  nonstatic_byte_count ), heapOopSize );
-    orig_nonstatic_field_size   = nonstatic_field_size +
-    ((next_nonstatic_type_offset - first_nonstatic_field_offset)/heapOopSize);
-  }
-#endif
   bool compact_fields   = CompactFields;
   int  allocation_style = FieldsAllocationStyle;
   if( allocation_style < 0 || allocation_style > 2 ) { // Out of range?
@@ -3593,21 +3571,6 @@
                           first_nonstatic_oop_offset);
 
 #ifndef PRODUCT
-  if( PrintCompactFieldsSavings ) {
-    ResourceMark rm;
-    if( nonstatic_field_size < orig_nonstatic_field_size ) {
-      tty->print("[Saved %d of %d bytes in %s]\n",
-               (orig_nonstatic_field_size - nonstatic_field_size)*heapOopSize,
-               orig_nonstatic_field_size*heapOopSize,
-               _class_name);
-    } else if( nonstatic_field_size > orig_nonstatic_field_size ) {
-      tty->print("[Wasted %d over %d bytes in %s]\n",
-               (nonstatic_field_size - orig_nonstatic_field_size)*heapOopSize,
-               orig_nonstatic_field_size*heapOopSize,
-               _class_name);
-    }
-  }
-
   if (PrintFieldLayout) {
     print_field_layout(_class_name,
           _fields,
diff --git a/hotspot/src/share/vm/classfile/dictionary.cpp b/hotspot/src/share/vm/classfile/dictionary.cpp
index 92d9fb4..b79cda7 100644
--- a/hotspot/src/share/vm/classfile/dictionary.cpp
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp
@@ -253,22 +253,6 @@
   }
 }
 
-
-//   All classes, and their class loaders
-//   (added for helpers that use HandleMarks and ResourceMarks)
-// Don't iterate over placeholders
-void Dictionary::classes_do(void f(Klass*, ClassLoaderData*, TRAPS), TRAPS) {
-  for (int index = 0; index < table_size(); index++) {
-    for (DictionaryEntry* probe = bucket(index);
-                          probe != NULL;
-                          probe = probe->next()) {
-      Klass* k = probe->klass();
-      f(k, probe->loader_data(), CHECK);
-    }
-  }
-}
-
-
 //   All classes, and their class loaders
 // Don't iterate over placeholders
 void Dictionary::classes_do(void f(Klass*, ClassLoaderData*)) {
diff --git a/hotspot/src/share/vm/classfile/dictionary.hpp b/hotspot/src/share/vm/classfile/dictionary.hpp
index 8820b25..53629a0 100644
--- a/hotspot/src/share/vm/classfile/dictionary.hpp
+++ b/hotspot/src/share/vm/classfile/dictionary.hpp
@@ -90,7 +90,6 @@
   void classes_do(void f(Klass*));
   void classes_do(void f(Klass*, TRAPS), TRAPS);
   void classes_do(void f(Klass*, ClassLoaderData*));
-  void classes_do(void f(Klass*, ClassLoaderData*, TRAPS), TRAPS);
 
   void methods_do(void f(Method*));
 
diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp
index 3aa1b77..6823090 100644
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp
@@ -1747,13 +1747,6 @@
   dictionary()->classes_do(f);
 }
 
-//   All classes, and their class loaders
-//   (added for helpers that use HandleMarks and ResourceMarks)
-// Don't iterate over placeholders
-void SystemDictionary::classes_do(void f(Klass*, ClassLoaderData*, TRAPS), TRAPS) {
-  dictionary()->classes_do(f, CHECK);
-}
-
 void SystemDictionary::placeholders_do(void f(Symbol*)) {
   placeholders()->entries_do(f);
 }
diff --git a/hotspot/src/share/vm/classfile/systemDictionary.hpp b/hotspot/src/share/vm/classfile/systemDictionary.hpp
index f1ac0b4..98e8f43 100644
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp
@@ -313,10 +313,7 @@
   static void classes_do(void f(Klass*, TRAPS), TRAPS);
   //   All classes, and their class loaders
   static void classes_do(void f(Klass*, ClassLoaderData*));
-  //   All classes, and their class loaders
-  //   (added for helpers that use HandleMarks and ResourceMarks)
-  static void classes_do(void f(Klass*, ClassLoaderData*, TRAPS), TRAPS);
-  // All entries in the placeholder table and their class loaders
+
   static void placeholders_do(void f(Symbol*));
 
   // Iterate over all methods in all klasses in dictionary
diff --git a/hotspot/src/share/vm/classfile/verifier.cpp b/hotspot/src/share/vm/classfile/verifier.cpp
index fda30ac..015b809 100644
--- a/hotspot/src/share/vm/classfile/verifier.cpp
+++ b/hotspot/src/share/vm/classfile/verifier.cpp
@@ -362,7 +362,7 @@
 }
 #endif
 
-void ErrorContext::details(outputStream* ss, Method* method) const {
+void ErrorContext::details(outputStream* ss, const Method* method) const {
   if (is_valid()) {
     ss->print_cr("");
     ss->print_cr("Exception Details:");
@@ -435,7 +435,7 @@
   ss->print_cr("");
 }
 
-void ErrorContext::location_details(outputStream* ss, Method* method) const {
+void ErrorContext::location_details(outputStream* ss, const Method* method) const {
   if (_bci != -1 && method != NULL) {
     streamIndentor si(ss);
     const char* bytecode_name = "<invalid>";
@@ -470,7 +470,7 @@
   }
 }
 
-void ErrorContext::bytecode_details(outputStream* ss, Method* method) const {
+void ErrorContext::bytecode_details(outputStream* ss, const Method* method) const {
   if (method != NULL) {
     streamIndentor si(ss);
     ss->indent().print_cr("Bytecode:");
@@ -479,7 +479,7 @@
   }
 }
 
-void ErrorContext::handler_details(outputStream* ss, Method* method) const {
+void ErrorContext::handler_details(outputStream* ss, const Method* method) const {
   if (method != NULL) {
     streamIndentor si(ss);
     ExceptionTable table(method);
@@ -494,7 +494,7 @@
   }
 }
 
-void ErrorContext::stackmap_details(outputStream* ss, Method* method) const {
+void ErrorContext::stackmap_details(outputStream* ss, const Method* method) const {
   if (method != NULL && method->has_stackmap_table()) {
     streamIndentor si(ss);
     ss->indent().print_cr("Stackmap Table:");
diff --git a/hotspot/src/share/vm/classfile/verifier.hpp b/hotspot/src/share/vm/classfile/verifier.hpp
index bdab7a7..bfab2c8 100644
--- a/hotspot/src/share/vm/classfile/verifier.hpp
+++ b/hotspot/src/share/vm/classfile/verifier.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -224,7 +224,7 @@
     _expected.reset_frame();
   }
 
-  void details(outputStream* ss, Method* method) const;
+  void details(outputStream* ss, const Method* method) const;
 
 #ifdef ASSERT
   void print_on(outputStream* str) const {
@@ -237,12 +237,12 @@
 #endif
 
  private:
-  void location_details(outputStream* ss, Method* method) const;
+  void location_details(outputStream* ss, const Method* method) const;
   void reason_details(outputStream* ss) const;
   void frame_details(outputStream* ss) const;
-  void bytecode_details(outputStream* ss, Method* method) const;
-  void handler_details(outputStream* ss, Method* method) const;
-  void stackmap_details(outputStream* ss, Method* method) const;
+  void bytecode_details(outputStream* ss, const Method* method) const;
+  void handler_details(outputStream* ss, const Method* method) const;
+  void stackmap_details(outputStream* ss, const Method* method) const;
 };
 
 // A new instance of this class is created for each class being verified
diff --git a/hotspot/src/share/vm/classfile/vmSymbols.cpp b/hotspot/src/share/vm/classfile/vmSymbols.cpp
index 92939ea..cc38c6d 100644
--- a/hotspot/src/share/vm/classfile/vmSymbols.cpp
+++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp
@@ -49,7 +49,7 @@
   }
 }
 
-#ifndef PRODUCT
+#ifdef ASSERT
 #define VM_SYMBOL_ENUM_NAME_BODY(name, string) #name "\0"
 static const char* vm_symbol_enum_names =
   VM_SYMBOLS_DO(VM_SYMBOL_ENUM_NAME_BODY, VM_ALIAS_IGNORE)
@@ -64,7 +64,7 @@
   }
   return string;
 }
-#endif //PRODUCT
+#endif //ASSERT
 
 // Put all the VM symbol strings in one place.
 // Makes for a more compact libjvm.
diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp
index 428b294..9fd9aff 100644
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp
@@ -68,7 +68,7 @@
   template(java_lang_Float,                           "java/lang/Float")                          \
   template(java_lang_Double,                          "java/lang/Double")                         \
   template(java_lang_Byte,                            "java/lang/Byte")                           \
-  template(java_lang_Byte_Cache,                      "java/lang/Byte$ByteCache")                 \
+  template(java_lang_Byte_ByteCache,                  "java/lang/Byte$ByteCache")                 \
   template(java_lang_Short,                           "java/lang/Short")                          \
   template(java_lang_Short_ShortCache,                "java/lang/Short$ShortCache")               \
   template(java_lang_Integer,                         "java/lang/Integer")                        \
diff --git a/hotspot/src/share/vm/code/nmethod.cpp b/hotspot/src/share/vm/code/nmethod.cpp
index 60bc88b..597a7ac 100644
--- a/hotspot/src/share/vm/code/nmethod.cpp
+++ b/hotspot/src/share/vm/code/nmethod.cpp
@@ -1794,6 +1794,19 @@
           Metadata* md = r->metadata_value();
           f(md);
         }
+      } else if (iter.type() == relocInfo::virtual_call_type) {
+        // Check compiledIC holders associated with this nmethod
+        CompiledIC *ic = CompiledIC_at(iter.reloc());
+        if (ic->is_icholder_call()) {
+          CompiledICHolder* cichk = ic->cached_icholder();
+          f(cichk->holder_method());
+          f(cichk->holder_klass());
+        } else {
+          Metadata* ic_oop = ic->cached_metadata();
+          if (ic_oop != NULL) {
+            f(ic_oop);
+          }
+        }
       }
     }
   }
@@ -1804,6 +1817,7 @@
     Metadata* md = *p;
     f(md);
   }
+
   // Call function Method*, not embedded in these other places.
   if (_method != NULL) f(_method);
 }
diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp
index 086bff8..ad097d9 100644
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp
@@ -1854,8 +1854,10 @@
     tty->print("%7d ", (int) tty->time_stamp().milliseconds());  // print timestamp
     tty->print("%4d ", compile_id);    // print compilation number
     tty->print("%s ", (is_osr ? "%" : " "));
-    int code_size = (task->code() == NULL) ? 0 : task->code()->total_size();
-    tty->print_cr("size: %d time: %d inlined: %d bytes", code_size, (int)time.milliseconds(), task->num_inlined_bytecodes());
+    if (task->code() != NULL) {
+      tty->print("size: %d(%d) ", task->code()->total_size(), task->code()->insts_size());
+    }
+    tty->print_cr("time: %d inlined: %d bytes", (int)time.milliseconds(), task->num_inlined_bytecodes());
   }
 
   if (PrintCodeCacheOnCompilation)
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp
index e57d405..c2aafb7 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -52,7 +52,7 @@
 }
 
 void ConcurrentMarkSweepPolicy::initialize_generations() {
-  _generations = new GenerationSpecPtr[number_of_generations()];
+  _generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC, 0, AllocFailStrategy::RETURN_NULL);
   if (_generations == NULL)
     vm_exit_during_initialization("Unable to allocate gen spec");
 
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
index 0f92b36..6da8915 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
@@ -692,8 +692,7 @@
   _cmsGen ->init_initiating_occupancy(CMSInitiatingOccupancyFraction, CMSTriggerRatio);
 
   // Clip CMSBootstrapOccupancy between 0 and 100.
-  _bootstrap_occupancy = ((double)MIN2((uintx)100, MAX2((uintx)0, CMSBootstrapOccupancy)))
-                         /(double)100;
+  _bootstrap_occupancy = ((double)CMSBootstrapOccupancy)/(double)100;
 
   _full_gcs_since_conc_gc = 0;
 
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
index 39e5a27..137f76c 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
@@ -4515,7 +4515,8 @@
     _total_used_bytes(0), _total_capacity_bytes(0),
     _total_prev_live_bytes(0), _total_next_live_bytes(0),
     _hum_used_bytes(0), _hum_capacity_bytes(0),
-    _hum_prev_live_bytes(0), _hum_next_live_bytes(0) {
+    _hum_prev_live_bytes(0), _hum_next_live_bytes(0),
+    _total_remset_bytes(0) {
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
   MemRegion g1_committed = g1h->g1_committed();
   MemRegion g1_reserved = g1h->g1_reserved();
@@ -4533,23 +4534,25 @@
                  HeapRegion::GrainBytes);
   _out->print_cr(G1PPRL_LINE_PREFIX);
   _out->print_cr(G1PPRL_LINE_PREFIX
-                 G1PPRL_TYPE_H_FORMAT
-                 G1PPRL_ADDR_BASE_H_FORMAT
-                 G1PPRL_BYTE_H_FORMAT
-                 G1PPRL_BYTE_H_FORMAT
-                 G1PPRL_BYTE_H_FORMAT
-                 G1PPRL_DOUBLE_H_FORMAT,
-                 "type", "address-range",
-                 "used", "prev-live", "next-live", "gc-eff");
+                G1PPRL_TYPE_H_FORMAT
+                G1PPRL_ADDR_BASE_H_FORMAT
+                G1PPRL_BYTE_H_FORMAT
+                G1PPRL_BYTE_H_FORMAT
+                G1PPRL_BYTE_H_FORMAT
+                G1PPRL_DOUBLE_H_FORMAT
+                G1PPRL_BYTE_H_FORMAT,
+                "type", "address-range",
+                "used", "prev-live", "next-live", "gc-eff", "remset");
   _out->print_cr(G1PPRL_LINE_PREFIX
-                 G1PPRL_TYPE_H_FORMAT
-                 G1PPRL_ADDR_BASE_H_FORMAT
-                 G1PPRL_BYTE_H_FORMAT
-                 G1PPRL_BYTE_H_FORMAT
-                 G1PPRL_BYTE_H_FORMAT
-                 G1PPRL_DOUBLE_H_FORMAT,
-                 "", "",
-                 "(bytes)", "(bytes)", "(bytes)", "(bytes/ms)");
+                G1PPRL_TYPE_H_FORMAT
+                G1PPRL_ADDR_BASE_H_FORMAT
+                G1PPRL_BYTE_H_FORMAT
+                G1PPRL_BYTE_H_FORMAT
+                G1PPRL_BYTE_H_FORMAT
+                G1PPRL_DOUBLE_H_FORMAT
+                G1PPRL_BYTE_H_FORMAT,
+                "", "",
+                "(bytes)", "(bytes)", "(bytes)", "(bytes/ms)", "(bytes)");
 }
 
 // It takes as a parameter a reference to one of the _hum_* fields, it
@@ -4591,6 +4594,7 @@
   size_t prev_live_bytes = r->live_bytes();
   size_t next_live_bytes = r->next_live_bytes();
   double gc_eff          = r->gc_efficiency();
+  size_t remset_bytes    = r->rem_set()->mem_size();
   if (r->used() == 0) {
     type = "FREE";
   } else if (r->is_survivor()) {
@@ -4624,6 +4628,7 @@
   _total_capacity_bytes  += capacity_bytes;
   _total_prev_live_bytes += prev_live_bytes;
   _total_next_live_bytes += next_live_bytes;
+  _total_remset_bytes    += remset_bytes;
 
   // Print a line for this particular region.
   _out->print_cr(G1PPRL_LINE_PREFIX
@@ -4632,14 +4637,17 @@
                  G1PPRL_BYTE_FORMAT
                  G1PPRL_BYTE_FORMAT
                  G1PPRL_BYTE_FORMAT
-                 G1PPRL_DOUBLE_FORMAT,
+                 G1PPRL_DOUBLE_FORMAT
+                 G1PPRL_BYTE_FORMAT,
                  type, bottom, end,
-                 used_bytes, prev_live_bytes, next_live_bytes, gc_eff);
+                 used_bytes, prev_live_bytes, next_live_bytes, gc_eff , remset_bytes);
 
   return false;
 }
 
 G1PrintRegionLivenessInfoClosure::~G1PrintRegionLivenessInfoClosure() {
+  // add static memory usages to remembered set sizes
+  _total_remset_bytes += HeapRegionRemSet::fl_mem_size() + HeapRegionRemSet::static_mem_size();
   // Print the footer of the output.
   _out->print_cr(G1PPRL_LINE_PREFIX);
   _out->print_cr(G1PPRL_LINE_PREFIX
@@ -4647,13 +4655,15 @@
                  G1PPRL_SUM_MB_FORMAT("capacity")
                  G1PPRL_SUM_MB_PERC_FORMAT("used")
                  G1PPRL_SUM_MB_PERC_FORMAT("prev-live")
-                 G1PPRL_SUM_MB_PERC_FORMAT("next-live"),
+                 G1PPRL_SUM_MB_PERC_FORMAT("next-live")
+                 G1PPRL_SUM_MB_FORMAT("remset"),
                  bytes_to_mb(_total_capacity_bytes),
                  bytes_to_mb(_total_used_bytes),
                  perc(_total_used_bytes, _total_capacity_bytes),
                  bytes_to_mb(_total_prev_live_bytes),
                  perc(_total_prev_live_bytes, _total_capacity_bytes),
                  bytes_to_mb(_total_next_live_bytes),
-                 perc(_total_next_live_bytes, _total_capacity_bytes));
+                 perc(_total_next_live_bytes, _total_capacity_bytes),
+                 bytes_to_mb(_total_remset_bytes));
   _out->cr();
 }
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
index 211a728..58ef49e 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
@@ -1257,6 +1257,9 @@
   size_t _hum_prev_live_bytes;
   size_t _hum_next_live_bytes;
 
+  // Accumulator for the remembered set size
+  size_t _total_remset_bytes;
+
   static double perc(size_t val, size_t total) {
     if (total == 0) {
       return 0.0;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp
index a055d4f..00ea5b5 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp
@@ -101,20 +101,23 @@
          ReservedSpace::allocation_align_size_up(_committed_size),
          err_msg("Unaligned? committed_size: " SIZE_FORMAT, _committed_size));
 
-  // Verify that the committed space for the card counts
-  // matches our committed max card num.
+  // Verify that the committed space for the card counts matches our
+  // committed max card num. Note for some allocation alignments, the
+  // amount of space actually committed for the counts table will be able
+  // to span more cards than the number spanned by the maximum heap.
   size_t prev_committed_size = _committed_size;
-  size_t prev_committed_card_num = prev_committed_size / sizeof(jbyte);
+  size_t prev_committed_card_num = committed_to_card_num(prev_committed_size);
+
   assert(prev_committed_card_num == _committed_max_card_num,
          err_msg("Card mismatch: "
                  "prev: " SIZE_FORMAT ", "
-                 "committed: "SIZE_FORMAT,
-                 prev_committed_card_num, _committed_max_card_num));
+                 "committed: "SIZE_FORMAT", "
+                 "reserved: "SIZE_FORMAT,
+                 prev_committed_card_num, _committed_max_card_num, _reserved_max_card_num));
 
   size_t new_size = (heap_capacity >> CardTableModRefBS::card_shift) * sizeof(jbyte);
   size_t new_committed_size = ReservedSpace::allocation_align_size_up(new_size);
-  size_t new_committed_card_num =
-                MIN2(_reserved_max_card_num, new_committed_size / sizeof(jbyte));
+  size_t new_committed_card_num = committed_to_card_num(new_committed_size);
 
   if (_committed_max_card_num < new_committed_card_num) {
     // we need to expand the backing store for the card counts
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp
index cef297b..fd516c0 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp
@@ -94,6 +94,14 @@
     return (jbyte*) (_ct_bot + card_num);
   }
 
+  // Helper routine.
+  // Returns the number of cards that can be counted by the given committed
+  // table size, with a maximum of the number of cards spanned by the max
+  // capacity of the heap.
+  size_t committed_to_card_num(size_t committed_size) {
+    return MIN2(_reserved_max_card_num, committed_size / sizeof(jbyte));
+  }
+
   // Clear the counts table for the given (exclusive) index range.
   void clear_range(size_t from_card_num, size_t to_card_num);
 
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
index 49cde42..11dcb0b 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
@@ -1549,7 +1549,7 @@
     }
 
     if (G1Log::finer()) {
-      g1_policy()->print_detailed_heap_transition();
+      g1_policy()->print_detailed_heap_transition(true /* full */);
     }
 
     print_heap_after_gc();
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
index a21290c..741c6b7 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
@@ -124,9 +124,12 @@
   _last_young_gc(false),
   _last_gc_was_young(false),
 
-  _eden_bytes_before_gc(0),
-  _survivor_bytes_before_gc(0),
-  _capacity_before_gc(0),
+  _eden_used_bytes_before_gc(0),
+  _survivor_used_bytes_before_gc(0),
+  _heap_used_bytes_before_gc(0),
+  _metaspace_used_bytes_before_gc(0),
+  _eden_capacity_bytes_before_gc(0),
+  _heap_capacity_bytes_before_gc(0),
 
   _eden_cset_region_length(0),
   _survivor_cset_region_length(0),
@@ -746,7 +749,7 @@
 
 void G1CollectorPolicy::record_full_collection_start() {
   _full_collection_start_sec = os::elapsedTime();
-  record_heap_size_info_at_start();
+  record_heap_size_info_at_start(true /* full */);
   // Release the future to-space so that it is available for compaction into.
   _g1->set_full_collection();
 }
@@ -803,7 +806,7 @@
   _trace_gen0_time_data.record_start_collection(s_w_t_ms);
   _stop_world_start = 0.0;
 
-  record_heap_size_info_at_start();
+  record_heap_size_info_at_start(false /* full */);
 
   phase_times()->record_cur_collection_start_sec(start_time_sec);
   _pending_cards = _g1->pending_card_num();
@@ -938,14 +941,6 @@
   _mmu_tracker->add_pause(end_time_sec - pause_time_ms/1000.0,
                           end_time_sec, false);
 
-  size_t freed_bytes =
-    _cur_collection_pause_used_at_start_bytes - cur_used_bytes;
-  size_t surviving_bytes = _collection_set_bytes_used_before - freed_bytes;
-
-  double survival_fraction =
-    (double)surviving_bytes/
-    (double)_collection_set_bytes_used_before;
-
   if (update_stats) {
     _trace_gen0_time_data.record_end_collection(pause_time_ms, phase_times());
     // this is where we update the allocation rate of the application
@@ -998,6 +993,7 @@
       }
     }
   }
+
   bool new_in_marking_window = _in_marking_window;
   bool new_in_marking_window_im = false;
   if (during_initial_mark_pause()) {
@@ -1083,8 +1079,10 @@
     }
     _rs_length_diff_seq->add((double) rs_length_diff);
 
-    size_t copied_bytes = surviving_bytes;
+    size_t freed_bytes = _heap_used_bytes_before_gc - cur_used_bytes;
+    size_t copied_bytes = _collection_set_bytes_used_before - freed_bytes;
     double cost_per_byte_ms = 0.0;
+
     if (copied_bytes > 0) {
       cost_per_byte_ms = phase_times()->average_last_obj_copy_time() / (double) copied_bytes;
       if (_in_marking_window) {
@@ -1148,51 +1146,61 @@
   byte_size_in_proper_unit((double)(bytes)),                    \
   proper_unit_for_byte_size((bytes))
 
-void G1CollectorPolicy::record_heap_size_info_at_start() {
+void G1CollectorPolicy::record_heap_size_info_at_start(bool full) {
   YoungList* young_list = _g1->young_list();
-  _eden_bytes_before_gc = young_list->eden_used_bytes();
-  _survivor_bytes_before_gc = young_list->survivor_used_bytes();
-  _capacity_before_gc = _g1->capacity();
-
-  _cur_collection_pause_used_at_start_bytes = _g1->used();
+  _eden_used_bytes_before_gc = young_list->eden_used_bytes();
+  _survivor_used_bytes_before_gc = young_list->survivor_used_bytes();
+  _heap_capacity_bytes_before_gc = _g1->capacity();
+  _heap_used_bytes_before_gc = _g1->used();
   _cur_collection_pause_used_regions_at_start = _g1->used_regions();
 
-  size_t eden_capacity_before_gc =
-         (_young_list_target_length * HeapRegion::GrainBytes) - _survivor_bytes_before_gc;
+  _eden_capacity_bytes_before_gc =
+         (_young_list_target_length * HeapRegion::GrainBytes) - _survivor_used_bytes_before_gc;
 
-  _prev_eden_capacity = eden_capacity_before_gc;
+  if (full) {
+    _metaspace_used_bytes_before_gc = MetaspaceAux::allocated_used_bytes();
+  }
 }
 
 void G1CollectorPolicy::print_heap_transition() {
   _g1->print_size_transition(gclog_or_tty,
-    _cur_collection_pause_used_at_start_bytes, _g1->used(), _g1->capacity());
+                             _heap_used_bytes_before_gc,
+                             _g1->used(),
+                             _g1->capacity());
 }
 
-void G1CollectorPolicy::print_detailed_heap_transition() {
-    YoungList* young_list = _g1->young_list();
-    size_t eden_bytes = young_list->eden_used_bytes();
-    size_t survivor_bytes = young_list->survivor_used_bytes();
-    size_t used_before_gc = _cur_collection_pause_used_at_start_bytes;
-    size_t used = _g1->used();
-    size_t capacity = _g1->capacity();
-    size_t eden_capacity =
-      (_young_list_target_length * HeapRegion::GrainBytes) - survivor_bytes;
+void G1CollectorPolicy::print_detailed_heap_transition(bool full) {
+  YoungList* young_list = _g1->young_list();
 
-    gclog_or_tty->print_cr(
-      "   [Eden: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT") "
-      "Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" "
-      "Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"
-      EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]",
-      EXT_SIZE_PARAMS(_eden_bytes_before_gc),
-      EXT_SIZE_PARAMS(_prev_eden_capacity),
-      EXT_SIZE_PARAMS(eden_bytes),
-      EXT_SIZE_PARAMS(eden_capacity),
-      EXT_SIZE_PARAMS(_survivor_bytes_before_gc),
-      EXT_SIZE_PARAMS(survivor_bytes),
-      EXT_SIZE_PARAMS(used_before_gc),
-      EXT_SIZE_PARAMS(_capacity_before_gc),
-      EXT_SIZE_PARAMS(used),
-      EXT_SIZE_PARAMS(capacity));
+  size_t eden_used_bytes_after_gc = young_list->eden_used_bytes();
+  size_t survivor_used_bytes_after_gc = young_list->survivor_used_bytes();
+  size_t heap_used_bytes_after_gc = _g1->used();
+
+  size_t heap_capacity_bytes_after_gc = _g1->capacity();
+  size_t eden_capacity_bytes_after_gc =
+    (_young_list_target_length * HeapRegion::GrainBytes) - survivor_used_bytes_after_gc;
+
+  gclog_or_tty->print(
+    "   [Eden: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT") "
+    "Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" "
+    "Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"
+    EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]",
+    EXT_SIZE_PARAMS(_eden_used_bytes_before_gc),
+    EXT_SIZE_PARAMS(_eden_capacity_bytes_before_gc),
+    EXT_SIZE_PARAMS(eden_used_bytes_after_gc),
+    EXT_SIZE_PARAMS(eden_capacity_bytes_after_gc),
+    EXT_SIZE_PARAMS(_survivor_used_bytes_before_gc),
+    EXT_SIZE_PARAMS(survivor_used_bytes_after_gc),
+    EXT_SIZE_PARAMS(_heap_used_bytes_before_gc),
+    EXT_SIZE_PARAMS(_heap_capacity_bytes_before_gc),
+    EXT_SIZE_PARAMS(heap_used_bytes_after_gc),
+    EXT_SIZE_PARAMS(heap_capacity_bytes_after_gc));
+
+  if (full) {
+    MetaspaceAux::print_metaspace_change(_metaspace_used_bytes_before_gc);
+  }
+
+  gclog_or_tty->cr();
 }
 
 void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time,
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
index 0886785..90106c0 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
@@ -175,7 +175,6 @@
   CollectionSetChooser* _collectionSetChooser;
 
   double _full_collection_start_sec;
-  size_t _cur_collection_pause_used_at_start_bytes;
   uint   _cur_collection_pause_used_regions_at_start;
 
   // These exclude marking times.
@@ -194,7 +193,6 @@
 
   uint _young_list_target_length;
   uint _young_list_fixed_length;
-  size_t _prev_eden_capacity; // used for logging
 
   // The max number of regions we can extend the eden by while the GC
   // locker is active. This should be >= _young_list_target_length;
@@ -693,11 +691,11 @@
 
   // Records the information about the heap size for reporting in
   // print_detailed_heap_transition
-  void record_heap_size_info_at_start();
+  void record_heap_size_info_at_start(bool full);
 
   // Print heap sizing transition (with less and more detail).
   void print_heap_transition();
-  void print_detailed_heap_transition();
+  void print_detailed_heap_transition(bool full = false);
 
   void record_stop_world_start();
   void record_concurrent_pause();
@@ -861,9 +859,16 @@
   uint _max_survivor_regions;
 
   // For reporting purposes.
-  size_t _eden_bytes_before_gc;
-  size_t _survivor_bytes_before_gc;
-  size_t _capacity_before_gc;
+  // The value of _heap_bytes_before_gc is also used to calculate
+  // the cost of copying.
+
+  size_t _eden_used_bytes_before_gc;         // Eden occupancy before GC
+  size_t _survivor_used_bytes_before_gc;     // Survivor occupancy before GC
+  size_t _heap_used_bytes_before_gc;         // Heap occupancy before GC
+  size_t _metaspace_used_bytes_before_gc;    // Metaspace occupancy before GC
+
+  size_t _eden_capacity_bytes_before_gc;     // Eden capacity before GC
+  size_t _heap_capacity_bytes_before_gc;     // Heap capacity before GC
 
   // The amount of survivor regions after a collection.
   uint _recorded_survivor_regions;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
index 1e005a2..d148721 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -282,7 +282,8 @@
     _fine_eviction_stride = _max_fine_entries / _fine_eviction_sample_size;
   }
 
-  _fine_grain_regions = new PerRegionTablePtr[_max_fine_entries];
+  _fine_grain_regions = NEW_C_HEAP_ARRAY3(PerRegionTablePtr, _max_fine_entries,
+                        mtGC, 0, AllocFailStrategy::RETURN_NULL);
 
   if (_fine_grain_regions == NULL) {
     vm_exit_out_of_memory(sizeof(void*)*_max_fine_entries, OOM_MALLOC_ERROR,
@@ -706,10 +707,11 @@
   // Cast away const in this case.
   MutexLockerEx x((Mutex*)&_m, Mutex::_no_safepoint_check_flag);
   size_t sum = 0;
-  PerRegionTable * cur = _first_all_fine_prts;
-  while (cur != NULL) {
-    sum += cur->mem_size();
-    cur = cur->next();
+  // all PRTs are of the same size so it is sufficient to query only one of them.
+  if (_first_all_fine_prts != NULL) {
+    assert(_last_all_fine_prts != NULL &&
+      _first_all_fine_prts->mem_size() == _last_all_fine_prts->mem_size(), "check that mem_size() is constant");
+    sum += _first_all_fine_prts->mem_size() * _n_fine_entries;
   }
   sum += (sizeof(PerRegionTable*) * _max_fine_entries);
   sum += (_coarse_map.size_in_words() * HeapWordSize);
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp
index 3d4cbed..adf1864 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp
@@ -24,7 +24,6 @@
 
 #include "precompiled.hpp"
 #include "gc_implementation/parallelScavenge/parMarkBitMap.hpp"
-#include "gc_implementation/parallelScavenge/parMarkBitMap.inline.hpp"
 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/os.hpp"
@@ -108,31 +107,6 @@
   return false;
 }
 
-size_t
-ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, HeapWord* end_addr) const
-{
-  assert(beg_addr <= end_addr, "bad range");
-
-  idx_t live_bits = 0;
-
-  // The bitmap routines require the right boundary to be word-aligned.
-  const idx_t end_bit = addr_to_bit(end_addr);
-  const idx_t range_end = BitMap::word_align_up(end_bit);
-
-  idx_t beg_bit = find_obj_beg(addr_to_bit(beg_addr), range_end);
-  while (beg_bit < end_bit) {
-    idx_t tmp_end = find_obj_end(beg_bit, range_end);
-    if (tmp_end < end_bit) {
-      live_bits += tmp_end - beg_bit + 1;
-      beg_bit = find_obj_beg(tmp_end + 1, range_end);
-    } else {
-      live_bits += end_bit - beg_bit;  // No + 1 here; end_bit is not counted.
-      return bits_to_words(live_bits);
-    }
-  }
-  return bits_to_words(live_bits);
-}
-
 size_t ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, oop end_obj) const
 {
   assert(beg_addr <= (HeapWord*)end_obj, "bad range");
@@ -244,13 +218,6 @@
   return complete;
 }
 
-#ifndef PRODUCT
-void ParMarkBitMap::reset_counters()
-{
-  _cas_tries = _cas_retries = _cas_by_another = 0;
-}
-#endif  // #ifndef PRODUCT
-
 #ifdef ASSERT
 void ParMarkBitMap::verify_clear() const
 {
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp
index fdc0feb..7c6cf51 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp
@@ -26,11 +26,11 @@
 #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PARMARKBITMAP_HPP
 
 #include "memory/memRegion.hpp"
-#include "gc_implementation/parallelScavenge/psVirtualspace.hpp"
-#include "utilities/bitMap.inline.hpp"
+#include "oops/oop.hpp"
+#include "utilities/bitMap.hpp"
 
-class oopDesc;
 class ParMarkBitMapClosure;
+class PSVirtualSpace;
 
 class ParMarkBitMap: public CHeapObj<mtGC>
 {
@@ -41,13 +41,11 @@
   enum IterationStatus { incomplete, complete, full, would_overflow };
 
   inline ParMarkBitMap();
-  inline ParMarkBitMap(MemRegion covered_region);
   bool initialize(MemRegion covered_region);
 
   // Atomically mark an object as live.
   bool mark_obj(HeapWord* addr, size_t size);
   inline bool mark_obj(oop obj, int size);
-  inline bool mark_obj(oop obj);
 
   // Return whether the specified begin or end bit is set.
   inline bool is_obj_beg(idx_t bit) const;
@@ -77,11 +75,6 @@
   // Return the size in words of the object (a search is done for the end bit).
   inline size_t obj_size(idx_t beg_bit)  const;
   inline size_t obj_size(HeapWord* addr) const;
-  inline size_t obj_size(oop obj)        const;
-
-  // Synonyms for the above.
-  size_t obj_size_in_words(oop obj) const { return obj_size((HeapWord*)obj); }
-  size_t obj_size_in_words(HeapWord* addr) const { return obj_size(addr); }
 
   // Apply live_closure to each live object that lies completely within the
   // range [live_range_beg, live_range_end).  This is used to iterate over the
@@ -124,15 +117,12 @@
                                  HeapWord* range_end,
                                  HeapWord* dead_range_end) const;
 
-  // Return the number of live words in the range [beg_addr, end_addr) due to
+  // Return the number of live words in the range [beg_addr, end_obj) due to
   // objects that start in the range.  If a live object extends onto the range,
   // the caller must detect and account for any live words due to that object.
   // If a live object extends beyond the end of the range, only the words within
-  // the range are included in the result.
-  size_t live_words_in_range(HeapWord* beg_addr, HeapWord* end_addr) const;
-
-  // Same as the above, except the end of the range must be a live object, which
-  // is the case when updating pointers.  This allows a branch to be removed
+  // the range are included in the result. The end of the range must be a live object,
+  // which is the case when updating pointers.  This allows a branch to be removed
   // from inside the loop.
   size_t live_words_in_range(HeapWord* beg_addr, oop end_obj) const;
 
@@ -156,22 +146,11 @@
   // Clear a range of bits or the entire bitmap (both begin and end bits are
   // cleared).
   inline void clear_range(idx_t beg, idx_t end);
-  inline void clear() { clear_range(0, size()); }
 
   // Return the number of bits required to represent the specified number of
   // HeapWords, or the specified region.
   static inline idx_t bits_required(size_t words);
   static inline idx_t bits_required(MemRegion covered_region);
-  static inline idx_t words_required(MemRegion covered_region);
-
-#ifndef PRODUCT
-  // CAS statistics.
-  size_t cas_tries() { return _cas_tries; }
-  size_t cas_retries() { return _cas_retries; }
-  size_t cas_by_another() { return _cas_by_another; }
-
-  void reset_counters();
-#endif  // #ifndef PRODUCT
 
   void print_on_error(outputStream* st) const {
     st->print_cr("Marking Bits: (ParMarkBitMap*) " PTR_FORMAT, this);
@@ -197,28 +176,11 @@
   BitMap          _beg_bits;
   BitMap          _end_bits;
   PSVirtualSpace* _virtual_space;
-
-#ifndef PRODUCT
-  size_t _cas_tries;
-  size_t _cas_retries;
-  size_t _cas_by_another;
-#endif  // #ifndef PRODUCT
 };
 
 inline ParMarkBitMap::ParMarkBitMap():
-  _beg_bits(),
-  _end_bits()
-{
-  _region_start = 0;
-  _virtual_space = 0;
-}
-
-inline ParMarkBitMap::ParMarkBitMap(MemRegion covered_region):
-  _beg_bits(),
-  _end_bits()
-{
-  initialize(covered_region);
-}
+  _beg_bits(), _end_bits(), _region_start(NULL), _region_size(0), _virtual_space(NULL)
+{ }
 
 inline void ParMarkBitMap::clear_range(idx_t beg, idx_t end)
 {
@@ -240,12 +202,6 @@
   return bits_required(covered_region.word_size());
 }
 
-inline ParMarkBitMap::idx_t
-ParMarkBitMap::words_required(MemRegion covered_region)
-{
-  return bits_required(covered_region) / BitsPerWord;
-}
-
 inline HeapWord*
 ParMarkBitMap::region_start() const
 {
@@ -350,11 +306,6 @@
   return obj_size(addr_to_bit(addr));
 }
 
-inline size_t ParMarkBitMap::obj_size(oop obj) const
-{
-  return obj_size((HeapWord*)obj);
-}
-
 inline ParMarkBitMap::IterationStatus
 ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure,
                        HeapWord* range_beg,
@@ -435,8 +386,10 @@
 
 inline void ParMarkBitMap::verify_addr(HeapWord* addr) const {
   // Allow one past the last valid address; useful for loop bounds.
-  assert(addr >= region_start(), "addr too small");
-  assert(addr <= region_start() + region_size(), "addr too big");
+  assert(addr >= region_start(),
+      err_msg("addr too small, addr: " PTR_FORMAT " region start: " PTR_FORMAT, addr, region_start()));
+  assert(addr <= region_end(),
+      err_msg("addr too big, addr: " PTR_FORMAT " region end: " PTR_FORMAT, addr, region_end()));
 }
 #endif  // #ifdef ASSERT
 
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.inline.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.inline.hpp
deleted file mode 100644
index e7f1dfa..0000000
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.inline.hpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PARMARKBITMAP_INLINE_HPP
-#define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PARMARKBITMAP_INLINE_HPP
-
-#include "oops/oop.hpp"
-
-inline bool
-ParMarkBitMap::mark_obj(oop obj)
-{
- return mark_obj(obj, obj->size());
-}
-
-#endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PARMARKBITMAP_INLINE_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
index 3834722..ed91fe2 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -213,7 +213,7 @@
   int random_seed = 17;
   do {
     while (ParCompactionManager::steal_objarray(which, &random_seed, task)) {
-      ObjArrayKlass* const k = (ObjArrayKlass*)task.obj()->klass();
+      ObjArrayKlass* k = (ObjArrayKlass*)task.obj()->klass();
       k->oop_follow_contents(cm, task.obj(), task.index());
       cm->follow_marking_stacks();
     }
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp
index 3b24ed8..8b3ee26 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -201,15 +201,232 @@
                                            size_t cur_eden,
                                            size_t max_old_gen_size,
                                            size_t max_eden_size,
-                                           bool   is_full_gc,
-                                           GCCause::Cause gc_cause,
-                                           CollectorPolicy* collector_policy) {
+                                           bool   is_full_gc) {
+  compute_eden_space_size(young_live,
+                          eden_live,
+                          cur_eden,
+                          max_eden_size,
+                          is_full_gc);
+
+  compute_old_gen_free_space(old_live,
+                             cur_eden,
+                             max_old_gen_size,
+                             is_full_gc);
+}
+
+void PSAdaptiveSizePolicy::compute_eden_space_size(
+                                           size_t young_live,
+                                           size_t eden_live,
+                                           size_t cur_eden,
+                                           size_t max_eden_size,
+                                           bool   is_full_gc) {
 
   // Update statistics
   // Time statistics are updated as we go, update footprint stats here
   _avg_base_footprint->sample(BaseFootPrintEstimate);
   avg_young_live()->sample(young_live);
   avg_eden_live()->sample(eden_live);
+
+  // This code used to return if the policy was not ready , i.e.,
+  // policy_is_ready() returning false.  The intent was that
+  // decisions below needed major collection times and so could
+  // not be made before two major collections.  A consequence was
+  // adjustments to the young generation were not done until after
+  // two major collections even if the minor collections times
+  // exceeded the requested goals.  Now let the young generation
+  // adjust for the minor collection times.  Major collection times
+  // will be zero for the first collection and will naturally be
+  // ignored.  Tenured generation adjustments are only made at the
+  // full collections so until the second major collection has
+  // been reached, no tenured generation adjustments will be made.
+
+  // Until we know better, desired promotion size uses the last calculation
+  size_t desired_promo_size = _promo_size;
+
+  // Start eden at the current value.  The desired value that is stored
+  // in _eden_size is not bounded by constraints of the heap and can
+  // run away.
+  //
+  // As expected setting desired_eden_size to the current
+  // value of desired_eden_size as a starting point
+  // caused desired_eden_size to grow way too large and caused
+  // an overflow down stream.  It may have improved performance in
+  // some case but is dangerous.
+  size_t desired_eden_size = cur_eden;
+
+  // Cache some values. There's a bit of work getting these, so
+  // we might save a little time.
+  const double major_cost = major_gc_cost();
+  const double minor_cost = minor_gc_cost();
+
+  // This method sets the desired eden size.  That plus the
+  // desired survivor space sizes sets the desired young generation
+  // size.  This methods does not know what the desired survivor
+  // size is but expects that other policy will attempt to make
+  // the survivor sizes compatible with the live data in the
+  // young generation.  This limit is an estimate of the space left
+  // in the young generation after the survivor spaces have been
+  // subtracted out.
+  size_t eden_limit = max_eden_size;
+
+  const double gc_cost_limit = GCTimeLimit/100.0;
+
+  // Which way should we go?
+  // if pause requirement is not met
+  //   adjust size of any generation with average paus exceeding
+  //   the pause limit.  Adjust one pause at a time (the larger)
+  //   and only make adjustments for the major pause at full collections.
+  // else if throughput requirement not met
+  //   adjust the size of the generation with larger gc time.  Only
+  //   adjust one generation at a time.
+  // else
+  //   adjust down the total heap size.  Adjust down the larger of the
+  //   generations.
+
+  // Add some checks for a threshold for a change.  For example,
+  // a change less than the necessary alignment is probably not worth
+  // attempting.
+
+
+  if ((_avg_minor_pause->padded_average() > gc_pause_goal_sec()) ||
+      (_avg_major_pause->padded_average() > gc_pause_goal_sec())) {
+    //
+    // Check pauses
+    //
+    // Make changes only to affect one of the pauses (the larger)
+    // at a time.
+    adjust_eden_for_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size);
+
+  } else if (_avg_minor_pause->padded_average() > gc_minor_pause_goal_sec()) {
+    // Adjust only for the minor pause time goal
+    adjust_eden_for_minor_pause_time(is_full_gc, &desired_eden_size);
+
+  } else if(adjusted_mutator_cost() < _throughput_goal) {
+    // This branch used to require that (mutator_cost() > 0.0 in 1.4.2.
+    // This sometimes resulted in skipping to the minimize footprint
+    // code.  Change this to try and reduce GC time if mutator time is
+    // negative for whatever reason.  Or for future consideration,
+    // bail out of the code if mutator time is negative.
+    //
+    // Throughput
+    //
+    assert(major_cost >= 0.0, "major cost is < 0.0");
+    assert(minor_cost >= 0.0, "minor cost is < 0.0");
+    // Try to reduce the GC times.
+    adjust_eden_for_throughput(is_full_gc, &desired_eden_size);
+
+  } else {
+
+    // Be conservative about reducing the footprint.
+    //   Do a minimum number of major collections first.
+    //   Have reasonable averages for major and minor collections costs.
+    if (UseAdaptiveSizePolicyFootprintGoal &&
+        young_gen_policy_is_ready() &&
+        avg_major_gc_cost()->average() >= 0.0 &&
+        avg_minor_gc_cost()->average() >= 0.0) {
+      size_t desired_sum = desired_eden_size + desired_promo_size;
+      desired_eden_size = adjust_eden_for_footprint(desired_eden_size, desired_sum);
+    }
+  }
+
+  // Note we make the same tests as in the code block below;  the code
+  // seems a little easier to read with the printing in another block.
+  if (PrintAdaptiveSizePolicy) {
+    if (desired_eden_size > eden_limit) {
+      gclog_or_tty->print_cr(
+            "PSAdaptiveSizePolicy::compute_eden_space_size limits:"
+            " desired_eden_size: " SIZE_FORMAT
+            " old_eden_size: " SIZE_FORMAT
+            " eden_limit: " SIZE_FORMAT
+            " cur_eden: " SIZE_FORMAT
+            " max_eden_size: " SIZE_FORMAT
+            " avg_young_live: " SIZE_FORMAT,
+            desired_eden_size, _eden_size, eden_limit, cur_eden,
+            max_eden_size, (size_t)avg_young_live()->average());
+    }
+    if (gc_cost() > gc_cost_limit) {
+      gclog_or_tty->print_cr(
+            "PSAdaptiveSizePolicy::compute_eden_space_size: gc time limit"
+            " gc_cost: %f "
+            " GCTimeLimit: %d",
+            gc_cost(), GCTimeLimit);
+    }
+  }
+
+  // Align everything and make a final limit check
+  const size_t alignment = _intra_generation_alignment;
+  desired_eden_size  = align_size_up(desired_eden_size, alignment);
+  desired_eden_size  = MAX2(desired_eden_size, alignment);
+
+  eden_limit  = align_size_down(eden_limit, alignment);
+
+  // And one last limit check, now that we've aligned things.
+  if (desired_eden_size > eden_limit) {
+    // If the policy says to get a larger eden but
+    // is hitting the limit, don't decrease eden.
+    // This can lead to a general drifting down of the
+    // eden size.  Let the tenuring calculation push more
+    // into the old gen.
+    desired_eden_size = MAX2(eden_limit, cur_eden);
+  }
+
+  if (PrintAdaptiveSizePolicy) {
+    // Timing stats
+    gclog_or_tty->print(
+               "PSAdaptiveSizePolicy::compute_eden_space_size: costs"
+               " minor_time: %f"
+               " major_cost: %f"
+               " mutator_cost: %f"
+               " throughput_goal: %f",
+               minor_gc_cost(), major_gc_cost(), mutator_cost(),
+               _throughput_goal);
+
+    // We give more details if Verbose is set
+    if (Verbose) {
+      gclog_or_tty->print( " minor_pause: %f"
+                  " major_pause: %f"
+                  " minor_interval: %f"
+                  " major_interval: %f"
+                  " pause_goal: %f",
+                  _avg_minor_pause->padded_average(),
+                  _avg_major_pause->padded_average(),
+                  _avg_minor_interval->average(),
+                  _avg_major_interval->average(),
+                  gc_pause_goal_sec());
+    }
+
+    // Footprint stats
+    gclog_or_tty->print( " live_space: " SIZE_FORMAT
+                " free_space: " SIZE_FORMAT,
+                live_space(), free_space());
+    // More detail
+    if (Verbose) {
+      gclog_or_tty->print( " base_footprint: " SIZE_FORMAT
+                  " avg_young_live: " SIZE_FORMAT
+                  " avg_old_live: " SIZE_FORMAT,
+                  (size_t)_avg_base_footprint->average(),
+                  (size_t)avg_young_live()->average(),
+                  (size_t)avg_old_live()->average());
+    }
+
+    // And finally, our old and new sizes.
+    gclog_or_tty->print(" old_eden_size: " SIZE_FORMAT
+               " desired_eden_size: " SIZE_FORMAT,
+               _eden_size, desired_eden_size);
+    gclog_or_tty->cr();
+  }
+
+  set_eden_size(desired_eden_size);
+}
+
+void PSAdaptiveSizePolicy::compute_old_gen_free_space(
+                                           size_t old_live,
+                                           size_t cur_eden,
+                                           size_t max_old_gen_size,
+                                           bool   is_full_gc) {
+
+  // Update statistics
+  // Time statistics are updated as we go, update footprint stats here
   if (is_full_gc) {
     // old_live is only accurate after a full gc
     avg_old_live()->sample(old_live);
@@ -242,32 +459,14 @@
   // some case but is dangerous.
   size_t desired_eden_size = cur_eden;
 
-#ifdef ASSERT
-  size_t original_promo_size = desired_promo_size;
-  size_t original_eden_size = desired_eden_size;
-#endif
-
   // Cache some values. There's a bit of work getting these, so
   // we might save a little time.
   const double major_cost = major_gc_cost();
   const double minor_cost = minor_gc_cost();
 
-  // Used for diagnostics
-  clear_generation_free_space_flags();
-
   // Limits on our growth
   size_t promo_limit = (size_t)(max_old_gen_size - avg_old_live()->average());
 
-  // This method sets the desired eden size.  That plus the
-  // desired survivor space sizes sets the desired young generation
-  // size.  This methods does not know what the desired survivor
-  // size is but expects that other policy will attempt to make
-  // the survivor sizes compatible with the live data in the
-  // young generation.  This limit is an estimate of the space left
-  // in the young generation after the survivor spaces have been
-  // subtracted out.
-  size_t eden_limit = max_eden_size;
-
   // But don't force a promo size below the current promo size. Otherwise,
   // the promo size will shrink for no good reason.
   promo_limit = MAX2(promo_limit, _promo_size);
@@ -290,7 +489,6 @@
   // a change less than the necessary alignment is probably not worth
   // attempting.
 
-
   if ((_avg_minor_pause->padded_average() > gc_pause_goal_sec()) ||
       (_avg_major_pause->padded_average() > gc_pause_goal_sec())) {
     //
@@ -298,12 +496,13 @@
     //
     // Make changes only to affect one of the pauses (the larger)
     // at a time.
-    adjust_for_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size);
-
+    if (is_full_gc) {
+      set_decide_at_full_gc(decide_at_full_gc_true);
+      adjust_promo_for_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size);
+    }
   } else if (_avg_minor_pause->padded_average() > gc_minor_pause_goal_sec()) {
     // Adjust only for the minor pause time goal
-    adjust_for_minor_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size);
-
+    adjust_promo_for_minor_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size);
   } else if(adjusted_mutator_cost() < _throughput_goal) {
     // This branch used to require that (mutator_cost() > 0.0 in 1.4.2.
     // This sometimes resulted in skipping to the minimize footprint
@@ -316,8 +515,10 @@
     assert(major_cost >= 0.0, "major cost is < 0.0");
     assert(minor_cost >= 0.0, "minor cost is < 0.0");
     // Try to reduce the GC times.
-    adjust_for_throughput(is_full_gc, &desired_promo_size, &desired_eden_size);
-
+    if (is_full_gc) {
+      set_decide_at_full_gc(decide_at_full_gc_true);
+      adjust_promo_for_throughput(is_full_gc, &desired_promo_size);
+    }
   } else {
 
     // Be conservative about reducing the footprint.
@@ -327,13 +528,10 @@
         young_gen_policy_is_ready() &&
         avg_major_gc_cost()->average() >= 0.0 &&
         avg_minor_gc_cost()->average() >= 0.0) {
-      size_t desired_sum = desired_eden_size + desired_promo_size;
-      desired_eden_size = adjust_eden_for_footprint(desired_eden_size,
-                                                    desired_sum);
       if (is_full_gc) {
         set_decide_at_full_gc(decide_at_full_gc_true);
-        desired_promo_size = adjust_promo_for_footprint(desired_promo_size,
-                                                        desired_sum);
+        size_t desired_sum = desired_eden_size + desired_promo_size;
+        desired_promo_size = adjust_promo_for_footprint(desired_promo_size, desired_sum);
       }
     }
   }
@@ -345,7 +543,7 @@
       // "free_in_old_gen" was the original value for used for promo_limit
       size_t free_in_old_gen = (size_t)(max_old_gen_size - avg_old_live()->average());
       gclog_or_tty->print_cr(
-            "PSAdaptiveSizePolicy::compute_generation_free_space limits:"
+            "PSAdaptiveSizePolicy::compute_old_gen_free_space limits:"
             " desired_promo_size: " SIZE_FORMAT
             " promo_limit: " SIZE_FORMAT
             " free_in_old_gen: " SIZE_FORMAT
@@ -354,21 +552,9 @@
             desired_promo_size, promo_limit, free_in_old_gen,
             max_old_gen_size, (size_t) avg_old_live()->average());
     }
-    if (desired_eden_size > eden_limit) {
-      gclog_or_tty->print_cr(
-            "AdaptiveSizePolicy::compute_generation_free_space limits:"
-            " desired_eden_size: " SIZE_FORMAT
-            " old_eden_size: " SIZE_FORMAT
-            " eden_limit: " SIZE_FORMAT
-            " cur_eden: " SIZE_FORMAT
-            " max_eden_size: " SIZE_FORMAT
-            " avg_young_live: " SIZE_FORMAT,
-            desired_eden_size, _eden_size, eden_limit, cur_eden,
-            max_eden_size, (size_t)avg_young_live()->average());
-    }
     if (gc_cost() > gc_cost_limit) {
       gclog_or_tty->print_cr(
-            "AdaptiveSizePolicy::compute_generation_free_space: gc time limit"
+            "PSAdaptiveSizePolicy::compute_old_gen_free_space: gc time limit"
             " gc_cost: %f "
             " GCTimeLimit: %d",
             gc_cost(), GCTimeLimit);
@@ -377,46 +563,18 @@
 
   // Align everything and make a final limit check
   const size_t alignment = _intra_generation_alignment;
-  desired_eden_size  = align_size_up(desired_eden_size, alignment);
-  desired_eden_size  = MAX2(desired_eden_size, alignment);
   desired_promo_size = align_size_up(desired_promo_size, alignment);
   desired_promo_size = MAX2(desired_promo_size, alignment);
 
-  eden_limit  = align_size_down(eden_limit, alignment);
   promo_limit = align_size_down(promo_limit, alignment);
 
-  // Is too much time being spent in GC?
-  //   Is the heap trying to grow beyond it's limits?
-
-  const size_t free_in_old_gen =
-    (size_t)(max_old_gen_size - avg_old_live()->average());
-  if (desired_promo_size > free_in_old_gen && desired_eden_size > eden_limit) {
-    check_gc_overhead_limit(young_live,
-                            eden_live,
-                            max_old_gen_size,
-                            max_eden_size,
-                            is_full_gc,
-                            gc_cause,
-                            collector_policy);
-  }
-
-
   // And one last limit check, now that we've aligned things.
-  if (desired_eden_size > eden_limit) {
-    // If the policy says to get a larger eden but
-    // is hitting the limit, don't decrease eden.
-    // This can lead to a general drifting down of the
-    // eden size.  Let the tenuring calculation push more
-    // into the old gen.
-    desired_eden_size = MAX2(eden_limit, cur_eden);
-  }
   desired_promo_size = MIN2(desired_promo_size, promo_limit);
 
-
   if (PrintAdaptiveSizePolicy) {
     // Timing stats
     gclog_or_tty->print(
-               "PSAdaptiveSizePolicy::compute_generation_free_space: costs"
+               "PSAdaptiveSizePolicy::compute_old_gen_free_space: costs"
                " minor_time: %f"
                " major_cost: %f"
                " mutator_cost: %f"
@@ -454,19 +612,13 @@
 
     // And finally, our old and new sizes.
     gclog_or_tty->print(" old_promo_size: " SIZE_FORMAT
-               " old_eden_size: " SIZE_FORMAT
-               " desired_promo_size: " SIZE_FORMAT
-               " desired_eden_size: " SIZE_FORMAT,
-               _promo_size, _eden_size,
-               desired_promo_size, desired_eden_size);
+               " desired_promo_size: " SIZE_FORMAT,
+               _promo_size, desired_promo_size);
     gclog_or_tty->cr();
   }
 
-  decay_supplemental_growth(is_full_gc);
-
   set_promo_size(desired_promo_size);
-  set_eden_size(desired_eden_size);
-};
+}
 
 void PSAdaptiveSizePolicy::decay_supplemental_growth(bool is_full_gc) {
   // Decay the supplemental increment?  Decay the supplement growth
@@ -490,9 +642,39 @@
   }
 }
 
-void PSAdaptiveSizePolicy::adjust_for_minor_pause_time(bool is_full_gc,
+void PSAdaptiveSizePolicy::adjust_promo_for_minor_pause_time(bool is_full_gc,
     size_t* desired_promo_size_ptr, size_t* desired_eden_size_ptr) {
 
+  if (PSAdjustTenuredGenForMinorPause) {
+    if (is_full_gc) {
+      set_decide_at_full_gc(decide_at_full_gc_true);
+    }
+    // If the desired eden size is as small as it will get,
+    // try to adjust the old gen size.
+    if (*desired_eden_size_ptr <= _intra_generation_alignment) {
+      // Vary the old gen size to reduce the young gen pause.  This
+      // may not be a good idea.  This is just a test.
+      if (minor_pause_old_estimator()->decrement_will_decrease()) {
+        set_change_old_gen_for_min_pauses(decrease_old_gen_for_min_pauses_true);
+        *desired_promo_size_ptr =
+          _promo_size - promo_decrement_aligned_down(*desired_promo_size_ptr);
+      } else {
+        set_change_old_gen_for_min_pauses(increase_old_gen_for_min_pauses_true);
+        size_t promo_heap_delta =
+          promo_increment_with_supplement_aligned_up(*desired_promo_size_ptr);
+        if ((*desired_promo_size_ptr + promo_heap_delta) >
+            *desired_promo_size_ptr) {
+          *desired_promo_size_ptr =
+            _promo_size + promo_heap_delta;
+        }
+      }
+    }
+  }
+}
+
+void PSAdaptiveSizePolicy::adjust_eden_for_minor_pause_time(bool is_full_gc,
+    size_t* desired_eden_size_ptr) {
+
   // Adjust the young generation size to reduce pause time of
   // of collections.
   //
@@ -512,49 +694,19 @@
       set_change_young_gen_for_min_pauses(
           increase_young_gen_for_min_pauses_true);
   }
-  if (PSAdjustTenuredGenForMinorPause) {
-    // If the desired eden size is as small as it will get,
-    // try to adjust the old gen size.
-    if (*desired_eden_size_ptr <= _intra_generation_alignment) {
-      // Vary the old gen size to reduce the young gen pause.  This
-      // may not be a good idea.  This is just a test.
-      if (minor_pause_old_estimator()->decrement_will_decrease()) {
-        set_change_old_gen_for_min_pauses(
-          decrease_old_gen_for_min_pauses_true);
-        *desired_promo_size_ptr =
-          _promo_size - promo_decrement_aligned_down(*desired_promo_size_ptr);
-      } else {
-        set_change_old_gen_for_min_pauses(
-          increase_old_gen_for_min_pauses_true);
-        size_t promo_heap_delta =
-          promo_increment_with_supplement_aligned_up(*desired_promo_size_ptr);
-        if ((*desired_promo_size_ptr + promo_heap_delta) >
-            *desired_promo_size_ptr) {
-          *desired_promo_size_ptr =
-            _promo_size + promo_heap_delta;
-        }
-      }
-    }
-  }
 }
 
-void PSAdaptiveSizePolicy::adjust_for_pause_time(bool is_full_gc,
+void PSAdaptiveSizePolicy::adjust_promo_for_pause_time(bool is_full_gc,
                                              size_t* desired_promo_size_ptr,
                                              size_t* desired_eden_size_ptr) {
 
   size_t promo_heap_delta = 0;
-  size_t eden_heap_delta = 0;
-  // Add some checks for a threshhold for a change.  For example,
+  // Add some checks for a threshold for a change.  For example,
   // a change less than the required alignment is probably not worth
   // attempting.
-  if (is_full_gc) {
-    set_decide_at_full_gc(decide_at_full_gc_true);
-  }
 
   if (_avg_minor_pause->padded_average() > _avg_major_pause->padded_average()) {
-    adjust_for_minor_pause_time(is_full_gc,
-                                desired_promo_size_ptr,
-                                desired_eden_size_ptr);
+    adjust_promo_for_minor_pause_time(is_full_gc, desired_promo_size_ptr, desired_eden_size_ptr);
     // major pause adjustments
   } else if (is_full_gc) {
     // Adjust for the major pause time only at full gc's because the
@@ -573,6 +725,33 @@
       //   promo_increment_aligned_up(*desired_promo_size_ptr);
       set_change_old_gen_for_maj_pauses(increase_old_gen_for_maj_pauses_true);
     }
+  }
+
+  if (PrintAdaptiveSizePolicy && Verbose) {
+    gclog_or_tty->print_cr(
+      "PSAdaptiveSizePolicy::compute_old_gen_free_space "
+      "adjusting gen sizes for major pause (avg %f goal %f). "
+      "desired_promo_size " SIZE_FORMAT " promo delta " SIZE_FORMAT,
+      _avg_major_pause->average(), gc_pause_goal_sec(),
+      *desired_promo_size_ptr, promo_heap_delta);
+  }
+}
+
+void PSAdaptiveSizePolicy::adjust_eden_for_pause_time(bool is_full_gc,
+                                             size_t* desired_promo_size_ptr,
+                                             size_t* desired_eden_size_ptr) {
+
+  size_t eden_heap_delta = 0;
+  // Add some checks for a threshold for a change.  For example,
+  // a change less than the required alignment is probably not worth
+  // attempting.
+  if (_avg_minor_pause->padded_average() > _avg_major_pause->padded_average()) {
+    adjust_eden_for_minor_pause_time(is_full_gc,
+                                desired_eden_size_ptr);
+    // major pause adjustments
+  } else if (is_full_gc) {
+    // Adjust for the major pause time only at full gc's because the
+    // affects of a change can only be seen at full gc's.
     if (PSAdjustYoungGenForMajorPause) {
       // If the promo size is at the minimum (i.e., the old gen
       // size will not actually decrease), consider changing the
@@ -607,43 +786,35 @@
 
   if (PrintAdaptiveSizePolicy && Verbose) {
     gclog_or_tty->print_cr(
-      "AdaptiveSizePolicy::compute_generation_free_space "
+      "PSAdaptiveSizePolicy::compute_eden_space_size "
       "adjusting gen sizes for major pause (avg %f goal %f). "
-      "desired_promo_size " SIZE_FORMAT "desired_eden_size "
-       SIZE_FORMAT
-      " promo delta " SIZE_FORMAT  " eden delta " SIZE_FORMAT,
+      "desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT,
       _avg_major_pause->average(), gc_pause_goal_sec(),
-      *desired_promo_size_ptr, *desired_eden_size_ptr,
-      promo_heap_delta, eden_heap_delta);
+      *desired_eden_size_ptr, eden_heap_delta);
   }
 }
 
-void PSAdaptiveSizePolicy::adjust_for_throughput(bool is_full_gc,
-                                             size_t* desired_promo_size_ptr,
-                                             size_t* desired_eden_size_ptr) {
+void PSAdaptiveSizePolicy::adjust_promo_for_throughput(bool is_full_gc,
+                                             size_t* desired_promo_size_ptr) {
 
-  // Add some checks for a threshhold for a change.  For example,
+  // Add some checks for a threshold for a change.  For example,
   // a change less than the required alignment is probably not worth
   // attempting.
-  if (is_full_gc) {
-    set_decide_at_full_gc(decide_at_full_gc_true);
-  }
 
   if ((gc_cost() + mutator_cost()) == 0.0) {
     return;
   }
 
   if (PrintAdaptiveSizePolicy && Verbose) {
-    gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_for_throughput("
-      "is_full: %d, promo: " SIZE_FORMAT ",  cur_eden: " SIZE_FORMAT "): ",
-      is_full_gc, *desired_promo_size_ptr, *desired_eden_size_ptr);
+    gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_promo_for_throughput("
+      "is_full: %d, promo: " SIZE_FORMAT "): ",
+      is_full_gc, *desired_promo_size_ptr);
     gclog_or_tty->print_cr("mutator_cost %f  major_gc_cost %f "
       "minor_gc_cost %f", mutator_cost(), major_gc_cost(), minor_gc_cost());
   }
 
   // Tenured generation
   if (is_full_gc) {
-
     // Calculate the change to use for the tenured gen.
     size_t scaled_promo_heap_delta = 0;
     // Can the increment to the generation be scaled?
@@ -720,6 +891,26 @@
           *desired_promo_size_ptr, scaled_promo_heap_delta);
     }
   }
+}
+
+void PSAdaptiveSizePolicy::adjust_eden_for_throughput(bool is_full_gc,
+                                             size_t* desired_eden_size_ptr) {
+
+  // Add some checks for a threshold for a change.  For example,
+  // a change less than the required alignment is probably not worth
+  // attempting.
+
+  if ((gc_cost() + mutator_cost()) == 0.0) {
+    return;
+  }
+
+  if (PrintAdaptiveSizePolicy && Verbose) {
+    gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_eden_for_throughput("
+      "is_full: %d, cur_eden: " SIZE_FORMAT "): ",
+      is_full_gc, *desired_eden_size_ptr);
+    gclog_or_tty->print_cr("mutator_cost %f  major_gc_cost %f "
+      "minor_gc_cost %f", mutator_cost(), major_gc_cost(), minor_gc_cost());
+  }
 
   // Young generation
   size_t scaled_eden_heap_delta = 0;
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp
index 030cb9d..683c6a9 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -136,18 +136,24 @@
   double gc_minor_pause_goal_sec() const { return _gc_minor_pause_goal_sec; }
 
   // Change the young generation size to achieve a minor GC pause time goal
-  void adjust_for_minor_pause_time(bool is_full_gc,
+  void adjust_promo_for_minor_pause_time(bool is_full_gc,
                                    size_t* desired_promo_size_ptr,
                                    size_t* desired_eden_size_ptr);
+  void adjust_eden_for_minor_pause_time(bool is_full_gc,
+                                   size_t* desired_eden_size_ptr);
   // Change the generation sizes to achieve a GC pause time goal
   // Returned sizes are not necessarily aligned.
-  void adjust_for_pause_time(bool is_full_gc,
+  void adjust_promo_for_pause_time(bool is_full_gc,
+                         size_t* desired_promo_size_ptr,
+                         size_t* desired_eden_size_ptr);
+  void adjust_eden_for_pause_time(bool is_full_gc,
                          size_t* desired_promo_size_ptr,
                          size_t* desired_eden_size_ptr);
   // Change the generation sizes to achieve an application throughput goal
   // Returned sizes are not necessarily aligned.
-  void adjust_for_throughput(bool is_full_gc,
-                             size_t* desired_promo_size_ptr,
+  void adjust_promo_for_throughput(bool is_full_gc,
+                             size_t* desired_promo_size_ptr);
+  void adjust_eden_for_throughput(bool is_full_gc,
                              size_t* desired_eden_size_ptr);
   // Change the generation sizes to achieve minimum footprint
   // Returned sizes are not aligned.
@@ -168,9 +174,6 @@
   size_t promo_decrement_aligned_down(size_t cur_promo);
   size_t promo_increment_with_supplement_aligned_up(size_t cur_promo);
 
-  // Decay the supplemental growth additive.
-  void decay_supplemental_growth(bool is_full_gc);
-
   // Returns a change that has been scaled down.  Result
   // is not aligned.  (If useful, move to some shared
   // location.)
@@ -336,7 +339,7 @@
   // perform a Full GC?
   bool should_full_GC(size_t live_in_old_gen);
 
-  // Calculates optimial free space sizes for both the old and young
+  // Calculates optimal (free) space sizes for both the young and old
   // generations.  Stores results in _eden_size and _promo_size.
   // Takes current used space in all generations as input, as well
   // as an indication if a full gc has just been performed, for use
@@ -347,9 +350,18 @@
                                      size_t cur_eden,  // current eden in bytes
                                      size_t max_old_gen_size,
                                      size_t max_eden_size,
-                                     bool   is_full_gc,
-                                     GCCause::Cause gc_cause,
-                                     CollectorPolicy* collector_policy);
+                                     bool   is_full_gc);
+
+  void compute_eden_space_size(size_t young_live,
+                               size_t eden_live,
+                               size_t cur_eden,  // current eden in bytes
+                               size_t max_eden_size,
+                               bool   is_full_gc);
+
+  void compute_old_gen_free_space(size_t old_live,
+                                             size_t cur_eden,  // current eden in bytes
+                                             size_t max_old_gen_size,
+                                             bool   is_full_gc);
 
   // Calculates new survivor space size;  returns a new tenuring threshold
   // value. Stores new survivor size in _survivor_size.
@@ -390,6 +402,9 @@
 
   // Printing support
   virtual bool print_adaptive_size_policy_on(outputStream* st) const;
+
+  // Decay the supplemental growth additive.
+  void decay_supplemental_growth(bool is_full_gc);
 };
 
 #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSADAPTIVESIZEPOLICY_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp
index 62c578f..415d629 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -187,11 +187,8 @@
 
     // Process ObjArrays one at a time to avoid marking stack bloat.
     ObjArrayTask task;
-    if (_objarray_stack.pop_overflow(task)) {
-      ObjArrayKlass* const k = (ObjArrayKlass*)task.obj()->klass();
-      k->oop_follow_contents(this, task.obj(), task.index());
-    } else if (_objarray_stack.pop_local(task)) {
-      ObjArrayKlass* const k = (ObjArrayKlass*)task.obj()->klass();
+    if (_objarray_stack.pop_overflow(task) || _objarray_stack.pop_local(task)) {
+      ObjArrayKlass* k = (ObjArrayKlass*)task.obj()->klass();
       k->oop_follow_contents(this, task.obj(), task.index());
     }
   } while (!marking_stacks_empty());
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
index adbaee4..90b0d091 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -92,8 +92,8 @@
   const bool clear_all_soft_refs =
     heap->collector_policy()->should_clear_all_soft_refs();
 
-  int count = (maximum_heap_compaction)?1:MarkSweepAlwaysCompactCount;
-  IntFlagSetting flag_setting(MarkSweepAlwaysCompactCount, count);
+  uint count = maximum_heap_compaction ? 1 : MarkSweepAlwaysCompactCount;
+  UIntFlagSetting flag_setting(MarkSweepAlwaysCompactCount, count);
   PSMarkSweep::invoke_no_policy(clear_all_soft_refs || maximum_heap_compaction);
 }
 
@@ -277,18 +277,36 @@
           young_gen->from_space()->capacity_in_bytes() +
           young_gen->to_space()->capacity_in_bytes(),
           "Sizes of space in young gen are out-of-bounds");
+
+        size_t young_live = young_gen->used_in_bytes();
+        size_t eden_live = young_gen->eden_space()->used_in_bytes();
+        size_t old_live = old_gen->used_in_bytes();
+        size_t cur_eden = young_gen->eden_space()->capacity_in_bytes();
+        size_t max_old_gen_size = old_gen->max_gen_size();
         size_t max_eden_size = young_gen->max_size() -
           young_gen->from_space()->capacity_in_bytes() -
           young_gen->to_space()->capacity_in_bytes();
-        size_policy->compute_generation_free_space(young_gen->used_in_bytes(),
-                                 young_gen->eden_space()->used_in_bytes(),
-                                 old_gen->used_in_bytes(),
-                                 young_gen->eden_space()->capacity_in_bytes(),
-                                 old_gen->max_gen_size(),
-                                 max_eden_size,
-                                 true /* full gc*/,
-                                 gc_cause,
-                                 heap->collector_policy());
+
+        // Used for diagnostics
+        size_policy->clear_generation_free_space_flags();
+
+        size_policy->compute_generation_free_space(young_live,
+                                                   eden_live,
+                                                   old_live,
+                                                   cur_eden,
+                                                   max_old_gen_size,
+                                                   max_eden_size,
+                                                   true /* full gc*/);
+
+        size_policy->check_gc_overhead_limit(young_live,
+                                             eden_live,
+                                             max_old_gen_size,
+                                             max_eden_size,
+                                             true /* full gc*/,
+                                             gc_cause,
+                                             heap->collector_policy());
+
+        size_policy->decay_supplemental_growth(true /* full gc*/);
 
         heap->resize_old_gen(size_policy->calculated_old_free_size_in_bytes());
 
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp
index 9844d1a..820696a 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp
@@ -88,8 +88,7 @@
    * by the MarkSweepAlwaysCompactCount parameter. This is a significant
    * performance improvement!
    */
-  bool skip_dead = (MarkSweepAlwaysCompactCount < 1)
-    || ((PSMarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0);
+  bool skip_dead = ((PSMarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0);
 
   size_t allowed_deadspace = 0;
   if (skip_dead) {
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
index b03107a..72177e1 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -948,7 +948,6 @@
 
   pre_gc_values->fill(heap);
 
-  NOT_PRODUCT(_mark_bitmap.reset_counters());
   DEBUG_ONLY(add_obj_count = add_obj_size = 0;)
   DEBUG_ONLY(mark_bitmap_count = mark_bitmap_size = 0;)
 
@@ -2042,15 +2041,6 @@
     marking_start.update();
     marking_phase(vmthread_cm, maximum_heap_compaction);
 
-#ifndef PRODUCT
-    if (TraceParallelOldGCMarkingPhase) {
-      gclog_or_tty->print_cr("marking_phase: cas_tries %d  cas_retries %d "
-        "cas_by_another %d",
-        mark_bitmap()->cas_tries(), mark_bitmap()->cas_retries(),
-        mark_bitmap()->cas_by_another());
-    }
-#endif  // #ifndef PRODUCT
-
     bool max_on_system_gc = UseMaximumCompactionOnSystemGC
       && gc_cause == GCCause::_java_lang_system_gc;
     summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc);
@@ -2094,19 +2084,36 @@
           young_gen->from_space()->capacity_in_bytes() +
           young_gen->to_space()->capacity_in_bytes(),
           "Sizes of space in young gen are out-of-bounds");
+
+        size_t young_live = young_gen->used_in_bytes();
+        size_t eden_live = young_gen->eden_space()->used_in_bytes();
+        size_t old_live = old_gen->used_in_bytes();
+        size_t cur_eden = young_gen->eden_space()->capacity_in_bytes();
+        size_t max_old_gen_size = old_gen->max_gen_size();
         size_t max_eden_size = young_gen->max_size() -
           young_gen->from_space()->capacity_in_bytes() -
           young_gen->to_space()->capacity_in_bytes();
-        size_policy->compute_generation_free_space(
-                              young_gen->used_in_bytes(),
-                              young_gen->eden_space()->used_in_bytes(),
-                              old_gen->used_in_bytes(),
-                              young_gen->eden_space()->capacity_in_bytes(),
-                              old_gen->max_gen_size(),
-                              max_eden_size,
-                              true /* full gc*/,
-                              gc_cause,
-                              heap->collector_policy());
+
+        // Used for diagnostics
+        size_policy->clear_generation_free_space_flags();
+
+        size_policy->compute_generation_free_space(young_live,
+                                                   eden_live,
+                                                   old_live,
+                                                   cur_eden,
+                                                   max_old_gen_size,
+                                                   max_eden_size,
+                                                   true /* full gc*/);
+
+        size_policy->check_gc_overhead_limit(young_live,
+                                             eden_live,
+                                             max_old_gen_size,
+                                             max_eden_size,
+                                             true /* full gc*/,
+                                             gc_cause,
+                                             heap->collector_policy());
+
+        size_policy->decay_supplemental_growth(true /* full gc*/);
 
         heap->resize_old_gen(
           size_policy->calculated_old_free_size_in_bytes());
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
index 4bc7870..f427c39 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
@@ -552,19 +552,33 @@
             young_gen->from_space()->capacity_in_bytes() +
             young_gen->to_space()->capacity_in_bytes(),
             "Sizes of space in young gen are out-of-bounds");
+
+          size_t young_live = young_gen->used_in_bytes();
+          size_t eden_live = young_gen->eden_space()->used_in_bytes();
+          size_t cur_eden = young_gen->eden_space()->capacity_in_bytes();
+          size_t max_old_gen_size = old_gen->max_gen_size();
           size_t max_eden_size = young_gen->max_size() -
             young_gen->from_space()->capacity_in_bytes() -
             young_gen->to_space()->capacity_in_bytes();
-          size_policy->compute_generation_free_space(young_gen->used_in_bytes(),
-                                   young_gen->eden_space()->used_in_bytes(),
-                                   old_gen->used_in_bytes(),
-                                   young_gen->eden_space()->capacity_in_bytes(),
-                                   old_gen->max_gen_size(),
-                                   max_eden_size,
-                                   false  /* full gc*/,
-                                   gc_cause,
-                                   heap->collector_policy());
 
+          // Used for diagnostics
+          size_policy->clear_generation_free_space_flags();
+
+          size_policy->compute_eden_space_size(young_live,
+                                               eden_live,
+                                               cur_eden,
+                                               max_eden_size,
+                                               false /* not full gc*/);
+
+          size_policy->check_gc_overhead_limit(young_live,
+                                               eden_live,
+                                               max_old_gen_size,
+                                               max_eden_size,
+                                               false /* not full gc*/,
+                                               gc_cause,
+                                               heap->collector_policy());
+
+          size_policy->decay_supplemental_growth(false /* not full gc*/);
         }
         // Resize the young generation at every collection
         // even if new sizes have not been calculated.  This is
diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
index 5e52aa1..817a1e6 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -30,7 +30,7 @@
 #include "oops/objArrayKlass.inline.hpp"
 #include "oops/oop.inline.hpp"
 
-unsigned int            MarkSweep::_total_invocations = 0;
+uint                    MarkSweep::_total_invocations = 0;
 
 Stack<oop, mtGC>              MarkSweep::_marking_stack;
 Stack<ObjArrayTask, mtGC>     MarkSweep::_objarray_stack;
@@ -95,7 +95,7 @@
     // Process ObjArrays one at a time to avoid marking stack bloat.
     if (!_objarray_stack.is_empty()) {
       ObjArrayTask task = _objarray_stack.pop();
-      ObjArrayKlass* const k = (ObjArrayKlass*)task.obj()->klass();
+      ObjArrayKlass* k = (ObjArrayKlass*)task.obj()->klass();
       k->oop_follow_contents(task.obj(), task.index());
     }
   } while (!_marking_stack.is_empty() || !_objarray_stack.is_empty());
diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
index ec724af..dc3af9a 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
@@ -113,7 +113,7 @@
   //
  protected:
   // Total invocations of a MarkSweep collection
-  static unsigned int _total_invocations;
+  static uint _total_invocations;
 
   // Traversal stacks used during phase1
   static Stack<oop, mtGC>                      _marking_stack;
@@ -147,7 +147,7 @@
   static AdjustKlassClosure   adjust_klass_closure;
 
   // Accessors
-  static unsigned int total_invocations() { return _total_invocations; }
+  static uint total_invocations() { return _total_invocations; }
 
   // Reference Processing
   static ReferenceProcessor* const ref_processor() { return _ref_processor; }
diff --git a/hotspot/src/share/vm/memory/allocation.cpp b/hotspot/src/share/vm/memory/allocation.cpp
index 1c1bf7a..a6721c9 100644
--- a/hotspot/src/share/vm/memory/allocation.cpp
+++ b/hotspot/src/share/vm/memory/allocation.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -49,10 +49,15 @@
 # include "os_bsd.inline.hpp"
 #endif
 
-void* StackObj::operator new(size_t size)  { ShouldNotCallThis(); return 0; };
-void  StackObj::operator delete(void* p)   { ShouldNotCallThis(); };
-void* _ValueObj::operator new(size_t size)  { ShouldNotCallThis(); return 0; };
-void  _ValueObj::operator delete(void* p)   { ShouldNotCallThis(); };
+void* StackObj::operator new(size_t size)       { ShouldNotCallThis(); return 0; }
+void  StackObj::operator delete(void* p)        { ShouldNotCallThis(); }
+void* StackObj::operator new [](size_t size)    { ShouldNotCallThis(); return 0; }
+void  StackObj::operator delete [](void* p)     { ShouldNotCallThis(); }
+
+void* _ValueObj::operator new(size_t size)      { ShouldNotCallThis(); return 0; }
+void  _ValueObj::operator delete(void* p)       { ShouldNotCallThis(); }
+void* _ValueObj::operator new [](size_t size)   { ShouldNotCallThis(); return 0; }
+void  _ValueObj::operator delete [](void* p)    { ShouldNotCallThis(); }
 
 void* MetaspaceObj::operator new(size_t size, ClassLoaderData* loader_data,
                                 size_t word_size, bool read_only, TRAPS) {
@@ -81,7 +86,6 @@
   st->print(" {"INTPTR_FORMAT"}", this);
 }
 
-
 void* ResourceObj::operator new(size_t size, allocation_type type, MEMFLAGS flags) {
   address res;
   switch (type) {
@@ -99,6 +103,10 @@
   return res;
 }
 
+void* ResourceObj::operator new [](size_t size, allocation_type type, MEMFLAGS flags) {
+  return (address) operator new(size, type, flags);
+}
+
 void* ResourceObj::operator new(size_t size, const std::nothrow_t&  nothrow_constant,
     allocation_type type, MEMFLAGS flags) {
   //should only call this with std::nothrow, use other operator new() otherwise
@@ -118,6 +126,10 @@
   return res;
 }
 
+void* ResourceObj::operator new [](size_t size, const std::nothrow_t&  nothrow_constant,
+    allocation_type type, MEMFLAGS flags) {
+  return (address)operator new(size, nothrow_constant, type, flags);
+}
 
 void ResourceObj::operator delete(void* p) {
   assert(((ResourceObj *)p)->allocated_on_C_heap(),
@@ -126,6 +138,10 @@
   FreeHeap(p);
 }
 
+void ResourceObj::operator delete [](void* p) {
+  operator delete(p);
+}
+
 #ifdef ASSERT
 void ResourceObj::set_allocation_type(address res, allocation_type type) {
     // Set allocation type in the resource object
@@ -215,8 +231,6 @@
   tty->print_cr("Heap free   " INTPTR_FORMAT, p);
 }
 
-bool warn_new_operator = false; // see vm_main
-
 //--------------------------------------------------------------------------------------
 // ChunkPool implementation
 
@@ -360,7 +374,7 @@
 void* Chunk::operator new(size_t requested_size, size_t length) {
   // requested_size is equal to sizeof(Chunk) but in order for the arena
   // allocations to come out aligned as expected the size must be aligned
-  // to expected arean alignment.
+  // to expected arena alignment.
   // expect requested_size but if sizeof(Chunk) doesn't match isn't proper size we must align it.
   assert(ARENA_ALIGN(requested_size) == aligned_overhead_size(), "Bad alignment");
   size_t bytes = ARENA_ALIGN(requested_size) + length;
@@ -669,19 +683,40 @@
 // a memory leak.  Use CHeapObj as the base class of such objects to make it explicit
 // that they're allocated on the C heap.
 // Commented out in product version to avoid conflicts with third-party C++ native code.
-// %% note this is causing a problem on solaris debug build. the global
-// new is being called from jdk source and causing data corruption.
-// src/share/native/sun/awt/font/fontmanager/textcache/hsMemory.cpp::hsSoftNew
-// define CATCH_OPERATOR_NEW_USAGE if you want to use this.
-#ifdef CATCH_OPERATOR_NEW_USAGE
+// On certain platforms, such as Mac OS X (Darwin), in debug version, new is being called
+// from jdk source and causing data corruption. Such as
+//  Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair
+// define ALLOW_OPERATOR_NEW_USAGE for platform on which global operator new allowed.
+//
+#ifndef ALLOW_OPERATOR_NEW_USAGE
 void* operator new(size_t size){
-  static bool warned = false;
-  if (!warned && warn_new_operator)
-    warning("should not call global (default) operator new");
-  warned = true;
-  return (void *) AllocateHeap(size, "global operator new");
+  assert(false, "Should not call global operator new");
+  return 0;
 }
-#endif
+
+void* operator new [](size_t size){
+  assert(false, "Should not call global operator new[]");
+  return 0;
+}
+
+void* operator new(size_t size, const std::nothrow_t&  nothrow_constant){
+  assert(false, "Should not call global operator new");
+  return 0;
+}
+
+void* operator new [](size_t size, std::nothrow_t&  nothrow_constant){
+  assert(false, "Should not call global operator new[]");
+  return 0;
+}
+
+void operator delete(void* p) {
+  assert(false, "Should not call global delete");
+}
+
+void operator delete [](void* p) {
+  assert(false, "Should not call global delete []");
+}
+#endif // ALLOW_OPERATOR_NEW_USAGE
 
 void AllocatedObj::print() const       { print_on(tty); }
 void AllocatedObj::print_value() const { print_value_on(tty); }
diff --git a/hotspot/src/share/vm/memory/allocation.hpp b/hotspot/src/share/vm/memory/allocation.hpp
index b65b297..2955943 100644
--- a/hotspot/src/share/vm/memory/allocation.hpp
+++ b/hotspot/src/share/vm/memory/allocation.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -86,12 +86,23 @@
 // subclasses.
 //
 // The following macros and function should be used to allocate memory
-// directly in the resource area or in the C-heap:
+// directly in the resource area or in the C-heap, The _OBJ variants
+// of the NEW/FREE_C_HEAP macros are used for alloc/dealloc simple
+// objects which are not inherited from CHeapObj, note constructor and
+// destructor are not called. The preferable way to allocate objects
+// is using the new operator.
 //
-//   NEW_RESOURCE_ARRAY(type,size)
+// WARNING: The array variant must only be used for a homogenous array
+// where all objects are of the exact type specified. If subtypes are
+// stored in the array then must pay attention to calling destructors
+// at needed.
+//
+//   NEW_RESOURCE_ARRAY(type, size)
 //   NEW_RESOURCE_OBJ(type)
-//   NEW_C_HEAP_ARRAY(type,size)
-//   NEW_C_HEAP_OBJ(type)
+//   NEW_C_HEAP_ARRAY(type, size)
+//   NEW_C_HEAP_OBJ(type, memflags)
+//   FREE_C_HEAP_ARRAY(type, old, memflags)
+//   FREE_C_HEAP_OBJ(objname, type, memflags)
 //   char* AllocateHeap(size_t size, const char* name);
 //   void  FreeHeap(void* p);
 //
@@ -195,8 +206,11 @@
   _NOINLINE_ void* operator new(size_t size, address caller_pc = 0);
   _NOINLINE_ void* operator new (size_t size, const std::nothrow_t&  nothrow_constant,
                                address caller_pc = 0);
-
+  _NOINLINE_ void* operator new [](size_t size, address caller_pc = 0);
+  _NOINLINE_ void* operator new [](size_t size, const std::nothrow_t&  nothrow_constant,
+                               address caller_pc = 0);
   void  operator delete(void* p);
+  void  operator delete [] (void* p);
 };
 
 // Base class for objects allocated on the stack only.
@@ -206,6 +220,8 @@
  private:
   void* operator new(size_t size);
   void  operator delete(void* p);
+  void* operator new [](size_t size);
+  void  operator delete [](void* p);
 };
 
 // Base class for objects used as value objects.
@@ -229,7 +245,9 @@
 class _ValueObj {
  private:
   void* operator new(size_t size);
-  void operator delete(void* p);
+  void  operator delete(void* p);
+  void* operator new [](size_t size);
+  void  operator delete [](void* p);
 };
 
 
@@ -510,13 +528,24 @@
 
  public:
   void* operator new(size_t size, allocation_type type, MEMFLAGS flags);
+  void* operator new [](size_t size, allocation_type type, MEMFLAGS flags);
   void* operator new(size_t size, const std::nothrow_t&  nothrow_constant,
       allocation_type type, MEMFLAGS flags);
+  void* operator new [](size_t size, const std::nothrow_t&  nothrow_constant,
+      allocation_type type, MEMFLAGS flags);
+
   void* operator new(size_t size, Arena *arena) {
       address res = (address)arena->Amalloc(size);
       DEBUG_ONLY(set_allocation_type(res, ARENA);)
       return res;
   }
+
+  void* operator new [](size_t size, Arena *arena) {
+      address res = (address)arena->Amalloc(size);
+      DEBUG_ONLY(set_allocation_type(res, ARENA);)
+      return res;
+  }
+
   void* operator new(size_t size) {
       address res = (address)resource_allocate_bytes(size);
       DEBUG_ONLY(set_allocation_type(res, RESOURCE_AREA);)
@@ -529,7 +558,20 @@
       return res;
   }
 
+  void* operator new [](size_t size) {
+      address res = (address)resource_allocate_bytes(size);
+      DEBUG_ONLY(set_allocation_type(res, RESOURCE_AREA);)
+      return res;
+  }
+
+  void* operator new [](size_t size, const std::nothrow_t& nothrow_constant) {
+      address res = (address)resource_allocate_bytes(size, AllocFailStrategy::RETURN_NULL);
+      DEBUG_ONLY(if (res != NULL) set_allocation_type(res, RESOURCE_AREA);)
+      return res;
+  }
+
   void  operator delete(void* p);
+  void  operator delete [](void* p);
 };
 
 // One of the following macros must be used when allocating an array
@@ -563,24 +605,25 @@
 #define REALLOC_C_HEAP_ARRAY(type, old, size, memflags)\
   (type*) (ReallocateHeap((char*)old, (size) * sizeof(type), memflags))
 
-#define FREE_C_HEAP_ARRAY(type,old,memflags) \
+#define FREE_C_HEAP_ARRAY(type, old, memflags) \
   FreeHeap((char*)(old), memflags)
 
-#define NEW_C_HEAP_OBJ(type, memflags)\
-  NEW_C_HEAP_ARRAY(type, 1, memflags)
-
-
 #define NEW_C_HEAP_ARRAY2(type, size, memflags, pc)\
   (type*) (AllocateHeap((size) * sizeof(type), memflags, pc))
 
 #define REALLOC_C_HEAP_ARRAY2(type, old, size, memflags, pc)\
   (type*) (ReallocateHeap((char*)old, (size) * sizeof(type), memflags, pc))
 
-#define NEW_C_HEAP_OBJ2(type, memflags, pc)\
-  NEW_C_HEAP_ARRAY2(type, 1, memflags, pc)
+#define NEW_C_HEAP_ARRAY3(type, size, memflags, pc, allocfail)         \
+  (type*) AllocateHeap(size * sizeof(type), memflags, pc, allocfail)
 
+// allocate type in heap without calling ctor
+#define NEW_C_HEAP_OBJ(type, memflags)\
+  NEW_C_HEAP_ARRAY(type, 1, memflags)
 
-extern bool warn_new_operator;
+// deallocate obj of type in heap without calling dtor
+#define FREE_C_HEAP_OBJ(objname, memflags)\
+  FreeHeap((char*)objname, memflags);
 
 // for statistics
 #ifndef PRODUCT
diff --git a/hotspot/src/share/vm/memory/allocation.inline.hpp b/hotspot/src/share/vm/memory/allocation.inline.hpp
index d55695b..138dd66 100644
--- a/hotspot/src/share/vm/memory/allocation.inline.hpp
+++ b/hotspot/src/share/vm/memory/allocation.inline.hpp
@@ -86,30 +86,39 @@
 
 template <MEMFLAGS F> void* CHeapObj<F>::operator new(size_t size,
       address caller_pc){
-#ifdef ASSERT
     void* p = (void*)AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC));
+#ifdef ASSERT
     if (PrintMallocFree) trace_heap_malloc(size, "CHeapObj-new", p);
-    return p;
-#else
-    return (void *) AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC));
 #endif
+    return p;
   }
 
 template <MEMFLAGS F> void* CHeapObj<F>::operator new (size_t size,
   const std::nothrow_t&  nothrow_constant, address caller_pc) {
-#ifdef ASSERT
   void* p = (void*)AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC),
       AllocFailStrategy::RETURN_NULL);
+#ifdef ASSERT
     if (PrintMallocFree) trace_heap_malloc(size, "CHeapObj-new", p);
-    return p;
-#else
-  return (void *) AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC),
-      AllocFailStrategy::RETURN_NULL);
 #endif
+    return p;
+}
+
+template <MEMFLAGS F> void* CHeapObj<F>::operator new [](size_t size,
+      address caller_pc){
+    return CHeapObj<F>::operator new(size, caller_pc);
+}
+
+template <MEMFLAGS F> void* CHeapObj<F>::operator new [](size_t size,
+  const std::nothrow_t&  nothrow_constant, address caller_pc) {
+    return CHeapObj<F>::operator new(size, nothrow_constant, caller_pc);
 }
 
 template <MEMFLAGS F> void CHeapObj<F>::operator delete(void* p){
-   FreeHeap(p, F);
+    FreeHeap(p, F);
+}
+
+template <MEMFLAGS F> void CHeapObj<F>::operator delete [](void* p){
+    FreeHeap(p, F);
 }
 
 template <class E, MEMFLAGS F>
diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp
index cbe3654..7cc68de 100644
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -80,15 +80,11 @@
 
   _covered   = new MemRegion[max_covered_regions];
   _committed = new MemRegion[max_covered_regions];
-  if (_covered == NULL || _committed == NULL)
+  if (_covered == NULL || _committed == NULL) {
     vm_exit_during_initialization("couldn't alloc card table covered region set.");
-  int i;
-  for (i = 0; i < max_covered_regions; i++) {
-    _covered[i].set_word_size(0);
-    _committed[i].set_word_size(0);
   }
-  _cur_covered_regions = 0;
 
+  _cur_covered_regions = 0;
   const size_t rs_align = _page_size == (size_t) os::vm_page_size() ? 0 :
     MAX2(_page_size, (size_t) os::vm_allocation_granularity());
   ReservedSpace heap_rs(_byte_map_size, rs_align, false);
@@ -134,7 +130,7 @@
       || _lowest_non_clean_base_chunk_index == NULL
       || _last_LNC_resizing_collection == NULL)
     vm_exit_during_initialization("couldn't allocate an LNC array.");
-  for (i = 0; i < max_covered_regions; i++) {
+  for (int i = 0; i < max_covered_regions; i++) {
     _lowest_non_clean[i] = NULL;
     _lowest_non_clean_chunk_size[i] = 0;
     _last_LNC_resizing_collection[i] = -1;
@@ -153,6 +149,33 @@
   }
 }
 
+CardTableModRefBS::~CardTableModRefBS() {
+  if (_covered) {
+    delete[] _covered;
+    _covered = NULL;
+  }
+  if (_committed) {
+    delete[] _committed;
+    _committed = NULL;
+  }
+  if (_lowest_non_clean) {
+    FREE_C_HEAP_ARRAY(CardArr, _lowest_non_clean, mtGC);
+    _lowest_non_clean = NULL;
+  }
+  if (_lowest_non_clean_chunk_size) {
+    FREE_C_HEAP_ARRAY(size_t, _lowest_non_clean_chunk_size, mtGC);
+    _lowest_non_clean_chunk_size = NULL;
+  }
+  if (_lowest_non_clean_base_chunk_index) {
+    FREE_C_HEAP_ARRAY(uintptr_t, _lowest_non_clean_base_chunk_index, mtGC);
+    _lowest_non_clean_base_chunk_index = NULL;
+  }
+  if (_last_LNC_resizing_collection) {
+    FREE_C_HEAP_ARRAY(int, _last_LNC_resizing_collection, mtGC);
+    _last_LNC_resizing_collection = NULL;
+  }
+}
+
 int CardTableModRefBS::find_covering_region_by_base(HeapWord* base) {
   int i;
   for (i = 0; i < _cur_covered_regions; i++) {
diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp
index 69af2da..6b5de2a 100644
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -280,6 +280,7 @@
   }
 
   CardTableModRefBS(MemRegion whole_heap, int max_covered_regions);
+  ~CardTableModRefBS();
 
   // *** Barrier set functions.
 
diff --git a/hotspot/src/share/vm/memory/cardTableRS.cpp b/hotspot/src/share/vm/memory/cardTableRS.cpp
index bd1cd9d..7c21869 100644
--- a/hotspot/src/share/vm/memory/cardTableRS.cpp
+++ b/hotspot/src/share/vm/memory/cardTableRS.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -54,9 +54,10 @@
   _ct_bs = new CardTableModRefBSForCTRS(whole_heap, max_covered_regions);
 #endif
   set_bs(_ct_bs);
-  _last_cur_val_in_gen = new jbyte[GenCollectedHeap::max_gens + 1];
+  _last_cur_val_in_gen = NEW_C_HEAP_ARRAY3(jbyte, GenCollectedHeap::max_gens + 1,
+                         mtGC, 0, AllocFailStrategy::RETURN_NULL);
   if (_last_cur_val_in_gen == NULL) {
-    vm_exit_during_initialization("Could not last_cur_val_in_gen array.");
+    vm_exit_during_initialization("Could not create last_cur_val_in_gen array.");
   }
   for (int i = 0; i < GenCollectedHeap::max_gens + 1; i++) {
     _last_cur_val_in_gen[i] = clean_card_val();
@@ -64,6 +65,16 @@
   _ct_bs->set_CTRS(this);
 }
 
+CardTableRS::~CardTableRS() {
+  if (_ct_bs) {
+    delete _ct_bs;
+    _ct_bs = NULL;
+  }
+  if (_last_cur_val_in_gen) {
+    FREE_C_HEAP_ARRAY(jbyte, _last_cur_val_in_gen, mtInternal);
+  }
+}
+
 void CardTableRS::resize_covered_region(MemRegion new_region) {
   _ct_bs->resize_covered_region(new_region);
 }
diff --git a/hotspot/src/share/vm/memory/cardTableRS.hpp b/hotspot/src/share/vm/memory/cardTableRS.hpp
index 7ac9e41..234b397 100644
--- a/hotspot/src/share/vm/memory/cardTableRS.hpp
+++ b/hotspot/src/share/vm/memory/cardTableRS.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -102,6 +102,7 @@
 
 public:
   CardTableRS(MemRegion whole_heap, int max_covered_regions);
+  ~CardTableRS();
 
   // *** GenRemSet functions.
   GenRemSet::Name rs_kind() { return GenRemSet::CardTable; }
diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp
index c8543d9..cba14a0 100644
--- a/hotspot/src/share/vm/memory/collectorPolicy.cpp
+++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp
@@ -264,6 +264,27 @@
   // need to do this again
   MaxHeapSize = align_size_up(MaxHeapSize, max_alignment());
 
+  // adjust max heap size if necessary
+  if (NewSize + OldSize > MaxHeapSize) {
+    if (FLAG_IS_CMDLINE(MaxHeapSize)) {
+      // somebody set a maximum heap size with the intention that we should not
+      // exceed it. Adjust New/OldSize as necessary.
+      uintx calculated_size = NewSize + OldSize;
+      double shrink_factor = (double) MaxHeapSize / calculated_size;
+      // align
+      NewSize = align_size_down((uintx) (NewSize * shrink_factor), min_alignment());
+      // OldSize is already aligned because above we aligned MaxHeapSize to
+      // max_alignment(), and we just made sure that NewSize is aligned to
+      // min_alignment(). In initialize_flags() we verified that max_alignment()
+      // is a multiple of min_alignment().
+      OldSize = MaxHeapSize - NewSize;
+    } else {
+      MaxHeapSize = NewSize + OldSize;
+    }
+  }
+  // need to do this again
+  MaxHeapSize = align_size_up(MaxHeapSize, max_alignment());
+
   always_do_update_barrier = UseConcMarkSweepGC;
 
   // Check validity of heap flags
@@ -731,7 +752,7 @@
   // free memory should be here, especially if they are expensive. If this
   // attempt fails, an OOM exception will be thrown.
   {
-    IntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted
+    UIntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted
 
     gch->do_collection(true             /* full */,
                        true             /* clear_all_soft_refs */,
@@ -856,7 +877,7 @@
 }
 
 void MarkSweepPolicy::initialize_generations() {
-  _generations = new GenerationSpecPtr[number_of_generations()];
+  _generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC, 0, AllocFailStrategy::RETURN_NULL);
   if (_generations == NULL)
     vm_exit_during_initialization("Unable to allocate gen spec");
 
diff --git a/hotspot/src/share/vm/memory/heapInspection.cpp b/hotspot/src/share/vm/memory/heapInspection.cpp
index a51ea1d..d931049 100644
--- a/hotspot/src/share/vm/memory/heapInspection.cpp
+++ b/hotspot/src/share/vm/memory/heapInspection.cpp
@@ -154,12 +154,12 @@
   }
 }
 
-uint KlassInfoTable::hash(Klass* p) {
+uint KlassInfoTable::hash(const Klass* p) {
   assert(p->is_metadata(), "all klasses are metadata");
   return (uint)(((uintptr_t)p - (uintptr_t)_ref) >> 2);
 }
 
-KlassInfoEntry* KlassInfoTable::lookup(Klass* const k) {
+KlassInfoEntry* KlassInfoTable::lookup(Klass* k) {
   uint         idx = hash(k) % _size;
   assert(_buckets != NULL, "Allocation failure should have been caught");
   KlassInfoEntry*  e   = _buckets[idx].lookup(k);
diff --git a/hotspot/src/share/vm/memory/heapInspection.hpp b/hotspot/src/share/vm/memory/heapInspection.hpp
index a5de455..ccf39ba 100644
--- a/hotspot/src/share/vm/memory/heapInspection.hpp
+++ b/hotspot/src/share/vm/memory/heapInspection.hpp
@@ -189,15 +189,15 @@
   KlassInfoEntry(Klass* k, KlassInfoEntry* next) :
     _klass(k), _instance_count(0), _instance_words(0), _next(next), _index(-1)
   {}
-  KlassInfoEntry* next()     { return _next; }
-  bool is_equal(Klass* k)  { return k == _klass; }
-  Klass* klass()           { return _klass; }
-  long count()               { return _instance_count; }
+  KlassInfoEntry* next() const   { return _next; }
+  bool is_equal(const Klass* k)  { return k == _klass; }
+  Klass* klass()  const      { return _klass; }
+  long count()    const      { return _instance_count; }
   void set_count(long ct)    { _instance_count = ct; }
-  size_t words()             { return _instance_words; }
+  size_t words()  const      { return _instance_words; }
   void set_words(size_t wds) { _instance_words = wds; }
   void set_index(long index) { _index = index; }
-  long index()               { return _index; }
+  long index()    const      { return _index; }
   int compare(KlassInfoEntry* e1, KlassInfoEntry* e2);
   void print_on(outputStream* st) const;
   const char* name() const;
@@ -215,7 +215,7 @@
   KlassInfoEntry* list()           { return _list; }
   void set_list(KlassInfoEntry* l) { _list = l; }
  public:
-  KlassInfoEntry* lookup(Klass* const k);
+  KlassInfoEntry* lookup(Klass* k);
   void initialize() { _list = NULL; }
   void empty();
   void iterate(KlassInfoClosure* cic);
@@ -231,8 +231,8 @@
   HeapWord* _ref;
 
   KlassInfoBucket* _buckets;
-  uint hash(Klass* p);
-  KlassInfoEntry* lookup(Klass* const k); // allocates if not found!
+  uint hash(const Klass* p);
+  KlassInfoEntry* lookup(Klass* k); // allocates if not found!
 
   class AllClassesFinder : public KlassClosure {
     KlassInfoTable *_table;
diff --git a/hotspot/src/share/vm/memory/memRegion.cpp b/hotspot/src/share/vm/memory/memRegion.cpp
index 70483f9..baabdb8 100644
--- a/hotspot/src/share/vm/memory/memRegion.cpp
+++ b/hotspot/src/share/vm/memory/memRegion.cpp
@@ -23,6 +23,8 @@
  */
 
 #include "precompiled.hpp"
+#include "memory/allocation.hpp"
+#include "memory/allocation.inline.hpp"
 #include "memory/memRegion.hpp"
 #include "runtime/globals.hpp"
 
@@ -99,3 +101,19 @@
   ShouldNotReachHere();
   return MemRegion();
 }
+
+void* MemRegion::operator new(size_t size) {
+  return (address)AllocateHeap(size, mtGC, 0, AllocFailStrategy::RETURN_NULL);
+}
+
+void* MemRegion::operator new [](size_t size) {
+  return (address)AllocateHeap(size, mtGC, 0, AllocFailStrategy::RETURN_NULL);
+}
+void  MemRegion::operator delete(void* p) {
+  FreeHeap(p, mtGC);
+}
+
+void  MemRegion::operator delete [](void* p) {
+  FreeHeap(p, mtGC);
+}
+
diff --git a/hotspot/src/share/vm/memory/memRegion.hpp b/hotspot/src/share/vm/memory/memRegion.hpp
index 66f90f3..600d275 100644
--- a/hotspot/src/share/vm/memory/memRegion.hpp
+++ b/hotspot/src/share/vm/memory/memRegion.hpp
@@ -34,7 +34,9 @@
 
 // Note that MemRegions are passed by value, not by reference.
 // The intent is that they remain very small and contain no
-// objects.
+// objects. _ValueObj should never be allocated in heap but we do
+// create MemRegions (in CardTableModRefBS) in heap so operator
+// new and operator new [] added for this special case.
 
 class MetaWord;
 
@@ -92,6 +94,10 @@
   size_t word_size() const { return _word_size; }
 
   bool is_empty() const { return word_size() == 0; }
+  void* operator new(size_t size);
+  void* operator new [](size_t size);
+  void  operator delete(void* p);
+  void  operator delete [](void* p);
 };
 
 // For iteration over MemRegion's.
diff --git a/hotspot/src/share/vm/memory/space.hpp b/hotspot/src/share/vm/memory/space.hpp
index a434b0a..eb1e209 100644
--- a/hotspot/src/share/vm/memory/space.hpp
+++ b/hotspot/src/share/vm/memory/space.hpp
@@ -537,9 +537,8 @@
    * Occasionally, we want to ensure a full compaction, which is determined  \
    * by the MarkSweepAlwaysCompactCount parameter.                           \
    */                                                                        \
-  int invocations = MarkSweep::total_invocations();                          \
-  bool skip_dead = (MarkSweepAlwaysCompactCount < 1)                         \
-    ||((invocations % MarkSweepAlwaysCompactCount) != 0);                    \
+  uint invocations = MarkSweep::total_invocations();                         \
+  bool skip_dead = ((invocations % MarkSweepAlwaysCompactCount) != 0);       \
                                                                              \
   size_t allowed_deadspace = 0;                                              \
   if (skip_dead) {                                                           \
diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp
index a0849df..77fc4b8 100644
--- a/hotspot/src/share/vm/memory/universe.cpp
+++ b/hotspot/src/share/vm/memory/universe.cpp
@@ -1425,25 +1425,25 @@
 }
 
 
-void ActiveMethodOopsCache::add_previous_version(Method* const method) {
+void ActiveMethodOopsCache::add_previous_version(Method* method) {
   assert(Thread::current()->is_VM_thread(),
     "only VMThread can add previous versions");
 
   // Only append the previous method if it is executing on the stack.
   if (method->on_stack()) {
 
-  if (_prev_methods == NULL) {
-    // This is the first previous version so make some space.
-    // Start with 2 elements under the assumption that the class
-    // won't be redefined much.
+    if (_prev_methods == NULL) {
+      // This is the first previous version so make some space.
+      // Start with 2 elements under the assumption that the class
+      // won't be redefined much.
       _prev_methods = new (ResourceObj::C_HEAP, mtClass) GrowableArray<Method*>(2, true);
-  }
+    }
 
-  // RC_TRACE macro has an embedded ResourceMark
-  RC_TRACE(0x00000100,
-    ("add: %s(%s): adding prev version ref for cached method @%d",
-    method->name()->as_C_string(), method->signature()->as_C_string(),
-    _prev_methods->length()));
+    // RC_TRACE macro has an embedded ResourceMark
+    RC_TRACE(0x00000100,
+      ("add: %s(%s): adding prev version ref for cached method @%d",
+        method->name()->as_C_string(), method->signature()->as_C_string(),
+        _prev_methods->length()));
 
     _prev_methods->append(method);
   }
@@ -1464,16 +1464,17 @@
       MetadataFactory::free_metadata(method->method_holder()->class_loader_data(), method);
     } else {
       // RC_TRACE macro has an embedded ResourceMark
-      RC_TRACE(0x00000400, ("add: %s(%s): previous cached method @%d is alive",
-        method->name()->as_C_string(), method->signature()->as_C_string(), i));
+      RC_TRACE(0x00000400,
+        ("add: %s(%s): previous cached method @%d is alive",
+         method->name()->as_C_string(), method->signature()->as_C_string(), i));
     }
   }
 } // end add_previous_version()
 
 
-bool ActiveMethodOopsCache::is_same_method(Method* const method) const {
+bool ActiveMethodOopsCache::is_same_method(const Method* method) const {
   InstanceKlass* ik = InstanceKlass::cast(klass());
-  Method* check_method = ik->method_with_idnum(method_idnum());
+  const Method* check_method = ik->method_with_idnum(method_idnum());
   assert(check_method != NULL, "sanity check");
   if (check_method == method) {
     // done with the easy case
diff --git a/hotspot/src/share/vm/memory/universe.hpp b/hotspot/src/share/vm/memory/universe.hpp
index 48d32f7..6daf75d 100644
--- a/hotspot/src/share/vm/memory/universe.hpp
+++ b/hotspot/src/share/vm/memory/universe.hpp
@@ -90,8 +90,8 @@
   ActiveMethodOopsCache()   { _prev_methods = NULL; }
   ~ActiveMethodOopsCache();
 
-  void add_previous_version(Method* const method);
-  bool is_same_method(Method* const method) const;
+  void add_previous_version(Method* method);
+  bool is_same_method(const Method* method) const;
 };
 
 
diff --git a/hotspot/src/share/vm/oops/constantPool.hpp b/hotspot/src/share/vm/oops/constantPool.hpp
index 58cad7a..eca2dcd 100644
--- a/hotspot/src/share/vm/oops/constantPool.hpp
+++ b/hotspot/src/share/vm/oops/constantPool.hpp
@@ -354,7 +354,7 @@
 
   Symbol* klass_name_at(int which);  // Returns the name, w/o resolving.
 
-  Klass* resolved_klass_at(int which) {  // Used by Compiler
+  Klass* resolved_klass_at(int which) const {  // Used by Compiler
     guarantee(tag_at(which).is_klass(), "Corrupted constant pool");
     // Must do an acquire here in case another thread resolved the klass
     // behind our back, lest we later load stale values thru the oop.
diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
index ecb0dcb..06827e6 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
@@ -2724,7 +2724,7 @@
   OsrList_lock->unlock();
 }
 
-nmethod* InstanceKlass::lookup_osr_nmethod(Method* const m, int bci, int comp_level, bool match_level) const {
+nmethod* InstanceKlass::lookup_osr_nmethod(const Method* m, int bci, int comp_level, bool match_level) const {
   // This is a short non-blocking critical region, so the no safepoint check is ok.
   OsrList_lock->lock_without_safepoint_check();
   nmethod* osr = osr_nmethods_head();
diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp
index 55b8ff4..8ee9adc 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp
@@ -739,7 +739,7 @@
   void set_osr_nmethods_head(nmethod* h)     { _osr_nmethods_head = h; };
   void add_osr_nmethod(nmethod* n);
   void remove_osr_nmethod(nmethod* n);
-  nmethod* lookup_osr_nmethod(Method* const m, int bci, int level, bool match_level) const;
+  nmethod* lookup_osr_nmethod(const Method* m, int bci, int level, bool match_level) const;
 
   // Breakpoint support (see methods on Method* for details)
   BreakpointInfo* breakpoints() const       { return _breakpoints; };
diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp
index 06c644c..52dd264 100644
--- a/hotspot/src/share/vm/oops/klass.cpp
+++ b/hotspot/src/share/vm/oops/klass.cpp
@@ -50,7 +50,7 @@
   if (_name != NULL) _name->increment_refcount();
 }
 
-bool Klass::is_subclass_of(Klass* k) const {
+bool Klass::is_subclass_of(const Klass* k) const {
   // Run up the super chain and check
   if (this == k) return true;
 
diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp
index d2a4191..acd402c 100644
--- a/hotspot/src/share/vm/oops/klass.hpp
+++ b/hotspot/src/share/vm/oops/klass.hpp
@@ -393,9 +393,10 @@
 
   // vtables
   virtual klassVtable* vtable() const        { return NULL; }
+  virtual int vtable_length() const          { return 0; }
 
   // subclass check
-  bool is_subclass_of(Klass* k) const;
+  bool is_subclass_of(const Klass* k) const;
   // subtype check: true if is_subclass_of, or if k is interface and receiver implements it
   bool is_subtype_of(Klass* k) const {
     juint    off = k->super_check_offset();
diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp
index 74364c3..62b81ea 100644
--- a/hotspot/src/share/vm/oops/method.cpp
+++ b/hotspot/src/share/vm/oops/method.cpp
@@ -832,7 +832,9 @@
   assert(entry != NULL, "interpreter entry must be non-null");
   // Sets both _i2i_entry and _from_interpreted_entry
   set_interpreter_entry(entry);
-  if (is_native() && !is_method_handle_intrinsic()) {
+
+  // Don't overwrite already registered native entries.
+  if (is_native() && !has_native_function()) {
     set_native_function(
       SharedRuntime::native_method_throw_unsatisfied_link_error_entry(),
       !native_bind_event_is_interesting);
@@ -1581,7 +1583,7 @@
 }
 
 int Method::highest_comp_level() const {
-  MethodData* mdo = method_data();
+  const MethodData* mdo = method_data();
   if (mdo != NULL) {
     return mdo->highest_comp_level();
   } else {
@@ -1590,7 +1592,7 @@
 }
 
 int Method::highest_osr_comp_level() const {
-  MethodData* mdo = method_data();
+  const MethodData* mdo = method_data();
   if (mdo != NULL) {
     return mdo->highest_osr_comp_level();
   } else {
diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp
index 7e2696a..54c2647 100644
--- a/hotspot/src/share/vm/oops/method.hpp
+++ b/hotspot/src/share/vm/oops/method.hpp
@@ -986,7 +986,7 @@
   u2  _length;
 
  public:
-  ExceptionTable(Method* m) {
+  ExceptionTable(const Method* m) {
     if (m->has_exception_handler()) {
       _table = m->exception_table_start();
       _length = m->exception_table_length();
diff --git a/hotspot/src/share/vm/oops/methodData.hpp b/hotspot/src/share/vm/oops/methodData.hpp
index b9fc63e..765b91c 100644
--- a/hotspot/src/share/vm/oops/methodData.hpp
+++ b/hotspot/src/share/vm/oops/methodData.hpp
@@ -1338,9 +1338,9 @@
   void set_would_profile(bool p)              { _would_profile = p;    }
   bool would_profile() const                  { return _would_profile; }
 
-  int highest_comp_level()                    { return _highest_comp_level;      }
+  int highest_comp_level() const              { return _highest_comp_level;      }
   void set_highest_comp_level(int level)      { _highest_comp_level = level;     }
-  int highest_osr_comp_level()                { return _highest_osr_comp_level;  }
+  int highest_osr_comp_level() const          { return _highest_osr_comp_level;  }
   void set_highest_osr_comp_level(int level)  { _highest_osr_comp_level = level; }
 
   int num_loops() const                       { return _num_loops;  }
diff --git a/hotspot/src/share/vm/opto/bytecodeInfo.cpp b/hotspot/src/share/vm/opto/bytecodeInfo.cpp
index 6d8f1b3..9d2a36b 100644
--- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp
+++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp
@@ -85,16 +85,35 @@
   assert(!UseOldInlining, "do not use for old stuff");
 }
 
+/**
+ *  Return true when EA is ON and a java constructor is called or
+ *  a super constructor is called from an inlined java constructor.
+ *  Also return true for boxing methods.
+ */
 static bool is_init_with_ea(ciMethod* callee_method,
                             ciMethod* caller_method, Compile* C) {
-  // True when EA is ON and a java constructor is called or
-  // a super constructor is called from an inlined java constructor.
-  return C->do_escape_analysis() && EliminateAllocations &&
-         ( callee_method->is_initializer() ||
-           (caller_method->is_initializer() &&
-            caller_method != C->method() &&
-            caller_method->holder()->is_subclass_of(callee_method->holder()))
-         );
+  if (!C->do_escape_analysis() || !EliminateAllocations) {
+    return false; // EA is off
+  }
+  if (callee_method->is_initializer()) {
+    return true; // constuctor
+  }
+  if (caller_method->is_initializer() &&
+      caller_method != C->method() &&
+      caller_method->holder()->is_subclass_of(callee_method->holder())) {
+    return true; // super constructor is called from inlined constructor
+  }
+  if (C->eliminate_boxing() && callee_method->is_boxing_method()) {
+    return true;
+  }
+  return false;
+}
+
+/**
+ *  Force inlining unboxing accessor.
+ */
+static bool is_unboxing_method(ciMethod* callee_method, Compile* C) {
+  return C->eliminate_boxing() && callee_method->is_unboxing_method();
 }
 
 // positive filter: should callee be inlined?
@@ -144,6 +163,7 @@
   // bump the max size if the call is frequent
   if ((freq >= InlineFrequencyRatio) ||
       (call_site_count >= InlineFrequencyCount) ||
+      is_unboxing_method(callee_method, C) ||
       is_init_with_ea(callee_method, caller_method, C)) {
 
     max_inline_size = C->freq_inline_size();
@@ -237,8 +257,25 @@
     return false;
   }
 
+  if (callee_method->should_not_inline()) {
+    set_msg("disallowed by CompilerOracle");
+    return true;
+  }
+
+#ifndef PRODUCT
+  if (ciReplay::should_not_inline(callee_method)) {
+    set_msg("disallowed by ciReplay");
+    return true;
+  }
+#endif
+
   // Now perform checks which are heuristic
 
+  if (is_unboxing_method(callee_method, C)) {
+    // Inline unboxing methods.
+    return false;
+  }
+
   if (!callee_method->force_inline()) {
     if (callee_method->has_compiled_code() &&
         callee_method->instructions_size() > InlineSmallCode) {
@@ -260,18 +297,6 @@
     }
   }
 
-  if (callee_method->should_not_inline()) {
-    set_msg("disallowed by CompilerOracle");
-    return true;
-  }
-
-#ifndef PRODUCT
-  if (ciReplay::should_not_inline(callee_method)) {
-    set_msg("disallowed by ciReplay");
-    return true;
-  }
-#endif
-
   if (UseStringCache) {
     // Do not inline StringCache::profile() method used only at the beginning.
     if (callee_method->name() == ciSymbol::profile_name() &&
@@ -296,9 +321,8 @@
     }
 
     if (is_init_with_ea(callee_method, caller_method, C)) {
-
       // Escape Analysis: inline all executed constructors
-
+      return false;
     } else if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold,
                                                            CompileThreshold >> 1))) {
       set_msg("executed < MinInliningThreshold times");
diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp
index f01101c..49ed1e8 100644
--- a/hotspot/src/share/vm/opto/c2_globals.hpp
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp
@@ -442,12 +442,15 @@
   notproduct(bool, PrintEliminateLocks, false,                              \
           "Print out when locks are eliminated")                            \
                                                                             \
-  diagnostic(bool, EliminateAutoBox, false,                                 \
-          "Private flag to control optimizations for autobox elimination")  \
+  product(bool, EliminateAutoBox, true,                                     \
+          "Control optimizations for autobox elimination")                  \
                                                                             \
   product(intx, AutoBoxCacheMax, 128,                                       \
           "Sets max value cached by the java.lang.Integer autobox cache")   \
                                                                             \
+  experimental(bool, AggressiveUnboxing, false,                             \
+          "Control optimizations for aggressive boxing elimination")        \
+                                                                            \
   product(bool, DoEscapeAnalysis, true,                                     \
           "Perform escape analysis")                                        \
                                                                             \
diff --git a/hotspot/src/share/vm/opto/c2compiler.cpp b/hotspot/src/share/vm/opto/c2compiler.cpp
index 713e3f1..85f30a5 100644
--- a/hotspot/src/share/vm/opto/c2compiler.cpp
+++ b/hotspot/src/share/vm/opto/c2compiler.cpp
@@ -125,9 +125,10 @@
   bool subsume_loads = SubsumeLoads;
   bool do_escape_analysis = DoEscapeAnalysis &&
     !env->jvmti_can_access_local_variables();
+  bool eliminate_boxing = EliminateAutoBox;
   while (!env->failing()) {
     // Attempt to compile while subsuming loads into machine instructions.
-    Compile C(env, this, target, entry_bci, subsume_loads, do_escape_analysis);
+    Compile C(env, this, target, entry_bci, subsume_loads, do_escape_analysis, eliminate_boxing);
 
 
     // Check result and retry if appropriate.
@@ -142,6 +143,12 @@
         do_escape_analysis = false;
         continue;  // retry
       }
+      if (C.has_boxed_value()) {
+        // Recompile without boxing elimination regardless failure reason.
+        assert(eliminate_boxing, "must make progress");
+        eliminate_boxing = false;
+        continue;  // retry
+      }
       // Pass any other failure reason up to the ciEnv.
       // Note that serious, irreversible failures are already logged
       // on the ciEnv via env->record_method_not_compilable().
diff --git a/hotspot/src/share/vm/opto/callGenerator.cpp b/hotspot/src/share/vm/opto/callGenerator.cpp
index 8cac8ee..470a36e 100644
--- a/hotspot/src/share/vm/opto/callGenerator.cpp
+++ b/hotspot/src/share/vm/opto/callGenerator.cpp
@@ -134,7 +134,7 @@
     kit.C->log()->elem("direct_call bci='%d'", jvms->bci());
   }
 
-  CallStaticJavaNode *call = new (kit.C) CallStaticJavaNode(tf(), target, method(), kit.bci());
+  CallStaticJavaNode *call = new (kit.C) CallStaticJavaNode(kit.C, tf(), target, method(), kit.bci());
   _call_node = call;  // Save the call node in case we need it later
   if (!is_static) {
     // Make an explicit receiver null_check as part of this call.
@@ -304,29 +304,34 @@
 
 void LateInlineCallGenerator::do_late_inline() {
   // Can't inline it
-  if (call_node() == NULL || call_node()->outcnt() == 0 ||
-      call_node()->in(0) == NULL || call_node()->in(0)->is_top()) {
+  CallStaticJavaNode* call = call_node();
+  if (call == NULL || call->outcnt() == 0 ||
+      call->in(0) == NULL || call->in(0)->is_top()) {
     return;
   }
 
-  const TypeTuple *r = call_node()->tf()->domain();
+  const TypeTuple *r = call->tf()->domain();
   for (int i1 = 0; i1 < method()->arg_size(); i1++) {
-    if (call_node()->in(TypeFunc::Parms + i1)->is_top() && r->field_at(TypeFunc::Parms + i1) != Type::HALF) {
+    if (call->in(TypeFunc::Parms + i1)->is_top() && r->field_at(TypeFunc::Parms + i1) != Type::HALF) {
       assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing");
       return;
     }
   }
 
-  if (call_node()->in(TypeFunc::Memory)->is_top()) {
+  if (call->in(TypeFunc::Memory)->is_top()) {
     assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing");
     return;
   }
 
-  CallStaticJavaNode* call = call_node();
+  Compile* C = Compile::current();
+  // Remove inlined methods from Compiler's lists.
+  if (call->is_macro()) {
+    C->remove_macro_node(call);
+  }
 
   // Make a clone of the JVMState that appropriate to use for driving a parse
-  Compile* C = Compile::current();
-  JVMState* jvms     = call->jvms()->clone_shallow(C);
+  JVMState* old_jvms = call->jvms();
+  JVMState* jvms = old_jvms->clone_shallow(C);
   uint size = call->req();
   SafePointNode* map = new (C) SafePointNode(size, jvms);
   for (uint i1 = 0; i1 < size; i1++) {
@@ -340,16 +345,23 @@
     map->set_req(TypeFunc::Memory, mem);
   }
 
-  // Make enough space for the expression stack and transfer the incoming arguments
-  int nargs    = method()->arg_size();
+  uint nargs = method()->arg_size();
+  // blow away old call arguments
+  Node* top = C->top();
+  for (uint i1 = 0; i1 < nargs; i1++) {
+    map->set_req(TypeFunc::Parms + i1, top);
+  }
   jvms->set_map(map);
+
+  // Make enough space in the expression stack to transfer
+  // the incoming arguments and return value.
   map->ensure_stack(jvms, jvms->method()->max_stack());
-  if (nargs > 0) {
-    for (int i1 = 0; i1 < nargs; i1++) {
-      map->set_req(i1 + jvms->argoff(), call->in(TypeFunc::Parms + i1));
-    }
+  for (uint i1 = 0; i1 < nargs; i1++) {
+    map->set_argument(jvms, i1, call->in(TypeFunc::Parms + i1));
   }
 
+  // This check is done here because for_method_handle_inline() method
+  // needs jvms for inlined state.
   if (!do_late_inline_check(jvms)) {
     map->disconnect_inputs(NULL, C);
     return;
@@ -480,6 +492,26 @@
   return new LateInlineStringCallGenerator(method, inline_cg);
 }
 
+class LateInlineBoxingCallGenerator : public LateInlineCallGenerator {
+
+ public:
+  LateInlineBoxingCallGenerator(ciMethod* method, CallGenerator* inline_cg) :
+    LateInlineCallGenerator(method, inline_cg) {}
+
+  virtual JVMState* generate(JVMState* jvms) {
+    Compile *C = Compile::current();
+    C->print_inlining_skip(this);
+
+    C->add_boxing_late_inline(this);
+
+    JVMState* new_jvms =  DirectCallGenerator::generate(jvms);
+    return new_jvms;
+  }
+};
+
+CallGenerator* CallGenerator::for_boxing_late_inline(ciMethod* method, CallGenerator* inline_cg) {
+  return new LateInlineBoxingCallGenerator(method, inline_cg);
+}
 
 //---------------------------WarmCallGenerator--------------------------------
 // Internal class which handles initial deferral of inlining decisions.
diff --git a/hotspot/src/share/vm/opto/callGenerator.hpp b/hotspot/src/share/vm/opto/callGenerator.hpp
index 7051dbe..8cdc4e8 100644
--- a/hotspot/src/share/vm/opto/callGenerator.hpp
+++ b/hotspot/src/share/vm/opto/callGenerator.hpp
@@ -125,6 +125,7 @@
   static CallGenerator* for_late_inline(ciMethod* m, CallGenerator* inline_cg);
   static CallGenerator* for_mh_late_inline(ciMethod* caller, ciMethod* callee, bool input_not_const);
   static CallGenerator* for_string_late_inline(ciMethod* m, CallGenerator* inline_cg);
+  static CallGenerator* for_boxing_late_inline(ciMethod* m, CallGenerator* inline_cg);
 
   // How to make a call but defer the decision whether to inline or not.
   static CallGenerator* for_warm_call(WarmCallInfo* ci,
diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp
index c90b76d..cce6c5f 100644
--- a/hotspot/src/share/vm/opto/callnode.cpp
+++ b/hotspot/src/share/vm/opto/callnode.cpp
@@ -523,7 +523,9 @@
 
 
 void JVMState::dump_on(outputStream* st) const {
-  if (_map && !((uintptr_t)_map & 1)) {
+  bool print_map = _map && !((uintptr_t)_map & 1) &&
+                  ((caller() == NULL) || (caller()->map() != _map));
+  if (print_map) {
     if (_map->len() > _map->req()) {  // _map->has_exceptions()
       Node* ex = _map->in(_map->req());  // _map->next_exception()
       // skip the first one; it's already being printed
@@ -532,7 +534,10 @@
         ex->dump(1);
       }
     }
-    _map->dump(2);
+    _map->dump(Verbose ? 2 : 1);
+  }
+  if (caller() != NULL) {
+    caller()->dump_on(st);
   }
   st->print("JVMS depth=%d loc=%d stk=%d arg=%d mon=%d scalar=%d end=%d mondepth=%d sp=%d bci=%d reexecute=%s method=",
              depth(), locoff(), stkoff(), argoff(), monoff(), scloff(), endoff(), monitor_depth(), sp(), bci(), should_reexecute()?"true":"false");
@@ -546,9 +551,6 @@
       _method->print_codes_on(bci(), bci()+1, st);
     }
   }
-  if (caller() != NULL) {
-    caller()->dump_on(st);
-  }
 }
 
 // Extra way to dump a jvms from the debugger,
@@ -584,6 +586,15 @@
   return n;
 }
 
+/**
+ * Reset map for all callers
+ */
+void JVMState::set_map_deep(SafePointNode* map) {
+  for (JVMState* p = this; p->_caller != NULL; p = p->_caller) {
+    p->set_map(map);
+  }
+}
+
 //=============================================================================
 uint CallNode::cmp( const Node &n ) const
 { return _tf == ((CallNode&)n)._tf && _jvms == ((CallNode&)n)._jvms; }
@@ -663,17 +674,49 @@
 // Determine whether the call could modify the field of the specified
 // instance at the specified offset.
 //
-bool CallNode::may_modify(const TypePtr *addr_t, PhaseTransform *phase) {
-  const TypeOopPtr *adrInst_t  = addr_t->isa_oopptr();
-
-  // If not an OopPtr or not an instance type, assume the worst.
-  // Note: currently this method is called only for instance types.
-  if (adrInst_t == NULL || !adrInst_t->is_known_instance()) {
-    return true;
+bool CallNode::may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase) {
+  assert((t_oop != NULL), "sanity");
+  if (t_oop->is_known_instance()) {
+    // The instance_id is set only for scalar-replaceable allocations which
+    // are not passed as arguments according to Escape Analysis.
+    return false;
   }
-  // The instance_id is set only for scalar-replaceable allocations which
-  // are not passed as arguments according to Escape Analysis.
-  return false;
+  if (t_oop->is_ptr_to_boxed_value()) {
+    ciKlass* boxing_klass = t_oop->klass();
+    if (is_CallStaticJava() && as_CallStaticJava()->is_boxing_method()) {
+      // Skip unrelated boxing methods.
+      Node* proj = proj_out(TypeFunc::Parms);
+      if ((proj == NULL) || (phase->type(proj)->is_instptr()->klass() != boxing_klass)) {
+        return false;
+      }
+    }
+    if (is_CallJava() && as_CallJava()->method() != NULL) {
+      ciMethod* meth = as_CallJava()->method();
+      if (meth->is_accessor()) {
+        return false;
+      }
+      // May modify (by reflection) if an boxing object is passed
+      // as argument or returned.
+      if (returns_pointer() && (proj_out(TypeFunc::Parms) != NULL)) {
+        Node* proj = proj_out(TypeFunc::Parms);
+        const TypeInstPtr* inst_t = phase->type(proj)->isa_instptr();
+        if ((inst_t != NULL) && (!inst_t->klass_is_exact() ||
+                                 (inst_t->klass() == boxing_klass))) {
+          return true;
+        }
+      }
+      const TypeTuple* d = tf()->domain();
+      for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
+        const TypeInstPtr* inst_t = d->field_at(i)->isa_instptr();
+        if ((inst_t != NULL) && (!inst_t->klass_is_exact() ||
+                                 (inst_t->klass() == boxing_klass))) {
+          return true;
+        }
+      }
+      return false;
+    }
+  }
+  return true;
 }
 
 // Does this call have a direct reference to n other than debug information?
@@ -1020,6 +1063,7 @@
   int scloff = jvms->scloff();
   int endoff = jvms->endoff();
   assert(endoff == (int)req(), "no other states or debug info after me");
+  assert(jvms->scl_size() == 0, "parsed code should not have scalar objects");
   Node* top = Compile::current()->top();
   for (uint i = 0; i < grow_by; i++) {
     ins_req(monoff, top);
@@ -1035,6 +1079,7 @@
   const int MonitorEdges = 2;
   assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges");
   assert(req() == jvms()->endoff(), "correct sizing");
+  assert((jvms()->scl_size() == 0), "parsed code should not have scalar objects");
   int nextmon = jvms()->scloff();
   if (GenerateSynchronizationCode) {
     add_req(lock->box_node());
@@ -1050,6 +1095,7 @@
 
 void SafePointNode::pop_monitor() {
   // Delete last monitor from debug info
+  assert((jvms()->scl_size() == 0), "parsed code should not have scalar objects");
   debug_only(int num_before_pop = jvms()->nof_monitors());
   const int MonitorEdges = (1<<JVMState::logMonitorEdges);
   int scloff = jvms()->scloff();
@@ -1154,6 +1200,7 @@
   init_class_id(Class_Allocate);
   init_flags(Flag_is_macro);
   _is_scalar_replaceable = false;
+  _is_non_escaping = false;
   Node *topnode = C->top();
 
   init_req( TypeFunc::Control  , ctrl );
@@ -1169,8 +1216,6 @@
 }
 
 //=============================================================================
-uint AllocateArrayNode::size_of() const { return sizeof(*this); }
-
 Node* AllocateArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) {
   if (remove_dead_region(phase, can_reshape))  return this;
   // Don't bother trying to transform a dead node
@@ -1235,6 +1280,8 @@
       //   - the narrow_length is 0
       //   - the narrow_length is not wider than length
       assert(narrow_length_type == TypeInt::ZERO ||
+             length_type->is_con() && narrow_length_type->is_con() &&
+                (narrow_length_type->_hi <= length_type->_lo) ||
              (narrow_length_type->_hi <= length_type->_hi &&
               narrow_length_type->_lo >= length_type->_lo),
              "narrow type must be narrower than length type");
diff --git a/hotspot/src/share/vm/opto/callnode.hpp b/hotspot/src/share/vm/opto/callnode.hpp
index 0aa35c2..ebcca02 100644
--- a/hotspot/src/share/vm/opto/callnode.hpp
+++ b/hotspot/src/share/vm/opto/callnode.hpp
@@ -49,6 +49,7 @@
 class         CallLeafNoFPNode;
 class     AllocateNode;
 class       AllocateArrayNode;
+class     BoxLockNode;
 class     LockNode;
 class     UnlockNode;
 class JVMState;
@@ -235,7 +236,6 @@
 
   int            loc_size() const { return stkoff() - locoff(); }
   int            stk_size() const { return monoff() - stkoff(); }
-  int            arg_size() const { return monoff() - argoff(); }
   int            mon_size() const { return scloff() - monoff(); }
   int            scl_size() const { return endoff() - scloff(); }
 
@@ -298,6 +298,7 @@
   // Miscellaneous utility functions
   JVMState* clone_deep(Compile* C) const;    // recursively clones caller chain
   JVMState* clone_shallow(Compile* C) const; // retains uncloned caller
+  void      set_map_deep(SafePointNode *map);// reset map for all callers
 
 #ifndef PRODUCT
   void      format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const;
@@ -439,7 +440,7 @@
   static  bool           needs_polling_address_input();
 
 #ifndef PRODUCT
-  virtual void              dump_spec(outputStream *st) const;
+  virtual void           dump_spec(outputStream *st) const;
 #endif
 };
 
@@ -554,10 +555,10 @@
   virtual bool        guaranteed_safepoint()  { return true; }
   // For macro nodes, the JVMState gets modified during expansion, so when cloning
   // the node the JVMState must be cloned.
-  virtual void        clone_jvms() { }   // default is not to clone
+  virtual void        clone_jvms(Compile* C) { }   // default is not to clone
 
   // Returns true if the call may modify n
-  virtual bool        may_modify(const TypePtr *addr_t, PhaseTransform *phase);
+  virtual bool        may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase);
   // Does this node have a use of n other than in debug information?
   bool                has_non_debug_use(Node *n);
   // Returns the unique CheckCastPP of a call
@@ -630,9 +631,15 @@
   virtual uint cmp( const Node &n ) const;
   virtual uint size_of() const; // Size is bigger
 public:
-  CallStaticJavaNode(const TypeFunc* tf, address addr, ciMethod* method, int bci)
+  CallStaticJavaNode(Compile* C, const TypeFunc* tf, address addr, ciMethod* method, int bci)
     : CallJavaNode(tf, addr, method, bci), _name(NULL) {
     init_class_id(Class_CallStaticJava);
+    if (C->eliminate_boxing() && (method != NULL) && method->is_boxing_method()) {
+      init_flags(Flag_is_macro);
+      C->add_macro_node(this);
+    }
+    _is_scalar_replaceable = false;
+    _is_non_escaping = false;
   }
   CallStaticJavaNode(const TypeFunc* tf, address addr, const char* name, int bci,
                      const TypePtr* adr_type)
@@ -640,13 +647,31 @@
     init_class_id(Class_CallStaticJava);
     // This node calls a runtime stub, which often has narrow memory effects.
     _adr_type = adr_type;
+    _is_scalar_replaceable = false;
+    _is_non_escaping = false;
   }
-  const char *_name;            // Runtime wrapper name
+  const char *_name;      // Runtime wrapper name
+
+  // Result of Escape Analysis
+  bool _is_scalar_replaceable;
+  bool _is_non_escaping;
 
   // If this is an uncommon trap, return the request code, else zero.
   int uncommon_trap_request() const;
   static int extract_uncommon_trap_request(const Node* call);
 
+  bool is_boxing_method() const {
+    return is_macro() && (method() != NULL) && method()->is_boxing_method();
+  }
+  // Later inlining modifies the JVMState, so we need to clone it
+  // when the call node is cloned (because it is macro node).
+  virtual void  clone_jvms(Compile* C) {
+    if ((jvms() != NULL) && is_boxing_method()) {
+      set_jvms(jvms()->clone_deep(C));
+      jvms()->set_map_deep(this);
+    }
+  }
+
   virtual int         Opcode() const;
 #ifndef PRODUCT
   virtual void        dump_spec(outputStream *st) const;
@@ -748,12 +773,12 @@
     ParmLimit
   };
 
-  static const TypeFunc* alloc_type() {
+  static const TypeFunc* alloc_type(const Type* t) {
     const Type** fields = TypeTuple::fields(ParmLimit - TypeFunc::Parms);
     fields[AllocSize]   = TypeInt::POS;
     fields[KlassNode]   = TypeInstPtr::NOTNULL;
     fields[InitialTest] = TypeInt::BOOL;
-    fields[ALength]     = TypeInt::INT;  // length (can be a bad length)
+    fields[ALength]     = t;  // length (can be a bad length)
 
     const TypeTuple *domain = TypeTuple::make(ParmLimit, fields);
 
@@ -766,21 +791,26 @@
     return TypeFunc::make(domain, range);
   }
 
-  bool _is_scalar_replaceable;  // Result of Escape Analysis
+  // Result of Escape Analysis
+  bool _is_scalar_replaceable;
+  bool _is_non_escaping;
 
   virtual uint size_of() const; // Size is bigger
   AllocateNode(Compile* C, const TypeFunc *atype, Node *ctrl, Node *mem, Node *abio,
                Node *size, Node *klass_node, Node *initial_test);
   // Expansion modifies the JVMState, so we need to clone it
-  virtual void  clone_jvms() {
-    set_jvms(jvms()->clone_deep(Compile::current()));
+  virtual void  clone_jvms(Compile* C) {
+    if (jvms() != NULL) {
+      set_jvms(jvms()->clone_deep(C));
+      jvms()->set_map_deep(this);
+    }
   }
   virtual int Opcode() const;
   virtual uint ideal_reg() const { return Op_RegP; }
   virtual bool        guaranteed_safepoint()  { return false; }
 
   // allocations do not modify their arguments
-  virtual bool        may_modify(const TypePtr *addr_t, PhaseTransform *phase) { return false;}
+  virtual bool        may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase) { return false;}
 
   // Pattern-match a possible usage of AllocateNode.
   // Return null if no allocation is recognized.
@@ -815,10 +845,6 @@
   // are defined in graphKit.cpp, which sets up the bidirectional relation.)
   InitializeNode* initialization();
 
-  // Return the corresponding storestore barrier (or null if none).
-  // Walks out edges to find it...
-  MemBarStoreStoreNode* storestore();
-
   // Convenience for initialization->maybe_set_complete(phase)
   bool maybe_set_complete(PhaseGVN* phase);
 };
@@ -840,7 +866,6 @@
     set_req(AllocateNode::ALength,        count_val);
   }
   virtual int Opcode() const;
-  virtual uint size_of() const; // Size is bigger
   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
 
   // Dig the length operand out of a array allocation site.
@@ -918,7 +943,7 @@
   void set_nested()      { _kind = Nested; set_eliminated_lock_counter(); }
 
   // locking does not modify its arguments
-  virtual bool may_modify(const TypePtr *addr_t, PhaseTransform *phase){ return false;}
+  virtual bool may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase){ return false;}
 
 #ifndef PRODUCT
   void create_lock_counter(JVMState* s);
@@ -965,8 +990,11 @@
 
   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   // Expansion modifies the JVMState, so we need to clone it
-  virtual void  clone_jvms() {
-    set_jvms(jvms()->clone_deep(Compile::current()));
+  virtual void  clone_jvms(Compile* C) {
+    if (jvms() != NULL) {
+      set_jvms(jvms()->clone_deep(C));
+      jvms()->set_map_deep(this);
+    }
   }
 
   bool is_nested_lock_region(); // Is this Lock nested?
diff --git a/hotspot/src/share/vm/opto/cfgnode.cpp b/hotspot/src/share/vm/opto/cfgnode.cpp
index 68fcc9c..4185ada 100644
--- a/hotspot/src/share/vm/opto/cfgnode.cpp
+++ b/hotspot/src/share/vm/opto/cfgnode.cpp
@@ -806,7 +806,7 @@
       Node *in = ophi->in(i);
       if (in == NULL || igvn->type(in) == Type::TOP)
         continue;
-      Node *opt = MemNode::optimize_simple_memory_chain(in, at, igvn);
+      Node *opt = MemNode::optimize_simple_memory_chain(in, t_oop, NULL, igvn);
       PhiNode *optphi = opt->is_Phi() ? opt->as_Phi() : NULL;
       if (optphi != NULL && optphi->adr_type() == TypePtr::BOTTOM) {
         opt = node_map[optphi->_idx];
@@ -1921,7 +1921,7 @@
     const TypePtr* at = adr_type();
     for( uint i=1; i<req(); ++i ) {// For all paths in
       Node *ii = in(i);
-      Node *new_in = MemNode::optimize_memory_chain(ii, at, phase);
+      Node *new_in = MemNode::optimize_memory_chain(ii, at, NULL, phase);
       if (ii != new_in ) {
         set_req(i, new_in);
         progress = this;
diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp
index dd32b77..3222e25 100644
--- a/hotspot/src/share/vm/opto/compile.cpp
+++ b/hotspot/src/share/vm/opto/compile.cpp
@@ -418,6 +418,7 @@
   }
   // clean up the late inline lists
   remove_useless_late_inlines(&_string_late_inlines, useful);
+  remove_useless_late_inlines(&_boxing_late_inlines, useful);
   remove_useless_late_inlines(&_late_inlines, useful);
   debug_only(verify_graph_edges(true/*check for no_dead_code*/);)
 }
@@ -485,6 +486,12 @@
     tty->print_cr("** Bailout: Recompile without escape analysis          **");
     tty->print_cr("*********************************************************");
   }
+  if (_eliminate_boxing != EliminateAutoBox && PrintOpto) {
+    // Recompiling without boxing elimination
+    tty->print_cr("*********************************************************");
+    tty->print_cr("** Bailout: Recompile without boxing elimination       **");
+    tty->print_cr("*********************************************************");
+  }
   if (env()->break_at_compile()) {
     // Open the debugger when compiling this method.
     tty->print("### Breaking when compiling: ");
@@ -601,7 +608,8 @@
 // the continuation bci for on stack replacement.
 
 
-Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr_bci, bool subsume_loads, bool do_escape_analysis )
+Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr_bci,
+                  bool subsume_loads, bool do_escape_analysis, bool eliminate_boxing )
                 : Phase(Compiler),
                   _env(ci_env),
                   _log(ci_env->log()),
@@ -617,6 +625,7 @@
                   _warm_calls(NULL),
                   _subsume_loads(subsume_loads),
                   _do_escape_analysis(do_escape_analysis),
+                  _eliminate_boxing(eliminate_boxing),
                   _failure_reason(NULL),
                   _code_buffer("Compile::Fill_buffer"),
                   _orig_pc_slot(0),
@@ -638,6 +647,7 @@
                   _congraph(NULL),
                   _late_inlines(comp_arena(), 2, 0, NULL),
                   _string_late_inlines(comp_arena(), 2, 0, NULL),
+                  _boxing_late_inlines(comp_arena(), 2, 0, NULL),
                   _late_inlines_pos(0),
                   _number_of_mh_late_inlines(0),
                   _inlining_progress(false),
@@ -906,6 +916,7 @@
     _orig_pc_slot_offset_in_bytes(0),
     _subsume_loads(true),
     _do_escape_analysis(false),
+    _eliminate_boxing(false),
     _failure_reason(NULL),
     _code_buffer("Compile::Fill_buffer"),
     _has_method_handle_invokes(false),
@@ -1016,6 +1027,7 @@
   set_has_split_ifs(false);
   set_has_loops(has_method() && method()->has_loops()); // first approximation
   set_has_stringbuilder(false);
+  set_has_boxed_value(false);
   _trap_can_recompile = false;  // no traps emitted yet
   _major_progress = true; // start out assuming good things will happen
   set_has_unsafe_access(false);
@@ -1807,6 +1819,38 @@
   _string_late_inlines.trunc_to(0);
 }
 
+// Late inlining of boxing methods
+void Compile::inline_boxing_calls(PhaseIterGVN& igvn) {
+  if (_boxing_late_inlines.length() > 0) {
+    assert(has_boxed_value(), "inconsistent");
+
+    PhaseGVN* gvn = initial_gvn();
+    set_inlining_incrementally(true);
+
+    assert( igvn._worklist.size() == 0, "should be done with igvn" );
+    for_igvn()->clear();
+    gvn->replace_with(&igvn);
+
+    while (_boxing_late_inlines.length() > 0) {
+      CallGenerator* cg = _boxing_late_inlines.pop();
+      cg->do_late_inline();
+      if (failing())  return;
+    }
+    _boxing_late_inlines.trunc_to(0);
+
+    {
+      ResourceMark rm;
+      PhaseRemoveUseless pru(gvn, for_igvn());
+    }
+
+    igvn = PhaseIterGVN(gvn);
+    igvn.optimize();
+
+    set_inlining_progress(false);
+    set_inlining_incrementally(false);
+  }
+}
+
 void Compile::inline_incrementally_one(PhaseIterGVN& igvn) {
   assert(IncrementalInline, "incremental inlining should be on");
   PhaseGVN* gvn = initial_gvn();
@@ -1831,7 +1875,7 @@
 
   {
     ResourceMark rm;
-    PhaseRemoveUseless pru(C->initial_gvn(), C->for_igvn());
+    PhaseRemoveUseless pru(gvn, for_igvn());
   }
 
   igvn = PhaseIterGVN(gvn);
@@ -1929,12 +1973,25 @@
 
   if (failing())  return;
 
-  inline_incrementally(igvn);
+  {
+    NOT_PRODUCT( TracePhase t2("incrementalInline", &_t_incrInline, TimeCompiler); )
+    inline_incrementally(igvn);
+  }
 
   print_method("Incremental Inline", 2);
 
   if (failing())  return;
 
+  if (eliminate_boxing()) {
+    NOT_PRODUCT( TracePhase t2("incrementalInline", &_t_incrInline, TimeCompiler); )
+    // Inline valueOf() methods now.
+    inline_boxing_calls(igvn);
+
+    print_method("Incremental Boxing Inline", 2);
+
+    if (failing())  return;
+  }
+
   // No more new expensive nodes will be added to the list from here
   // so keep only the actual candidates for optimizations.
   cleanup_expensive_nodes(igvn);
@@ -2896,6 +2953,7 @@
     }
     break;
   case Op_MemBarStoreStore:
+  case Op_MemBarRelease:
     // Break the link with AllocateNode: it is no longer useful and
     // confuses register allocation.
     if (n->req() > MemBarNode::Precedent) {
diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp
index d951fbf..e0f1cd2 100644
--- a/hotspot/src/share/vm/opto/compile.hpp
+++ b/hotspot/src/share/vm/opto/compile.hpp
@@ -262,6 +262,7 @@
   const bool            _save_argument_registers; // save/restore arg regs for trampolines
   const bool            _subsume_loads;         // Load can be matched as part of a larger op.
   const bool            _do_escape_analysis;    // Do escape analysis.
+  const bool            _eliminate_boxing;      // Do boxing elimination.
   ciMethod*             _method;                // The method being compiled.
   int                   _entry_bci;             // entry bci for osr methods.
   const TypeFunc*       _tf;                    // My kind of signature
@@ -287,6 +288,7 @@
   bool                  _has_split_ifs;         // True if the method _may_ have some split-if
   bool                  _has_unsafe_access;     // True if the method _may_ produce faults in unsafe loads or stores.
   bool                  _has_stringbuilder;     // True StringBuffers or StringBuilders are allocated
+  bool                  _has_boxed_value;       // True if a boxed object is allocated
   int                   _max_vector_size;       // Maximum size of generated vectors
   uint                  _trap_hist[trapHistLength];  // Cumulative traps
   bool                  _trap_can_recompile;    // Have we emitted a recompiling trap?
@@ -375,6 +377,8 @@
                                                       // main parsing has finished.
   GrowableArray<CallGenerator*> _string_late_inlines; // same but for string operations
 
+  GrowableArray<CallGenerator*> _boxing_late_inlines; // same but for boxing operations
+
   int                           _late_inlines_pos;    // Where in the queue should the next late inlining candidate go (emulate depth first inlining)
   uint                          _number_of_mh_late_inlines; // number of method handle late inlining still pending
 
@@ -486,8 +490,12 @@
   // instructions that subsume a load may result in an unschedulable
   // instruction sequence.
   bool              subsume_loads() const       { return _subsume_loads; }
-  // Do escape analysis.
+  /** Do escape analysis. */
   bool              do_escape_analysis() const  { return _do_escape_analysis; }
+  /** Do boxing elimination. */
+  bool              eliminate_boxing() const    { return _eliminate_boxing; }
+  /** Do aggressive boxing elimination. */
+  bool              aggressive_unboxing() const { return _eliminate_boxing && AggressiveUnboxing; }
   bool              save_argument_registers() const { return _save_argument_registers; }
 
 
@@ -527,6 +535,8 @@
   void          set_has_unsafe_access(bool z)   { _has_unsafe_access = z; }
   bool              has_stringbuilder() const   { return _has_stringbuilder; }
   void          set_has_stringbuilder(bool z)   { _has_stringbuilder = z; }
+  bool              has_boxed_value() const     { return _has_boxed_value; }
+  void          set_has_boxed_value(bool z)     { _has_boxed_value = z; }
   int               max_vector_size() const     { return _max_vector_size; }
   void          set_max_vector_size(int s)      { _max_vector_size = s; }
   void          set_trap_count(uint r, uint c)  { assert(r < trapHistLength, "oob");        _trap_hist[r] = c; }
@@ -579,12 +589,12 @@
 #endif
   }
 
-  int           macro_count()                   { return _macro_nodes->length(); }
-  int           predicate_count()               { return _predicate_opaqs->length();}
-  int           expensive_count()               { return _expensive_nodes->length(); }
-  Node*         macro_node(int idx)             { return _macro_nodes->at(idx); }
-  Node*         predicate_opaque1_node(int idx) { return _predicate_opaqs->at(idx);}
-  Node*         expensive_node(int idx)         { return _expensive_nodes->at(idx); }
+  int           macro_count()             const { return _macro_nodes->length(); }
+  int           predicate_count()         const { return _predicate_opaqs->length();}
+  int           expensive_count()         const { return _expensive_nodes->length(); }
+  Node*         macro_node(int idx)       const { return _macro_nodes->at(idx); }
+  Node*         predicate_opaque1_node(int idx) const { return _predicate_opaqs->at(idx);}
+  Node*         expensive_node(int idx)   const { return _expensive_nodes->at(idx); }
   ConnectionGraph* congraph()                   { return _congraph;}
   void set_congraph(ConnectionGraph* congraph)  { _congraph = congraph;}
   void add_macro_node(Node * n) {
@@ -766,7 +776,12 @@
   // Decide how to build a call.
   // The profile factor is a discount to apply to this site's interp. profile.
   CallGenerator*    call_generator(ciMethod* call_method, int vtable_index, bool call_does_dispatch, JVMState* jvms, bool allow_inline, float profile_factor, bool allow_intrinsics = true, bool delayed_forbidden = false);
-  bool should_delay_inlining(ciMethod* call_method, JVMState* jvms);
+  bool should_delay_inlining(ciMethod* call_method, JVMState* jvms) {
+    return should_delay_string_inlining(call_method, jvms) ||
+           should_delay_boxing_inlining(call_method, jvms);
+  }
+  bool should_delay_string_inlining(ciMethod* call_method, JVMState* jvms);
+  bool should_delay_boxing_inlining(ciMethod* call_method, JVMState* jvms);
 
   // Helper functions to identify inlining potential at call-site
   ciMethod* optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass,
@@ -822,6 +837,10 @@
     _string_late_inlines.push(cg);
   }
 
+  void              add_boxing_late_inline(CallGenerator* cg) {
+    _boxing_late_inlines.push(cg);
+  }
+
   void remove_useless_late_inlines(GrowableArray<CallGenerator*>* inlines, Unique_Node_List &useful);
 
   void dump_inlining();
@@ -841,6 +860,7 @@
   void inline_incrementally_one(PhaseIterGVN& igvn);
   void inline_incrementally(PhaseIterGVN& igvn);
   void inline_string_calls(bool parse_time);
+  void inline_boxing_calls(PhaseIterGVN& igvn);
 
   // Matching, CFG layout, allocation, code generation
   PhaseCFG*         cfg()                       { return _cfg; }
@@ -913,7 +933,8 @@
   // replacement, entry_bci indicates the bytecode for which to compile a
   // continuation.
   Compile(ciEnv* ci_env, C2Compiler* compiler, ciMethod* target,
-          int entry_bci, bool subsume_loads, bool do_escape_analysis);
+          int entry_bci, bool subsume_loads, bool do_escape_analysis,
+          bool eliminate_boxing);
 
   // Second major entry point.  From the TypeFunc signature, generate code
   // to pass arguments from the Java calling convention to the C calling
diff --git a/hotspot/src/share/vm/opto/doCall.cpp b/hotspot/src/share/vm/opto/doCall.cpp
index 9a7562d..e55a01ba 100644
--- a/hotspot/src/share/vm/opto/doCall.cpp
+++ b/hotspot/src/share/vm/opto/doCall.cpp
@@ -176,9 +176,12 @@
           // Delay the inlining of this method to give us the
           // opportunity to perform some high level optimizations
           // first.
-          if (should_delay_inlining(callee, jvms)) {
+          if (should_delay_string_inlining(callee, jvms)) {
             assert(!delayed_forbidden, "strange");
             return CallGenerator::for_string_late_inline(callee, cg);
+          } else if (should_delay_boxing_inlining(callee, jvms)) {
+            assert(!delayed_forbidden, "strange");
+            return CallGenerator::for_boxing_late_inline(callee, cg);
           } else if ((should_delay || AlwaysIncrementalInline) && !delayed_forbidden) {
             return CallGenerator::for_late_inline(callee, cg);
           }
@@ -276,7 +279,7 @@
 
 // Return true for methods that shouldn't be inlined early so that
 // they are easier to analyze and optimize as intrinsics.
-bool Compile::should_delay_inlining(ciMethod* call_method, JVMState* jvms) {
+bool Compile::should_delay_string_inlining(ciMethod* call_method, JVMState* jvms) {
   if (has_stringbuilder()) {
 
     if ((call_method->holder() == C->env()->StringBuilder_klass() ||
@@ -327,6 +330,13 @@
   return false;
 }
 
+bool Compile::should_delay_boxing_inlining(ciMethod* call_method, JVMState* jvms) {
+  if (eliminate_boxing() && call_method->is_boxing_method()) {
+    set_has_boxed_value(true);
+    return true;
+  }
+  return false;
+}
 
 // uncommon-trap call-sites where callee is unloaded, uninitialized or will not link
 bool Parse::can_not_compile_call_site(ciMethod *dest_method, ciInstanceKlass* klass) {
diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp
index c5a93df..f29f82b 100644
--- a/hotspot/src/share/vm/opto/escape.cpp
+++ b/hotspot/src/share/vm/opto/escape.cpp
@@ -63,15 +63,19 @@
   // EA brings benefits only when the code has allocations and/or locks which
   // are represented by ideal Macro nodes.
   int cnt = C->macro_count();
-  for( int i=0; i < cnt; i++ ) {
+  for (int i = 0; i < cnt; i++) {
     Node *n = C->macro_node(i);
-    if ( n->is_Allocate() )
+    if (n->is_Allocate())
       return true;
-    if( n->is_Lock() ) {
+    if (n->is_Lock()) {
       Node* obj = n->as_Lock()->obj_node()->uncast();
-      if( !(obj->is_Parm() || obj->is_Con()) )
+      if (!(obj->is_Parm() || obj->is_Con()))
         return true;
     }
+    if (n->is_CallStaticJava() &&
+        n->as_CallStaticJava()->is_boxing_method()) {
+      return true;
+    }
   }
   return false;
 }
@@ -115,7 +119,7 @@
   { Compile::TracePhase t3("connectionGraph", &Phase::_t_connectionGraph, true);
 
   // 1. Populate Connection Graph (CG) with PointsTo nodes.
-  ideal_nodes.map(C->unique(), NULL);  // preallocate space
+  ideal_nodes.map(C->live_nodes(), NULL);  // preallocate space
   // Initialize worklist
   if (C->root() != NULL) {
     ideal_nodes.push(C->root());
@@ -152,8 +156,11 @@
       // escape status of the associated Allocate node some of them
       // may be eliminated.
       storestore_worklist.append(n);
+    } else if (n->is_MemBar() && (n->Opcode() == Op_MemBarRelease) &&
+               (n->req() > MemBarNode::Precedent)) {
+      record_for_optimizer(n);
 #ifdef ASSERT
-    } else if(n->is_AddP()) {
+    } else if (n->is_AddP()) {
       // Collect address nodes for graph verification.
       addp_worklist.append(n);
 #endif
@@ -206,8 +213,15 @@
   int non_escaped_length = non_escaped_worklist.length();
   for (int next = 0; next < non_escaped_length; next++) {
     JavaObjectNode* ptn = non_escaped_worklist.at(next);
-    if (ptn->escape_state() == PointsToNode::NoEscape &&
-        ptn->scalar_replaceable()) {
+    bool noescape = (ptn->escape_state() == PointsToNode::NoEscape);
+    Node* n = ptn->ideal_node();
+    if (n->is_Allocate()) {
+      n->as_Allocate()->_is_non_escaping = noescape;
+    }
+    if (n->is_CallStaticJava()) {
+      n->as_CallStaticJava()->_is_non_escaping = noescape;
+    }
+    if (noescape && ptn->scalar_replaceable()) {
       adjust_scalar_replaceable_state(ptn);
       if (ptn->scalar_replaceable()) {
         alloc_worklist.append(ptn->ideal_node());
@@ -330,8 +344,10 @@
       // Don't mark as processed since call's arguments have to be processed.
       delayed_worklist->push(n);
       // Check if a call returns an object.
-      if (n->as_Call()->returns_pointer() &&
-          n->as_Call()->proj_out(TypeFunc::Parms) != NULL) {
+      if ((n->as_Call()->returns_pointer() &&
+           n->as_Call()->proj_out(TypeFunc::Parms) != NULL) ||
+          (n->is_CallStaticJava() &&
+           n->as_CallStaticJava()->is_boxing_method())) {
         add_call_node(n->as_Call());
       }
     }
@@ -387,8 +403,8 @@
     case Op_ConNKlass: {
       // assume all oop constants globally escape except for null
       PointsToNode::EscapeState es;
-      if (igvn->type(n) == TypePtr::NULL_PTR ||
-          igvn->type(n) == TypeNarrowOop::NULL_PTR) {
+      const Type* t = igvn->type(n);
+      if (t == TypePtr::NULL_PTR || t == TypeNarrowOop::NULL_PTR) {
         es = PointsToNode::NoEscape;
       } else {
         es = PointsToNode::GlobalEscape;
@@ -468,6 +484,9 @@
       Node* adr = n->in(MemNode::Address);
       const Type *adr_type = igvn->type(adr);
       adr_type = adr_type->make_ptr();
+      if (adr_type == NULL) {
+        break; // skip dead nodes
+      }
       if (adr_type->isa_oopptr() ||
           (opcode == Op_StoreP || opcode == Op_StoreN || opcode == Op_StoreNKlass) &&
                         (adr_type == TypeRawPtr::NOTNULL &&
@@ -660,14 +679,18 @@
     case Op_GetAndSetP:
     case Op_GetAndSetN: {
       Node* adr = n->in(MemNode::Address);
-      if (opcode == Op_GetAndSetP || opcode == Op_GetAndSetN) {
-        const Type* t = _igvn->type(n);
-        if (t->make_ptr() != NULL) {
-          add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
-        }
-      }
       const Type *adr_type = _igvn->type(adr);
       adr_type = adr_type->make_ptr();
+#ifdef ASSERT
+      if (adr_type == NULL) {
+        n->dump(1);
+        assert(adr_type != NULL, "dead node should not be on list");
+        break;
+      }
+#endif
+      if (opcode == Op_GetAndSetP || opcode == Op_GetAndSetN) {
+        add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
+      }
       if (adr_type->isa_oopptr() ||
           (opcode == Op_StoreP || opcode == Op_StoreN || opcode == Op_StoreNKlass) &&
                         (adr_type == TypeRawPtr::NOTNULL &&
@@ -797,6 +820,18 @@
       // Returns a newly allocated unescaped object.
       add_java_object(call, PointsToNode::NoEscape);
       ptnode_adr(call_idx)->set_scalar_replaceable(false);
+    } else if (meth->is_boxing_method()) {
+      // Returns boxing object
+      PointsToNode::EscapeState es;
+      vmIntrinsics::ID intr = meth->intrinsic_id();
+      if (intr == vmIntrinsics::_floatValue || intr == vmIntrinsics::_doubleValue) {
+        // It does not escape if object is always allocated.
+        es = PointsToNode::NoEscape;
+      } else {
+        // It escapes globally if object could be loaded from cache.
+        es = PointsToNode::GlobalEscape;
+      }
+      add_java_object(call, es);
     } else {
       BCEscapeAnalyzer* call_analyzer = meth->get_bcea();
       call_analyzer->copy_dependencies(_compile->dependencies());
@@ -943,6 +978,9 @@
       assert((name == NULL || strcmp(name, "uncommon_trap") != 0), "normal calls only");
 #endif
       ciMethod* meth = call->as_CallJava()->method();
+      if ((meth != NULL) && meth->is_boxing_method()) {
+        break; // Boxing methods do not modify any oops.
+      }
       BCEscapeAnalyzer* call_analyzer = (meth !=NULL) ? meth->get_bcea() : NULL;
       // fall-through if not a Java method or no analyzer information
       if (call_analyzer != NULL) {
@@ -1791,9 +1829,8 @@
       jobj2->ideal_node()->is_Con()) {
     // Klass or String constants compare. Need to be careful with
     // compressed pointers - compare types of ConN and ConP instead of nodes.
-    const Type* t1 = jobj1->ideal_node()->bottom_type()->make_ptr();
-    const Type* t2 = jobj2->ideal_node()->bottom_type()->make_ptr();
-    assert(t1 != NULL && t2 != NULL, "sanity");
+    const Type* t1 = jobj1->ideal_node()->get_ptr_type();
+    const Type* t2 = jobj2->ideal_node()->get_ptr_type();
     if (t1->make_ptr() == t2->make_ptr()) {
       return _pcmp_eq;
     } else {
@@ -2744,6 +2781,11 @@
           // so it could be eliminated if it has no uses.
           alloc->as_Allocate()->_is_scalar_replaceable = true;
         }
+        if (alloc->is_CallStaticJava()) {
+          // Set the scalar_replaceable flag for boxing method
+          // so it could be eliminated if it has no uses.
+          alloc->as_CallStaticJava()->_is_scalar_replaceable = true;
+        }
         continue;
       }
       if (!n->is_CheckCastPP()) { // not unique CheckCastPP.
@@ -2782,6 +2824,11 @@
         // so it could be eliminated.
         alloc->as_Allocate()->_is_scalar_replaceable = true;
       }
+      if (alloc->is_CallStaticJava()) {
+        // Set the scalar_replaceable flag for boxing method
+        // so it could be eliminated.
+        alloc->as_CallStaticJava()->_is_scalar_replaceable = true;
+      }
       set_escape_state(ptnode_adr(n->_idx), es); // CheckCastPP escape state
       // in order for an object to be scalar-replaceable, it must be:
       //   - a direct allocation (not a call returning an object)
@@ -2911,7 +2958,9 @@
         // Load/store to instance's field
         memnode_worklist.append_if_missing(use);
       } else if (use->is_MemBar()) {
-        memnode_worklist.append_if_missing(use);
+        if (use->in(TypeFunc::Memory) == n) { // Ignore precedent edge
+          memnode_worklist.append_if_missing(use);
+        }
       } else if (use->is_AddP() && use->outcnt() > 0) { // No dead nodes
         Node* addp2 = find_second_addp(use, n);
         if (addp2 != NULL) {
@@ -3028,7 +3077,9 @@
           continue;
         memnode_worklist.append_if_missing(use);
       } else if (use->is_MemBar()) {
-        memnode_worklist.append_if_missing(use);
+        if (use->in(TypeFunc::Memory) == n) { // Ignore precedent edge
+          memnode_worklist.append_if_missing(use);
+        }
 #ifdef ASSERT
       } else if(use->is_Mem()) {
         assert(use->in(MemNode::Memory) != n, "EA: missing memory path");
@@ -3264,7 +3315,12 @@
     if (ptn == NULL || !ptn->is_JavaObject())
       continue;
     PointsToNode::EscapeState es = ptn->escape_state();
-    if (ptn->ideal_node()->is_Allocate() && (es == PointsToNode::NoEscape || Verbose)) {
+    if ((es != PointsToNode::NoEscape) && !Verbose) {
+      continue;
+    }
+    Node* n = ptn->ideal_node();
+    if (n->is_Allocate() || (n->is_CallStaticJava() &&
+                             n->as_CallStaticJava()->is_boxing_method())) {
       if (first) {
         tty->cr();
         tty->print("======== Connection graph for ");
diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp
index e228591..590770b 100644
--- a/hotspot/src/share/vm/opto/graphKit.cpp
+++ b/hotspot/src/share/vm/opto/graphKit.cpp
@@ -333,6 +333,7 @@
   assert(ex_jvms->stkoff() == phi_map->_jvms->stkoff(), "matching locals");
   assert(ex_jvms->sp() == phi_map->_jvms->sp(), "matching stack sizes");
   assert(ex_jvms->monoff() == phi_map->_jvms->monoff(), "matching JVMS");
+  assert(ex_jvms->scloff() == phi_map->_jvms->scloff(), "matching scalar replaced objects");
   assert(ex_map->req() == phi_map->req(), "matching maps");
   uint tos = ex_jvms->stkoff() + ex_jvms->sp();
   Node*         hidden_merge_mark = root();
@@ -409,7 +410,7 @@
         while (dst->req() > orig_width)  dst->del_req(dst->req()-1);
       } else {
         assert(dst->is_Phi(), "nobody else uses a hidden region");
-        phi = (PhiNode*)dst;
+        phi = dst->as_Phi();
       }
       if (add_multiple && src->in(0) == ex_control) {
         // Both are phis.
@@ -1438,7 +1439,12 @@
   } else {
     ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt);
   }
-  return _gvn.transform(ld);
+  ld = _gvn.transform(ld);
+  if ((bt == T_OBJECT) && C->do_escape_analysis() || C->eliminate_boxing()) {
+    // Improve graph before escape analysis and boxing elimination.
+    record_for_igvn(ld);
+  }
+  return ld;
 }
 
 Node* GraphKit::store_to_memory(Node* ctl, Node* adr, Node *val, BasicType bt,
@@ -3144,7 +3150,7 @@
   set_all_memory(mem); // Create new memory state
 
   AllocateNode* alloc
-    = new (C) AllocateNode(C, AllocateNode::alloc_type(),
+    = new (C) AllocateNode(C, AllocateNode::alloc_type(Type::TOP),
                            control(), mem, i_o(),
                            size, klass_node,
                            initial_slow_test);
@@ -3285,7 +3291,7 @@
 
   // Create the AllocateArrayNode and its result projections
   AllocateArrayNode* alloc
-    = new (C) AllocateArrayNode(C, AllocateArrayNode::alloc_type(),
+    = new (C) AllocateArrayNode(C, AllocateArrayNode::alloc_type(TypeInt::INT),
                                 control(), mem, i_o(),
                                 size, klass_node,
                                 initial_slow_test,
@@ -3326,10 +3332,9 @@
   if (ptr == NULL) {     // reduce dumb test in callers
     return NULL;
   }
-  if (ptr->is_CheckCastPP()) {  // strip a raw-to-oop cast
-    ptr = ptr->in(1);
-    if (ptr == NULL)  return NULL;
-  }
+  ptr = ptr->uncast();  // strip a raw-to-oop cast
+  if (ptr == NULL)  return NULL;
+
   if (ptr->is_Proj()) {
     Node* allo = ptr->in(0);
     if (allo != NULL && allo->is_Allocate()) {
@@ -3374,19 +3379,6 @@
   return NULL;
 }
 
-// Trace Allocate -> Proj[Parm] -> MemBarStoreStore
-MemBarStoreStoreNode* AllocateNode::storestore() {
-  ProjNode* rawoop = proj_out(AllocateNode::RawAddress);
-  if (rawoop == NULL)  return NULL;
-  for (DUIterator_Fast imax, i = rawoop->fast_outs(imax); i < imax; i++) {
-    Node* storestore = rawoop->fast_out(i);
-    if (storestore->is_MemBarStoreStore()) {
-      return storestore->as_MemBarStoreStore();
-    }
-  }
-  return NULL;
-}
-
 //----------------------------- loop predicates ---------------------------
 
 //------------------------------add_predicate_impl----------------------------
diff --git a/hotspot/src/share/vm/opto/idealGraphPrinter.hpp b/hotspot/src/share/vm/opto/idealGraphPrinter.hpp
index 7d1863f..f2892d5 100644
--- a/hotspot/src/share/vm/opto/idealGraphPrinter.hpp
+++ b/hotspot/src/share/vm/opto/idealGraphPrinter.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -41,9 +41,8 @@
 class InlineTree;
 class ciMethod;
 
-class IdealGraphPrinter
-{
-private:
+class IdealGraphPrinter : public CHeapObj<mtCompiler> {
+ private:
 
   static const char *INDENT;
   static const char *TOP_ELEMENT;
@@ -121,7 +120,7 @@
   IdealGraphPrinter();
   ~IdealGraphPrinter();
 
-public:
+ public:
 
   static void clean_up();
   static IdealGraphPrinter *printer();
@@ -135,8 +134,6 @@
   void print_method(Compile* compile, const char *name, int level=1, bool clear_nodes = false);
   void print(Compile* compile, const char *name, Node *root, int level=1, bool clear_nodes = false);
   void print_xml(const char *name);
-
-
 };
 
 #endif
diff --git a/hotspot/src/share/vm/opto/ifnode.cpp b/hotspot/src/share/vm/opto/ifnode.cpp
index b506a03..3995446 100644
--- a/hotspot/src/share/vm/opto/ifnode.cpp
+++ b/hotspot/src/share/vm/opto/ifnode.cpp
@@ -673,7 +673,7 @@
 //           /    Region
 //
 Node* IfNode::fold_compares(PhaseGVN* phase) {
-  if (!EliminateAutoBox || Opcode() != Op_If) return NULL;
+  if (!phase->C->eliminate_boxing() || Opcode() != Op_If) return NULL;
 
   Node* this_cmp = in(1)->in(1);
   if (this_cmp != NULL && this_cmp->Opcode() == Op_CmpI &&
diff --git a/hotspot/src/share/vm/opto/lcm.cpp b/hotspot/src/share/vm/opto/lcm.cpp
index ddb55d3..2b3eca4 100644
--- a/hotspot/src/share/vm/opto/lcm.cpp
+++ b/hotspot/src/share/vm/opto/lcm.cpp
@@ -219,9 +219,10 @@
         // cannot reason about it; is probably not implicit null exception
       } else {
         const TypePtr* tptr;
-        if (UseCompressedOops && Universe::narrow_oop_shift() == 0) {
+        if (UseCompressedOops && (Universe::narrow_oop_shift() == 0 ||
+                                  Universe::narrow_klass_shift() == 0)) {
           // 32-bits narrow oop can be the base of address expressions
-          tptr = base->bottom_type()->make_ptr();
+          tptr = base->get_ptr_type();
         } else {
           // only regular oops are expected here
           tptr = base->bottom_type()->is_ptr();
diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp
index 1f4b58e..609b702 100644
--- a/hotspot/src/share/vm/opto/library_call.cpp
+++ b/hotspot/src/share/vm/opto/library_call.cpp
@@ -2783,7 +2783,7 @@
 
 #ifdef _LP64
   if (type == T_OBJECT && adr->bottom_type()->is_ptr_to_narrowoop() && kind == LS_xchg) {
-    load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->bottom_type()->make_ptr()));
+    load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->get_ptr_type()));
   }
 #endif
 
@@ -3703,7 +3703,7 @@
   CallJavaNode* slow_call;
   if (is_static) {
     assert(!is_virtual, "");
-    slow_call = new(C) CallStaticJavaNode(tf,
+    slow_call = new(C) CallStaticJavaNode(C, tf,
                            SharedRuntime::get_resolve_static_call_stub(),
                            method, bci());
   } else if (is_virtual) {
@@ -3722,7 +3722,7 @@
                           method, vtable_index, bci());
   } else {  // neither virtual nor static:  opt_virtual
     null_check_receiver();
-    slow_call = new(C) CallStaticJavaNode(tf,
+    slow_call = new(C) CallStaticJavaNode(C, tf,
                                 SharedRuntime::get_resolve_opt_virtual_call_stub(),
                                 method, bci());
     slow_call->set_optimized_virtual(true);
diff --git a/hotspot/src/share/vm/opto/loopPredicate.cpp b/hotspot/src/share/vm/opto/loopPredicate.cpp
index a9867a5..f29d9da 100644
--- a/hotspot/src/share/vm/opto/loopPredicate.cpp
+++ b/hotspot/src/share/vm/opto/loopPredicate.cpp
@@ -821,8 +821,8 @@
         loop->dump_head();
       }
 #endif
-    } else if (cl != NULL && loop->is_range_check_if(iff, this, invar)) {
-      assert(proj->_con == predicate_proj->_con, "must match");
+    } else if ((cl != NULL) && (proj->_con == predicate_proj->_con) &&
+               loop->is_range_check_if(iff, this, invar)) {
 
       // Range check for counted loops
       const Node*    cmp    = bol->in(1)->as_Cmp();
diff --git a/hotspot/src/share/vm/opto/machnode.cpp b/hotspot/src/share/vm/opto/machnode.cpp
index b9b014e..0d6ddf9 100644
--- a/hotspot/src/share/vm/opto/machnode.cpp
+++ b/hotspot/src/share/vm/opto/machnode.cpp
@@ -349,11 +349,11 @@
   if (base == NodeSentinel)  return TypePtr::BOTTOM;
 
   const Type* t = base->bottom_type();
-  if (UseCompressedOops && Universe::narrow_oop_shift() == 0) {
+  if (t->isa_narrowoop() && Universe::narrow_oop_shift() == 0) {
     // 32-bit unscaled narrow oop can be the base of any address expression
     t = t->make_ptr();
   }
-  if (UseCompressedKlassPointers && Universe::narrow_klass_shift() == 0) {
+  if (t->isa_narrowklass() && Universe::narrow_klass_shift() == 0) {
     // 32-bit unscaled narrow oop can be the base of any address expression
     t = t->make_ptr();
   }
diff --git a/hotspot/src/share/vm/opto/macro.cpp b/hotspot/src/share/vm/opto/macro.cpp
index aeb1b62..56b9c939 100644
--- a/hotspot/src/share/vm/opto/macro.cpp
+++ b/hotspot/src/share/vm/opto/macro.cpp
@@ -666,7 +666,7 @@
         alloc->dump();
       else
         res->dump();
-    } else {
+    } else if (alloc->_is_scalar_replaceable) {
       tty->print("NotScalar (%s)", fail_eliminate);
       if (res == NULL)
         alloc->dump();
@@ -834,7 +834,7 @@
         if (field_val->is_EncodeP()) {
           field_val = field_val->in(1);
         } else {
-          field_val = transform_later(new (C) DecodeNNode(field_val, field_val->bottom_type()->make_ptr()));
+          field_val = transform_later(new (C) DecodeNNode(field_val, field_val->get_ptr_type()));
         }
       }
       sfpt->add_req(field_val);
@@ -845,18 +845,14 @@
     // to the allocated object with "sobj"
     int start = jvms->debug_start();
     int end   = jvms->debug_end();
-    for (int i = start; i < end; i++) {
-      if (sfpt->in(i) == res) {
-        sfpt->set_req(i, sobj);
-      }
-    }
+    sfpt->replace_edges_in_range(res, sobj, start, end);
     safepoints_done.append_if_missing(sfpt); // keep it for rollback
   }
   return true;
 }
 
 // Process users of eliminated allocation.
-void PhaseMacroExpand::process_users_of_allocation(AllocateNode *alloc) {
+void PhaseMacroExpand::process_users_of_allocation(CallNode *alloc) {
   Node* res = alloc->result_cast();
   if (res != NULL) {
     for (DUIterator_Last jmin, j = res->last_outs(jmin); j >= jmin; ) {
@@ -899,6 +895,17 @@
   // Process other users of allocation's projections
   //
   if (_resproj != NULL && _resproj->outcnt() != 0) {
+    // First disconnect stores captured by Initialize node.
+    // If Initialize node is eliminated first in the following code,
+    // it will kill such stores and DUIterator_Last will assert.
+    for (DUIterator_Fast jmax, j = _resproj->fast_outs(jmax);  j < jmax; j++) {
+      Node *use = _resproj->fast_out(j);
+      if (use->is_AddP()) {
+        // raw memory addresses used only by the initialization
+        _igvn.replace_node(use, C->top());
+        --j; --jmax;
+      }
+    }
     for (DUIterator_Last jmin, j = _resproj->last_outs(jmin); j >= jmin; ) {
       Node *use = _resproj->last_out(j);
       uint oc1 = _resproj->outcnt();
@@ -923,9 +930,6 @@
 #endif
           _igvn.replace_node(mem_proj, mem);
         }
-      } else if (use->is_AddP()) {
-        // raw memory addresses used only by the initialization
-        _igvn.replace_node(use, C->top());
       } else  {
         assert(false, "only Initialize or AddP expected");
       }
@@ -953,8 +957,18 @@
 }
 
 bool PhaseMacroExpand::eliminate_allocate_node(AllocateNode *alloc) {
-
-  if (!EliminateAllocations || !alloc->_is_scalar_replaceable) {
+  if (!EliminateAllocations || !alloc->_is_non_escaping) {
+    return false;
+  }
+  Node* klass = alloc->in(AllocateNode::KlassNode);
+  const TypeKlassPtr* tklass = _igvn.type(klass)->is_klassptr();
+  Node* res = alloc->result_cast();
+  // Eliminate boxing allocations which are not used
+  // regardless scalar replacable status.
+  bool boxing_alloc = C->eliminate_boxing() &&
+                      tklass->klass()->is_instance_klass()  &&
+                      tklass->klass()->as_instance_klass()->is_box_klass();
+  if (!alloc->_is_scalar_replaceable && (!boxing_alloc || (res != NULL))) {
     return false;
   }
 
@@ -965,14 +979,22 @@
     return false;
   }
 
+  if (!alloc->_is_scalar_replaceable) {
+    assert(res == NULL, "sanity");
+    // We can only eliminate allocation if all debug info references
+    // are already replaced with SafePointScalarObject because
+    // we can't search for a fields value without instance_id.
+    if (safepoints.length() > 0) {
+      return false;
+    }
+  }
+
   if (!scalar_replacement(alloc, safepoints)) {
     return false;
   }
 
   CompileLog* log = C->log();
   if (log != NULL) {
-    Node* klass = alloc->in(AllocateNode::KlassNode);
-    const TypeKlassPtr* tklass = _igvn.type(klass)->is_klassptr();
     log->head("eliminate_allocation type='%d'",
               log->identify(tklass->klass()));
     JVMState* p = alloc->jvms();
@@ -997,6 +1019,43 @@
   return true;
 }
 
+bool PhaseMacroExpand::eliminate_boxing_node(CallStaticJavaNode *boxing) {
+  // EA should remove all uses of non-escaping boxing node.
+  if (!C->eliminate_boxing() || boxing->proj_out(TypeFunc::Parms) != NULL) {
+    return false;
+  }
+
+  extract_call_projections(boxing);
+
+  const TypeTuple* r = boxing->tf()->range();
+  assert(r->cnt() > TypeFunc::Parms, "sanity");
+  const TypeInstPtr* t = r->field_at(TypeFunc::Parms)->isa_instptr();
+  assert(t != NULL, "sanity");
+
+  CompileLog* log = C->log();
+  if (log != NULL) {
+    log->head("eliminate_boxing type='%d'",
+              log->identify(t->klass()));
+    JVMState* p = boxing->jvms();
+    while (p != NULL) {
+      log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
+      p = p->caller();
+    }
+    log->tail("eliminate_boxing");
+  }
+
+  process_users_of_allocation(boxing);
+
+#ifndef PRODUCT
+  if (PrintEliminateAllocations) {
+    tty->print("++++ Eliminated: %d ", boxing->_idx);
+    boxing->method()->print_short_name(tty);
+    tty->cr();
+  }
+#endif
+
+  return true;
+}
 
 //---------------------------set_eden_pointers-------------------------
 void PhaseMacroExpand::set_eden_pointers(Node* &eden_top_adr, Node* &eden_end_adr) {
@@ -2384,6 +2443,9 @@
       case Node::Class_AllocateArray:
         success = eliminate_allocate_node(n->as_Allocate());
         break;
+      case Node::Class_CallStaticJava:
+        success = eliminate_boxing_node(n->as_CallStaticJava());
+        break;
       case Node::Class_Lock:
       case Node::Class_Unlock:
         assert(!n->as_AbstractLock()->is_eliminated(), "sanity");
@@ -2424,6 +2486,11 @@
         C->remove_macro_node(n);
         _igvn._worklist.push(n);
         success = true;
+      } else if (n->Opcode() == Op_CallStaticJava) {
+        // Remove it from macro list and put on IGVN worklist to optimize.
+        C->remove_macro_node(n);
+        _igvn._worklist.push(n);
+        success = true;
       } else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
         _igvn.replace_node(n, n->in(1));
         success = true;
diff --git a/hotspot/src/share/vm/opto/macro.hpp b/hotspot/src/share/vm/opto/macro.hpp
index ba35c49..7a72316 100644
--- a/hotspot/src/share/vm/opto/macro.hpp
+++ b/hotspot/src/share/vm/opto/macro.hpp
@@ -86,10 +86,11 @@
   Node *value_from_mem(Node *mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc);
   Node *value_from_mem_phi(Node *mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc, Node_Stack *value_phis, int level);
 
+  bool eliminate_boxing_node(CallStaticJavaNode *boxing);
   bool eliminate_allocate_node(AllocateNode *alloc);
   bool can_eliminate_allocation(AllocateNode *alloc, GrowableArray <SafePointNode *>& safepoints);
   bool scalar_replacement(AllocateNode *alloc, GrowableArray <SafePointNode *>& safepoints_done);
-  void process_users_of_allocation(AllocateNode *alloc);
+  void process_users_of_allocation(CallNode *alloc);
 
   void eliminate_card_mark(Node *cm);
   void mark_eliminated_box(Node* box, Node* obj);
diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp
index a4dcdb7..fc59ceb 100644
--- a/hotspot/src/share/vm/opto/memnode.cpp
+++ b/hotspot/src/share/vm/opto/memnode.cpp
@@ -103,11 +103,15 @@
 
 #endif
 
-Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase) {
-  const TypeOopPtr *tinst = t_adr->isa_oopptr();
-  if (tinst == NULL || !tinst->is_known_instance_field())
+Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypeOopPtr *t_oop, Node *load, PhaseGVN *phase) {
+  assert((t_oop != NULL), "sanity");
+  bool is_instance = t_oop->is_known_instance_field();
+  bool is_boxed_value_load = t_oop->is_ptr_to_boxed_value() &&
+                             (load != NULL) && load->is_Load() &&
+                             (phase->is_IterGVN() != NULL);
+  if (!(is_instance || is_boxed_value_load))
     return mchain;  // don't try to optimize non-instance types
-  uint instance_id = tinst->instance_id();
+  uint instance_id = t_oop->instance_id();
   Node *start_mem = phase->C->start()->proj_out(TypeFunc::Memory);
   Node *prev = NULL;
   Node *result = mchain;
@@ -122,15 +126,24 @@
         break;  // hit one of our sentinels
       } else if (proj_in->is_Call()) {
         CallNode *call = proj_in->as_Call();
-        if (!call->may_modify(t_adr, phase)) {
+        if (!call->may_modify(t_oop, phase)) { // returns false for instances
           result = call->in(TypeFunc::Memory);
         }
       } else if (proj_in->is_Initialize()) {
         AllocateNode* alloc = proj_in->as_Initialize()->allocation();
         // Stop if this is the initialization for the object instance which
         // which contains this memory slice, otherwise skip over it.
-        if (alloc != NULL && alloc->_idx != instance_id) {
+        if ((alloc == NULL) || (alloc->_idx == instance_id)) {
+          break;
+        }
+        if (is_instance) {
           result = proj_in->in(TypeFunc::Memory);
+        } else if (is_boxed_value_load) {
+          Node* klass = alloc->in(AllocateNode::KlassNode);
+          const TypeKlassPtr* tklass = phase->type(klass)->is_klassptr();
+          if (tklass->klass_is_exact() && !tklass->klass()->equals(t_oop->klass())) {
+            result = proj_in->in(TypeFunc::Memory); // not related allocation
+          }
         }
       } else if (proj_in->is_MemBar()) {
         result = proj_in->in(TypeFunc::Memory);
@@ -138,25 +151,26 @@
         assert(false, "unexpected projection");
       }
     } else if (result->is_ClearArray()) {
-      if (!ClearArrayNode::step_through(&result, instance_id, phase)) {
+      if (!is_instance || !ClearArrayNode::step_through(&result, instance_id, phase)) {
         // Can not bypass initialization of the instance
         // we are looking for.
         break;
       }
       // Otherwise skip it (the call updated 'result' value).
     } else if (result->is_MergeMem()) {
-      result = step_through_mergemem(phase, result->as_MergeMem(), t_adr, NULL, tty);
+      result = step_through_mergemem(phase, result->as_MergeMem(), t_oop, NULL, tty);
     }
   }
   return result;
 }
 
-Node *MemNode::optimize_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase) {
-  const TypeOopPtr *t_oop = t_adr->isa_oopptr();
-  bool is_instance = (t_oop != NULL) && t_oop->is_known_instance_field();
+Node *MemNode::optimize_memory_chain(Node *mchain, const TypePtr *t_adr, Node *load, PhaseGVN *phase) {
+  const TypeOopPtr* t_oop = t_adr->isa_oopptr();
+  if (t_oop == NULL)
+    return mchain;  // don't try to optimize non-oop types
+  Node* result = optimize_simple_memory_chain(mchain, t_oop, load, phase);
+  bool is_instance = t_oop->is_known_instance_field();
   PhaseIterGVN *igvn = phase->is_IterGVN();
-  Node *result = mchain;
-  result = optimize_simple_memory_chain(result, t_adr, phase);
   if (is_instance && igvn != NULL  && result->is_Phi()) {
     PhiNode *mphi = result->as_Phi();
     assert(mphi->bottom_type() == Type::MEMORY, "memory phi required");
@@ -383,7 +397,7 @@
   // Or Region for the check in LoadNode::Ideal();
   // 'sub' should have sub->in(0) != NULL.
   assert(sub->is_Allocate() || sub->is_Initialize() || sub->is_Start() ||
-         sub->is_Region(), "expecting only these nodes");
+         sub->is_Region() || sub->is_Call(), "expecting only these nodes");
 
   // Get control edge of 'sub'.
   Node* orig_sub = sub;
@@ -957,11 +971,14 @@
 // of aliasing.
 Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const {
   Node* ld_adr = in(MemNode::Address);
-
+  intptr_t ld_off = 0;
+  AllocateNode* ld_alloc = AllocateNode::Ideal_allocation(ld_adr, phase, ld_off);
   const TypeInstPtr* tp = phase->type(ld_adr)->isa_instptr();
-  Compile::AliasType* atp = tp != NULL ? phase->C->alias_type(tp) : NULL;
-  if (EliminateAutoBox && atp != NULL && atp->index() >= Compile::AliasIdxRaw &&
-      atp->field() != NULL && !atp->field()->is_volatile()) {
+  Compile::AliasType* atp = (tp != NULL) ? phase->C->alias_type(tp) : NULL;
+  // This is more general than load from boxing objects.
+  if (phase->C->eliminate_boxing() && (atp != NULL) &&
+      (atp->index() >= Compile::AliasIdxRaw) &&
+      (atp->field() != NULL) && !atp->field()->is_volatile()) {
     uint alias_idx = atp->index();
     bool final = atp->field()->is_final();
     Node* result = NULL;
@@ -983,7 +1000,7 @@
           Node* new_st = merge->memory_at(alias_idx);
           if (new_st == merge->base_memory()) {
             // Keep searching
-            current = merge->base_memory();
+            current = new_st;
             continue;
           }
           // Save the new memory state for the slice and fall through
@@ -1010,9 +1027,7 @@
         intptr_t st_off = 0;
         AllocateNode* alloc = AllocateNode::Ideal_allocation(st_adr, phase, st_off);
         if (alloc == NULL)       return NULL;
-        intptr_t ld_off = 0;
-        AllocateNode* allo2 = AllocateNode::Ideal_allocation(ld_adr, phase, ld_off);
-        if (alloc != allo2)      return NULL;
+        if (alloc != ld_alloc)   return NULL;
         if (ld_off != st_off)    return NULL;
         // At this point we have proven something like this setup:
         //  A = Allocate(...)
@@ -1029,14 +1044,12 @@
       return st->in(MemNode::ValueIn);
     }
 
-    intptr_t offset = 0;  // scratch
-
     // A load from a freshly-created object always returns zero.
     // (This can happen after LoadNode::Ideal resets the load's memory input
     // to find_captured_store, which returned InitializeNode::zero_memory.)
     if (st->is_Proj() && st->in(0)->is_Allocate() &&
-        st->in(0) == AllocateNode::Ideal_allocation(ld_adr, phase, offset) &&
-        offset >= st->in(0)->as_Allocate()->minimum_header_size()) {
+        (st->in(0) == ld_alloc) &&
+        (ld_off >= st->in(0)->as_Allocate()->minimum_header_size())) {
       // return a zero value for the load's basic type
       // (This is one of the few places where a generic PhaseTransform
       // can create new nodes.  Think of it as lazily manifesting
@@ -1048,15 +1061,27 @@
     if (st->is_Proj() && st->in(0)->is_Initialize()) {
       InitializeNode* init = st->in(0)->as_Initialize();
       AllocateNode* alloc = init->allocation();
-      if (alloc != NULL &&
-          alloc == AllocateNode::Ideal_allocation(ld_adr, phase, offset)) {
+      if ((alloc != NULL) && (alloc == ld_alloc)) {
         // examine a captured store value
-        st = init->find_captured_store(offset, memory_size(), phase);
+        st = init->find_captured_store(ld_off, memory_size(), phase);
         if (st != NULL)
           continue;             // take one more trip around
       }
     }
 
+    // Load boxed value from result of valueOf() call is input parameter.
+    if (this->is_Load() && ld_adr->is_AddP() &&
+        (tp != NULL) && tp->is_ptr_to_boxed_value()) {
+      intptr_t ignore = 0;
+      Node* base = AddPNode::Ideal_base_and_offset(ld_adr, phase, ignore);
+      if (base != NULL && base->is_Proj() &&
+          base->as_Proj()->_con == TypeFunc::Parms &&
+          base->in(0)->is_CallStaticJava() &&
+          base->in(0)->as_CallStaticJava()->is_boxing_method()) {
+        return base->in(0)->in(TypeFunc::Parms);
+      }
+    }
+
     break;
   }
 
@@ -1065,11 +1090,13 @@
 
 //----------------------is_instance_field_load_with_local_phi------------------
 bool LoadNode::is_instance_field_load_with_local_phi(Node* ctrl) {
-  if( in(MemNode::Memory)->is_Phi() && in(MemNode::Memory)->in(0) == ctrl &&
-      in(MemNode::Address)->is_AddP() ) {
-    const TypeOopPtr* t_oop = in(MemNode::Address)->bottom_type()->isa_oopptr();
-    // Only instances.
-    if( t_oop != NULL && t_oop->is_known_instance_field() &&
+  if( in(Memory)->is_Phi() && in(Memory)->in(0) == ctrl &&
+      in(Address)->is_AddP() ) {
+    const TypeOopPtr* t_oop = in(Address)->bottom_type()->isa_oopptr();
+    // Only instances and boxed values.
+    if( t_oop != NULL &&
+        (t_oop->is_ptr_to_boxed_value() ||
+         t_oop->is_known_instance_field()) &&
         t_oop->offset() != Type::OffsetBot &&
         t_oop->offset() != Type::OffsetTop) {
       return true;
@@ -1083,7 +1110,7 @@
 Node *LoadNode::Identity( PhaseTransform *phase ) {
   // If the previous store-maker is the right kind of Store, and the store is
   // to the same address, then we are equal to the value stored.
-  Node* mem = in(MemNode::Memory);
+  Node* mem = in(Memory);
   Node* value = can_see_stored_value(mem, phase);
   if( value ) {
     // byte, short & char stores truncate naturally.
@@ -1105,15 +1132,22 @@
   // instance's field to avoid infinite generation of phis in a loop.
   Node *region = mem->in(0);
   if (is_instance_field_load_with_local_phi(region)) {
-    const TypePtr *addr_t = in(MemNode::Address)->bottom_type()->isa_ptr();
+    const TypeOopPtr *addr_t = in(Address)->bottom_type()->isa_oopptr();
     int this_index  = phase->C->get_alias_index(addr_t);
     int this_offset = addr_t->offset();
-    int this_id    = addr_t->is_oopptr()->instance_id();
+    int this_iid    = addr_t->instance_id();
+    if (!addr_t->is_known_instance() &&
+         addr_t->is_ptr_to_boxed_value()) {
+      // Use _idx of address base (could be Phi node) for boxed values.
+      intptr_t   ignore = 0;
+      Node*      base = AddPNode::Ideal_base_and_offset(in(Address), phase, ignore);
+      this_iid = base->_idx;
+    }
     const Type* this_type = bottom_type();
     for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
       Node* phi = region->fast_out(i);
       if (phi->is_Phi() && phi != mem &&
-          phi->as_Phi()->is_same_inst_field(this_type, this_id, this_index, this_offset)) {
+          phi->as_Phi()->is_same_inst_field(this_type, this_iid, this_index, this_offset)) {
         return phi;
       }
     }
@@ -1122,170 +1156,106 @@
   return this;
 }
 
-
-// Returns true if the AliasType refers to the field that holds the
-// cached box array.  Currently only handles the IntegerCache case.
-static bool is_autobox_cache(Compile::AliasType* atp) {
-  if (atp != NULL && atp->field() != NULL) {
-    ciField* field = atp->field();
-    ciSymbol* klass = field->holder()->name();
-    if (field->name() == ciSymbol::cache_field_name() &&
-        field->holder()->uses_default_loader() &&
-        klass == ciSymbol::java_lang_Integer_IntegerCache()) {
-      return true;
-    }
-  }
-  return false;
-}
-
-// Fetch the base value in the autobox array
-static bool fetch_autobox_base(Compile::AliasType* atp, int& cache_offset) {
-  if (atp != NULL && atp->field() != NULL) {
-    ciField* field = atp->field();
-    ciSymbol* klass = field->holder()->name();
-    if (field->name() == ciSymbol::cache_field_name() &&
-        field->holder()->uses_default_loader() &&
-        klass == ciSymbol::java_lang_Integer_IntegerCache()) {
-      assert(field->is_constant(), "what?");
-      ciObjArray* array = field->constant_value().as_object()->as_obj_array();
-      // Fetch the box object at the base of the array and get its value
-      ciInstance* box = array->obj_at(0)->as_instance();
-      ciInstanceKlass* ik = box->klass()->as_instance_klass();
-      if (ik->nof_nonstatic_fields() == 1) {
-        // This should be true nonstatic_field_at requires calling
-        // nof_nonstatic_fields so check it anyway
-        ciConstant c = box->field_value(ik->nonstatic_field_at(0));
-        cache_offset = c.as_int();
-      }
-      return true;
-    }
-  }
-  return false;
-}
-
-// Returns true if the AliasType refers to the value field of an
-// autobox object.  Currently only handles Integer.
-static bool is_autobox_object(Compile::AliasType* atp) {
-  if (atp != NULL && atp->field() != NULL) {
-    ciField* field = atp->field();
-    ciSymbol* klass = field->holder()->name();
-    if (field->name() == ciSymbol::value_name() &&
-        field->holder()->uses_default_loader() &&
-        klass == ciSymbol::java_lang_Integer()) {
-      return true;
-    }
-  }
-  return false;
-}
-
-
 // We're loading from an object which has autobox behaviour.
 // If this object is result of a valueOf call we'll have a phi
 // merging a newly allocated object and a load from the cache.
 // We want to replace this load with the original incoming
 // argument to the valueOf call.
 Node* LoadNode::eliminate_autobox(PhaseGVN* phase) {
-  Node* base = in(Address)->in(AddPNode::Base);
-  if (base->is_Phi() && base->req() == 3) {
-    AllocateNode* allocation = NULL;
-    int allocation_index = -1;
-    int load_index = -1;
-    for (uint i = 1; i < base->req(); i++) {
-      allocation = AllocateNode::Ideal_allocation(base->in(i), phase);
-      if (allocation != NULL) {
-        allocation_index = i;
-        load_index = 3 - allocation_index;
-        break;
-      }
-    }
-    bool has_load = ( allocation != NULL &&
-                      (base->in(load_index)->is_Load() ||
-                       base->in(load_index)->is_DecodeN() &&
-                       base->in(load_index)->in(1)->is_Load()) );
-    if (has_load && in(Memory)->is_Phi() && in(Memory)->in(0) == base->in(0)) {
-      // Push the loads from the phi that comes from valueOf up
-      // through it to allow elimination of the loads and the recovery
-      // of the original value.
-      Node* mem_phi = in(Memory);
-      Node* offset = in(Address)->in(AddPNode::Offset);
-      Node* region = base->in(0);
-
-      Node* in1 = clone();
-      Node* in1_addr = in1->in(Address)->clone();
-      in1_addr->set_req(AddPNode::Base, base->in(allocation_index));
-      in1_addr->set_req(AddPNode::Address, base->in(allocation_index));
-      in1_addr->set_req(AddPNode::Offset, offset);
-      in1->set_req(0, region->in(allocation_index));
-      in1->set_req(Address, in1_addr);
-      in1->set_req(Memory, mem_phi->in(allocation_index));
-
-      Node* in2 = clone();
-      Node* in2_addr = in2->in(Address)->clone();
-      in2_addr->set_req(AddPNode::Base, base->in(load_index));
-      in2_addr->set_req(AddPNode::Address, base->in(load_index));
-      in2_addr->set_req(AddPNode::Offset, offset);
-      in2->set_req(0, region->in(load_index));
-      in2->set_req(Address, in2_addr);
-      in2->set_req(Memory, mem_phi->in(load_index));
-
-      in1_addr = phase->transform(in1_addr);
-      in1 =      phase->transform(in1);
-      in2_addr = phase->transform(in2_addr);
-      in2 =      phase->transform(in2);
-
-      PhiNode* result = PhiNode::make_blank(region, this);
-      result->set_req(allocation_index, in1);
-      result->set_req(load_index, in2);
-      return result;
-    }
+  assert(phase->C->eliminate_boxing(), "sanity");
+  intptr_t ignore = 0;
+  Node* base = AddPNode::Ideal_base_and_offset(in(Address), phase, ignore);
+  if ((base == NULL) || base->is_Phi()) {
+    // Push the loads from the phi that comes from valueOf up
+    // through it to allow elimination of the loads and the recovery
+    // of the original value. It is done in split_through_phi().
+    return NULL;
   } else if (base->is_Load() ||
              base->is_DecodeN() && base->in(1)->is_Load()) {
-    if (base->is_DecodeN()) {
-      // Get LoadN node which loads cached Integer object
-      base = base->in(1);
-    }
-    // Eliminate the load of Integer.value for integers from the cache
+    // Eliminate the load of boxed value for integer types from the cache
     // array by deriving the value from the index into the array.
     // Capture the offset of the load and then reverse the computation.
-    Node* load_base = base->in(Address)->in(AddPNode::Base);
-    if (load_base->is_DecodeN()) {
-      // Get LoadN node which loads IntegerCache.cache field
-      load_base = load_base->in(1);
+
+    // Get LoadN node which loads a boxing object from 'cache' array.
+    if (base->is_DecodeN()) {
+      base = base->in(1);
     }
-    if (load_base != NULL) {
-      Compile::AliasType* atp = phase->C->alias_type(load_base->adr_type());
-      intptr_t cache_offset;
-      int shift = -1;
-      Node* cache = NULL;
-      if (is_autobox_cache(atp)) {
-        shift  = exact_log2(type2aelembytes(T_OBJECT));
-        cache = AddPNode::Ideal_base_and_offset(load_base->in(Address), phase, cache_offset);
-      }
-      if (cache != NULL && base->in(Address)->is_AddP()) {
+    if (!base->in(Address)->is_AddP()) {
+      return NULL; // Complex address
+    }
+    AddPNode* address = base->in(Address)->as_AddP();
+    Node* cache_base = address->in(AddPNode::Base);
+    if ((cache_base != NULL) && cache_base->is_DecodeN()) {
+      // Get ConP node which is static 'cache' field.
+      cache_base = cache_base->in(1);
+    }
+    if ((cache_base != NULL) && cache_base->is_Con()) {
+      const TypeAryPtr* base_type = cache_base->bottom_type()->isa_aryptr();
+      if ((base_type != NULL) && base_type->is_autobox_cache()) {
         Node* elements[4];
-        int count = base->in(Address)->as_AddP()->unpack_offsets(elements, ARRAY_SIZE(elements));
-        int cache_low;
-        if (count > 0 && fetch_autobox_base(atp, cache_low)) {
-          int offset = arrayOopDesc::base_offset_in_bytes(memory_type()) - (cache_low << shift);
-          // Add up all the offsets making of the address of the load
-          Node* result = elements[0];
-          for (int i = 1; i < count; i++) {
-            result = phase->transform(new (phase->C) AddXNode(result, elements[i]));
-          }
-          // Remove the constant offset from the address and then
-          // remove the scaling of the offset to recover the original index.
-          result = phase->transform(new (phase->C) AddXNode(result, phase->MakeConX(-offset)));
-          if (result->Opcode() == Op_LShiftX && result->in(2) == phase->intcon(shift)) {
-            // Peel the shift off directly but wrap it in a dummy node
-            // since Ideal can't return existing nodes
-            result = new (phase->C) RShiftXNode(result->in(1), phase->intcon(0));
-          } else {
-            result = new (phase->C) RShiftXNode(result, phase->intcon(shift));
-          }
+        int shift = exact_log2(type2aelembytes(T_OBJECT));
+        int count = address->unpack_offsets(elements, ARRAY_SIZE(elements));
+        if ((count >  0) && elements[0]->is_Con() &&
+            ((count == 1) ||
+             (count == 2) && elements[1]->Opcode() == Op_LShiftX &&
+                             elements[1]->in(2) == phase->intcon(shift))) {
+          ciObjArray* array = base_type->const_oop()->as_obj_array();
+          // Fetch the box object cache[0] at the base of the array and get its value
+          ciInstance* box = array->obj_at(0)->as_instance();
+          ciInstanceKlass* ik = box->klass()->as_instance_klass();
+          assert(ik->is_box_klass(), "sanity");
+          assert(ik->nof_nonstatic_fields() == 1, "change following code");
+          if (ik->nof_nonstatic_fields() == 1) {
+            // This should be true nonstatic_field_at requires calling
+            // nof_nonstatic_fields so check it anyway
+            ciConstant c = box->field_value(ik->nonstatic_field_at(0));
+            BasicType bt = c.basic_type();
+            // Only integer types have boxing cache.
+            assert(bt == T_BOOLEAN || bt == T_CHAR  ||
+                   bt == T_BYTE    || bt == T_SHORT ||
+                   bt == T_INT     || bt == T_LONG, err_msg_res("wrong type = %s", type2name(bt)));
+            jlong cache_low = (bt == T_LONG) ? c.as_long() : c.as_int();
+            if (cache_low != (int)cache_low) {
+              return NULL; // should not happen since cache is array indexed by value
+            }
+            jlong offset = arrayOopDesc::base_offset_in_bytes(T_OBJECT) - (cache_low << shift);
+            if (offset != (int)offset) {
+              return NULL; // should not happen since cache is array indexed by value
+            }
+           // Add up all the offsets making of the address of the load
+            Node* result = elements[0];
+            for (int i = 1; i < count; i++) {
+              result = phase->transform(new (phase->C) AddXNode(result, elements[i]));
+            }
+            // Remove the constant offset from the address and then
+            result = phase->transform(new (phase->C) AddXNode(result, phase->MakeConX(-(int)offset)));
+            // remove the scaling of the offset to recover the original index.
+            if (result->Opcode() == Op_LShiftX && result->in(2) == phase->intcon(shift)) {
+              // Peel the shift off directly but wrap it in a dummy node
+              // since Ideal can't return existing nodes
+              result = new (phase->C) RShiftXNode(result->in(1), phase->intcon(0));
+            } else if (result->is_Add() && result->in(2)->is_Con() &&
+                       result->in(1)->Opcode() == Op_LShiftX &&
+                       result->in(1)->in(2) == phase->intcon(shift)) {
+              // We can't do general optimization: ((X<<Z) + Y) >> Z ==> X + (Y>>Z)
+              // but for boxing cache access we know that X<<Z will not overflow
+              // (there is range check) so we do this optimizatrion by hand here.
+              Node* add_con = new (phase->C) RShiftXNode(result->in(2), phase->intcon(shift));
+              result = new (phase->C) AddXNode(result->in(1)->in(1), phase->transform(add_con));
+            } else {
+              result = new (phase->C) RShiftXNode(result, phase->intcon(shift));
+            }
 #ifdef _LP64
-          result = new (phase->C) ConvL2INode(phase->transform(result));
+            if (bt != T_LONG) {
+              result = new (phase->C) ConvL2INode(phase->transform(result));
+            }
+#else
+            if (bt == T_LONG) {
+              result = new (phase->C) ConvI2LNode(phase->transform(result));
+            }
 #endif
-          return result;
+            return result;
+          }
         }
       }
     }
@@ -1293,65 +1263,131 @@
   return NULL;
 }
 
-//------------------------------split_through_phi------------------------------
-// Split instance field load through Phi.
-Node *LoadNode::split_through_phi(PhaseGVN *phase) {
-  Node* mem     = in(MemNode::Memory);
-  Node* address = in(MemNode::Address);
-  const TypePtr *addr_t = phase->type(address)->isa_ptr();
-  const TypeOopPtr *t_oop = addr_t->isa_oopptr();
-
-  assert(mem->is_Phi() && (t_oop != NULL) &&
-         t_oop->is_known_instance_field(), "invalide conditions");
-
-  Node *region = mem->in(0);
+static bool stable_phi(PhiNode* phi, PhaseGVN *phase) {
+  Node* region = phi->in(0);
   if (region == NULL) {
-    return NULL; // Wait stable graph
+    return false; // Wait stable graph
   }
-  uint cnt = mem->req();
+  uint cnt = phi->req();
   for (uint i = 1; i < cnt; i++) {
     Node* rc = region->in(i);
     if (rc == NULL || phase->type(rc) == Type::TOP)
-      return NULL; // Wait stable graph
-    Node *in = mem->in(i);
-    if (in == NULL) {
+      return false; // Wait stable graph
+    Node* in = phi->in(i);
+    if (in == NULL || phase->type(in) == Type::TOP)
+      return false; // Wait stable graph
+  }
+  return true;
+}
+//------------------------------split_through_phi------------------------------
+// Split instance or boxed field load through Phi.
+Node *LoadNode::split_through_phi(PhaseGVN *phase) {
+  Node* mem     = in(Memory);
+  Node* address = in(Address);
+  const TypeOopPtr *t_oop = phase->type(address)->isa_oopptr();
+
+  assert((t_oop != NULL) &&
+         (t_oop->is_known_instance_field() ||
+          t_oop->is_ptr_to_boxed_value()), "invalide conditions");
+
+  Compile* C = phase->C;
+  intptr_t ignore = 0;
+  Node*    base = AddPNode::Ideal_base_and_offset(address, phase, ignore);
+  bool base_is_phi = (base != NULL) && base->is_Phi();
+  bool load_boxed_values = t_oop->is_ptr_to_boxed_value() && C->aggressive_unboxing() &&
+                           (base != NULL) && (base == address->in(AddPNode::Base)) &&
+                           phase->type(base)->higher_equal(TypePtr::NOTNULL);
+
+  if (!((mem->is_Phi() || base_is_phi) &&
+        (load_boxed_values || t_oop->is_known_instance_field()))) {
+    return NULL; // memory is not Phi
+  }
+
+  if (mem->is_Phi()) {
+    if (!stable_phi(mem->as_Phi(), phase)) {
       return NULL; // Wait stable graph
     }
-  }
-  // Check for loop invariant.
-  if (cnt == 3) {
-    for (uint i = 1; i < cnt; i++) {
-      Node *in = mem->in(i);
-      Node* m = MemNode::optimize_memory_chain(in, addr_t, phase);
-      if (m == mem) {
-        set_req(MemNode::Memory, mem->in(cnt - i)); // Skip this phi.
-        return this;
+    uint cnt = mem->req();
+    // Check for loop invariant memory.
+    if (cnt == 3) {
+      for (uint i = 1; i < cnt; i++) {
+        Node* in = mem->in(i);
+        Node*  m = optimize_memory_chain(in, t_oop, this, phase);
+        if (m == mem) {
+          set_req(Memory, mem->in(cnt - i));
+          return this; // made change
+        }
       }
     }
   }
+  if (base_is_phi) {
+    if (!stable_phi(base->as_Phi(), phase)) {
+      return NULL; // Wait stable graph
+    }
+    uint cnt = base->req();
+    // Check for loop invariant memory.
+    if (cnt == 3) {
+      for (uint i = 1; i < cnt; i++) {
+        if (base->in(i) == base) {
+          return NULL; // Wait stable graph
+        }
+      }
+    }
+  }
+
+  bool load_boxed_phi = load_boxed_values && base_is_phi && (base->in(0) == mem->in(0));
+
   // Split through Phi (see original code in loopopts.cpp).
-  assert(phase->C->have_alias_type(addr_t), "instance should have alias type");
+  assert(C->have_alias_type(t_oop), "instance should have alias type");
 
   // Do nothing here if Identity will find a value
   // (to avoid infinite chain of value phis generation).
   if (!phase->eqv(this, this->Identity(phase)))
     return NULL;
 
-  // Skip the split if the region dominates some control edge of the address.
-  if (!MemNode::all_controls_dominate(address, region))
-    return NULL;
+  // Select Region to split through.
+  Node* region;
+  if (!base_is_phi) {
+    assert(mem->is_Phi(), "sanity");
+    region = mem->in(0);
+    // Skip if the region dominates some control edge of the address.
+    if (!MemNode::all_controls_dominate(address, region))
+      return NULL;
+  } else if (!mem->is_Phi()) {
+    assert(base_is_phi, "sanity");
+    region = base->in(0);
+    // Skip if the region dominates some control edge of the memory.
+    if (!MemNode::all_controls_dominate(mem, region))
+      return NULL;
+  } else if (base->in(0) != mem->in(0)) {
+    assert(base_is_phi && mem->is_Phi(), "sanity");
+    if (MemNode::all_controls_dominate(mem, base->in(0))) {
+      region = base->in(0);
+    } else if (MemNode::all_controls_dominate(address, mem->in(0))) {
+      region = mem->in(0);
+    } else {
+      return NULL; // complex graph
+    }
+  } else {
+    assert(base->in(0) == mem->in(0), "sanity");
+    region = mem->in(0);
+  }
 
   const Type* this_type = this->bottom_type();
-  int this_index  = phase->C->get_alias_index(addr_t);
-  int this_offset = addr_t->offset();
-  int this_iid    = addr_t->is_oopptr()->instance_id();
-  PhaseIterGVN *igvn = phase->is_IterGVN();
-  Node *phi = new (igvn->C) PhiNode(region, this_type, NULL, this_iid, this_index, this_offset);
+  int this_index  = C->get_alias_index(t_oop);
+  int this_offset = t_oop->offset();
+  int this_iid    = t_oop->instance_id();
+  if (!t_oop->is_known_instance() && load_boxed_values) {
+    // Use _idx of address base for boxed values.
+    this_iid = base->_idx;
+  }
+  PhaseIterGVN* igvn = phase->is_IterGVN();
+  Node* phi = new (C) PhiNode(region, this_type, NULL, this_iid, this_index, this_offset);
   for (uint i = 1; i < region->req(); i++) {
-    Node *x;
+    Node* x;
     Node* the_clone = NULL;
-    if (region->in(i) == phase->C->top()) {
-      x = phase->C->top();      // Dead path?  Use a dead data op
+    if (region->in(i) == C->top()) {
+      x = C->top();      // Dead path?  Use a dead data op
     } else {
       x = this->clone();        // Else clone up the data op
       the_clone = x;            // Remember for possible deletion.
@@ -1361,10 +1397,16 @@
       } else {
         x->set_req(0, NULL);
       }
-      for (uint j = 1; j < this->req(); j++) {
-        Node *in = this->in(j);
-        if (in->is_Phi() && in->in(0) == region)
-          x->set_req(j, in->in(i)); // Use pre-Phi input for the clone
+      if (mem->is_Phi() && (mem->in(0) == region)) {
+        x->set_req(Memory, mem->in(i)); // Use pre-Phi input for the clone.
+      }
+      if (address->is_Phi() && address->in(0) == region) {
+        x->set_req(Address, address->in(i)); // Use pre-Phi input for the clone
+      }
+      if (base_is_phi && (base->in(0) == region)) {
+        Node* base_x = base->in(i); // Clone address for loads from boxed objects.
+        Node* adr_x = phase->transform(new (C) AddPNode(base_x,base_x,address->in(AddPNode::Offset)));
+        x->set_req(Address, adr_x);
       }
     }
     // Check for a 'win' on some paths
@@ -1394,7 +1436,7 @@
       if (y != x) {
         x = y;
       } else {
-        y = igvn->hash_find(x);
+        y = igvn->hash_find_insert(x);
         if (y) {
           x = y;
         } else {
@@ -1405,8 +1447,9 @@
         }
       }
     }
-    if (x != the_clone && the_clone != NULL)
+    if (x != the_clone && the_clone != NULL) {
       igvn->remove_dead_node(the_clone);
+    }
     phi->set_req(i, x);
   }
   // Record Phi
@@ -1445,31 +1488,23 @@
       // A method-invariant, non-null address (constant or 'this' argument).
       set_req(MemNode::Control, NULL);
     }
-
-    if (EliminateAutoBox && can_reshape) {
-      assert(!phase->type(base)->higher_equal(TypePtr::NULL_PTR), "the autobox pointer should be non-null");
-      Compile::AliasType* atp = phase->C->alias_type(adr_type());
-      if (is_autobox_object(atp)) {
-        Node* result = eliminate_autobox(phase);
-        if (result != NULL) return result;
-      }
-    }
   }
 
   Node* mem = in(MemNode::Memory);
   const TypePtr *addr_t = phase->type(address)->isa_ptr();
 
-  if (addr_t != NULL) {
+  if (can_reshape && (addr_t != NULL)) {
     // try to optimize our memory input
-    Node* opt_mem = MemNode::optimize_memory_chain(mem, addr_t, phase);
+    Node* opt_mem = MemNode::optimize_memory_chain(mem, addr_t, this, phase);
     if (opt_mem != mem) {
       set_req(MemNode::Memory, opt_mem);
       if (phase->type( opt_mem ) == Type::TOP) return NULL;
       return this;
     }
     const TypeOopPtr *t_oop = addr_t->isa_oopptr();
-    if (can_reshape && opt_mem->is_Phi() &&
-        (t_oop != NULL) && t_oop->is_known_instance_field()) {
+    if ((t_oop != NULL) &&
+        (t_oop->is_known_instance_field() ||
+         t_oop->is_ptr_to_boxed_value())) {
       PhaseIterGVN *igvn = phase->is_IterGVN();
       if (igvn != NULL && igvn->_worklist.member(opt_mem)) {
         // Delay this transformation until memory Phi is processed.
@@ -1479,6 +1514,11 @@
       // Split instance field load through Phi.
       Node* result = split_through_phi(phase);
       if (result != NULL) return result;
+
+      if (t_oop->is_ptr_to_boxed_value()) {
+        Node* result = eliminate_autobox(phase);
+        if (result != NULL) return result;
+      }
     }
   }
 
@@ -1587,18 +1627,23 @@
           // This can happen if a interface-typed array narrows to a class type.
           jt = _type;
         }
-
-        if (EliminateAutoBox && adr->is_AddP()) {
+#ifdef ASSERT
+        if (phase->C->eliminate_boxing() && adr->is_AddP()) {
           // The pointers in the autobox arrays are always non-null
           Node* base = adr->in(AddPNode::Base);
-          if (base != NULL &&
-              !phase->type(base)->higher_equal(TypePtr::NULL_PTR)) {
-            Compile::AliasType* atp = C->alias_type(base->adr_type());
-            if (is_autobox_cache(atp)) {
-              return jt->join(TypePtr::NOTNULL)->is_ptr();
+          if ((base != NULL) && base->is_DecodeN()) {
+            // Get LoadN node which loads IntegerCache.cache field
+            base = base->in(1);
+          }
+          if ((base != NULL) && base->is_Con()) {
+            const TypeAryPtr* base_type = base->bottom_type()->isa_aryptr();
+            if ((base_type != NULL) && base_type->is_autobox_cache()) {
+              // It could be narrow oop
+              assert(jt->make_ptr()->ptr() == TypePtr::NotNull,"sanity");
             }
           }
         }
+#endif
         return jt;
       }
     }
@@ -1638,6 +1683,10 @@
     // Optimizations for constant objects
     ciObject* const_oop = tinst->const_oop();
     if (const_oop != NULL) {
+      // For constant Boxed value treat the target field as a compile time constant.
+      if (tinst->is_ptr_to_boxed_value()) {
+        return tinst->get_const_boxed_value();
+      } else
       // For constant CallSites treat the target field as a compile time constant.
       if (const_oop->is_call_site()) {
         ciCallSite* call_site = const_oop->as_call_site();
@@ -1759,7 +1808,8 @@
   // (Also allow a variable load from a fresh array to produce zero.)
   const TypeOopPtr *tinst = tp->isa_oopptr();
   bool is_instance = (tinst != NULL) && tinst->is_known_instance_field();
-  if (ReduceFieldZeroing || is_instance) {
+  bool is_boxed_value = (tinst != NULL) && tinst->is_ptr_to_boxed_value();
+  if (ReduceFieldZeroing || is_instance || is_boxed_value) {
     Node* value = can_see_stored_value(mem,phase);
     if (value != NULL && value->is_Con()) {
       assert(value->bottom_type()->higher_equal(_type),"sanity");
@@ -2883,24 +2933,38 @@
   if (in(0) && in(0)->is_top())  return NULL;
 
   // Eliminate volatile MemBars for scalar replaced objects.
-  if (can_reshape && req() == (Precedent+1) &&
-      (Opcode() == Op_MemBarAcquire || Opcode() == Op_MemBarVolatile)) {
-    // Volatile field loads and stores.
-    Node* my_mem = in(MemBarNode::Precedent);
-    if (my_mem != NULL && my_mem->is_Mem()) {
-      const TypeOopPtr* t_oop = my_mem->in(MemNode::Address)->bottom_type()->isa_oopptr();
-      // Check for scalar replaced object reference.
-      if( t_oop != NULL && t_oop->is_known_instance_field() &&
-          t_oop->offset() != Type::OffsetBot &&
-          t_oop->offset() != Type::OffsetTop) {
-        // Replace MemBar projections by its inputs.
-        PhaseIterGVN* igvn = phase->is_IterGVN();
-        igvn->replace_node(proj_out(TypeFunc::Memory), in(TypeFunc::Memory));
-        igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control));
-        // Must return either the original node (now dead) or a new node
-        // (Do not return a top here, since that would break the uniqueness of top.)
-        return new (phase->C) ConINode(TypeInt::ZERO);
+  if (can_reshape && req() == (Precedent+1)) {
+    bool eliminate = false;
+    int opc = Opcode();
+    if ((opc == Op_MemBarAcquire || opc == Op_MemBarVolatile)) {
+      // Volatile field loads and stores.
+      Node* my_mem = in(MemBarNode::Precedent);
+      if (my_mem != NULL && my_mem->is_Mem()) {
+        const TypeOopPtr* t_oop = my_mem->in(MemNode::Address)->bottom_type()->isa_oopptr();
+        // Check for scalar replaced object reference.
+        if( t_oop != NULL && t_oop->is_known_instance_field() &&
+            t_oop->offset() != Type::OffsetBot &&
+            t_oop->offset() != Type::OffsetTop) {
+          eliminate = true;
+        }
       }
+    } else if (opc == Op_MemBarRelease) {
+      // Final field stores.
+      Node* alloc = AllocateNode::Ideal_allocation(in(MemBarNode::Precedent), phase);
+      if ((alloc != NULL) && alloc->is_Allocate() &&
+          alloc->as_Allocate()->_is_non_escaping) {
+        // The allocated object does not escape.
+        eliminate = true;
+      }
+    }
+    if (eliminate) {
+      // Replace MemBar projections by its inputs.
+      PhaseIterGVN* igvn = phase->is_IterGVN();
+      igvn->replace_node(proj_out(TypeFunc::Memory), in(TypeFunc::Memory));
+      igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control));
+      // Must return either the original node (now dead) or a new node
+      // (Do not return a top here, since that would break the uniqueness of top.)
+      return new (phase->C) ConINode(TypeInt::ZERO);
     }
   }
   return NULL;
@@ -3113,9 +3177,7 @@
 // within the initialization without creating a vicious cycle, such as:
 //     { Foo p = new Foo(); p.next = p; }
 // True for constants and parameters and small combinations thereof.
-bool InitializeNode::detect_init_independence(Node* n,
-                                              bool st_is_pinned,
-                                              int& count) {
+bool InitializeNode::detect_init_independence(Node* n, int& count) {
   if (n == NULL)      return true;   // (can this really happen?)
   if (n->is_Proj())   n = n->in(0);
   if (n == this)      return false;  // found a cycle
@@ -3135,7 +3197,6 @@
     // a store is never pinned *before* the availability of its inputs.
     if (!MemNode::all_controls_dominate(n, this))
       return false;                  // failed to prove a good control
-
   }
 
   // Check data edges for possible dependencies on 'this'.
@@ -3145,7 +3206,7 @@
     if (m == NULL || m == n || m->is_top())  continue;
     uint first_i = n->find_edge(m);
     if (i != first_i)  continue;  // process duplicate edge just once
-    if (!detect_init_independence(m, st_is_pinned, count)) {
+    if (!detect_init_independence(m, count)) {
       return false;
     }
   }
@@ -3176,7 +3237,7 @@
     return FAIL;                // wrong allocation!  (store needs to float up)
   Node* val = st->in(MemNode::ValueIn);
   int complexity_count = 0;
-  if (!detect_init_independence(val, true, complexity_count))
+  if (!detect_init_independence(val, complexity_count))
     return FAIL;                // stored value must be 'simple enough'
 
   // The Store can be captured only if nothing after the allocation
diff --git a/hotspot/src/share/vm/opto/memnode.hpp b/hotspot/src/share/vm/opto/memnode.hpp
index 73b3e34..9a00990 100644
--- a/hotspot/src/share/vm/opto/memnode.hpp
+++ b/hotspot/src/share/vm/opto/memnode.hpp
@@ -75,8 +75,8 @@
                                       PhaseTransform* phase);
   static bool adr_phi_is_loop_invariant(Node* adr_phi, Node* cast);
 
-  static Node *optimize_simple_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase);
-  static Node *optimize_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase);
+  static Node *optimize_simple_memory_chain(Node *mchain, const TypeOopPtr *t_oop, Node *load, PhaseGVN *phase);
+  static Node *optimize_memory_chain(Node *mchain, const TypePtr *t_adr, Node *load, PhaseGVN *phase);
   // This one should probably be a phase-specific function:
   static bool all_controls_dominate(Node* dom, Node* sub);
 
@@ -1099,7 +1099,7 @@
 
   Node* make_raw_address(intptr_t offset, PhaseTransform* phase);
 
-  bool detect_init_independence(Node* n, bool st_is_pinned, int& count);
+  bool detect_init_independence(Node* n, int& count);
 
   void coalesce_subword_stores(intptr_t header_size, Node* size_in_bytes,
                                PhaseGVN* phase);
diff --git a/hotspot/src/share/vm/opto/multnode.cpp b/hotspot/src/share/vm/opto/multnode.cpp
index 2804141..dca8dbe 100644
--- a/hotspot/src/share/vm/opto/multnode.cpp
+++ b/hotspot/src/share/vm/opto/multnode.cpp
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "opto/callnode.hpp"
 #include "opto/matcher.hpp"
 #include "opto/multnode.hpp"
 #include "opto/opcodes.hpp"
@@ -73,13 +74,26 @@
   return (_con == TypeFunc::Control && def->is_CFG());
 }
 
+const Type* ProjNode::proj_type(const Type* t) const {
+  if (t == Type::TOP) {
+    return Type::TOP;
+  }
+  if (t == Type::BOTTOM) {
+    return Type::BOTTOM;
+  }
+  t = t->is_tuple()->field_at(_con);
+  Node* n = in(0);
+  if ((_con == TypeFunc::Parms) &&
+      n->is_CallStaticJava() && n->as_CallStaticJava()->is_boxing_method()) {
+    // The result of autoboxing is always non-null on normal path.
+    t = t->join(TypePtr::NOTNULL);
+  }
+  return t;
+}
+
 const Type *ProjNode::bottom_type() const {
-  if (in(0) == NULL)  return Type::TOP;
-  const Type *tb = in(0)->bottom_type();
-  if( tb == Type::TOP ) return Type::TOP;
-  if( tb == Type::BOTTOM ) return Type::BOTTOM;
-  const TypeTuple *t = tb->is_tuple();
-  return t->field_at(_con);
+  if (in(0) == NULL) return Type::TOP;
+  return proj_type(in(0)->bottom_type());
 }
 
 const TypePtr *ProjNode::adr_type() const {
@@ -115,11 +129,8 @@
 
 //------------------------------Value------------------------------------------
 const Type *ProjNode::Value( PhaseTransform *phase ) const {
-  if( !in(0) ) return Type::TOP;
-  const Type *t = phase->type(in(0));
-  if( t == Type::TOP ) return t;
-  if( t == Type::BOTTOM ) return t;
-  return t->is_tuple()->field_at(_con);
+  if (in(0) == NULL) return Type::TOP;
+  return proj_type(phase->type(in(0)));
 }
 
 //------------------------------out_RegMask------------------------------------
diff --git a/hotspot/src/share/vm/opto/multnode.hpp b/hotspot/src/share/vm/opto/multnode.hpp
index fba94e5..242e58f 100644
--- a/hotspot/src/share/vm/opto/multnode.hpp
+++ b/hotspot/src/share/vm/opto/multnode.hpp
@@ -60,6 +60,7 @@
   virtual uint cmp( const Node &n ) const;
   virtual uint size_of() const;
   void check_con() const;       // Called from constructor.
+  const Type* proj_type(const Type* t) const;
 
 public:
   ProjNode( Node *src, uint con, bool io_use = false )
@@ -83,6 +84,7 @@
   virtual const Type *Value( PhaseTransform *phase ) const;
   virtual uint ideal_reg() const;
   virtual const RegMask &out_RegMask() const;
+
 #ifndef PRODUCT
   virtual void dump_spec(outputStream *st) const;
 #endif
diff --git a/hotspot/src/share/vm/opto/node.cpp b/hotspot/src/share/vm/opto/node.cpp
index e1698b2..f210004 100644
--- a/hotspot/src/share/vm/opto/node.cpp
+++ b/hotspot/src/share/vm/opto/node.cpp
@@ -67,7 +67,8 @@
   }
   Compile::set_debug_idx(new_debug_idx);
   set_debug_idx( new_debug_idx );
-  assert(Compile::current()->unique() < (UINT_MAX - 1), "Node limit exceeded UINT_MAX");
+  assert(Compile::current()->unique() < (INT_MAX - 1), "Node limit exceeded INT_MAX");
+  assert(Compile::current()->live_nodes() < (uint)MaxNodeLimit, "Live Node limit exceeded limit");
   if (BreakAtNode != 0 && (_debug_idx == BreakAtNode || (int)_idx == BreakAtNode)) {
     tty->print_cr("BreakAtNode: _idx=%d _debug_idx=%d", _idx, _debug_idx);
     BREAKPOINT;
@@ -471,9 +472,9 @@
 //------------------------------clone------------------------------------------
 // Clone a Node.
 Node *Node::clone() const {
-  Compile *compile = Compile::current();
+  Compile* C = Compile::current();
   uint s = size_of();           // Size of inherited Node
-  Node *n = (Node*)compile->node_arena()->Amalloc_D(size_of() + _max*sizeof(Node*));
+  Node *n = (Node*)C->node_arena()->Amalloc_D(size_of() + _max*sizeof(Node*));
   Copy::conjoint_words_to_lower((HeapWord*)this, (HeapWord*)n, s);
   // Set the new input pointer array
   n->_in = (Node**)(((char*)n)+s);
@@ -492,18 +493,18 @@
     if (x != NULL) x->add_out(n);
   }
   if (is_macro())
-    compile->add_macro_node(n);
+    C->add_macro_node(n);
   if (is_expensive())
-    compile->add_expensive_node(n);
+    C->add_expensive_node(n);
 
-  n->set_idx(compile->next_unique()); // Get new unique index as well
+  n->set_idx(C->next_unique()); // Get new unique index as well
   debug_only( n->verify_construction() );
   NOT_PRODUCT(nodes_created++);
   // Do not patch over the debug_idx of a clone, because it makes it
   // impossible to break on the clone's moment of creation.
   //debug_only( n->set_debug_idx( debug_idx() ) );
 
-  compile->copy_node_notes_to(n, (Node*) this);
+  C->copy_node_notes_to(n, (Node*) this);
 
   // MachNode clone
   uint nopnds;
@@ -518,13 +519,12 @@
                                   (const void*)(&mthis->_opnds), 1));
     mach->_opnds = to;
     for ( uint i = 0; i < nopnds; ++i ) {
-      to[i] = from[i]->clone(compile);
+      to[i] = from[i]->clone(C);
     }
   }
   // cloning CallNode may need to clone JVMState
   if (n->is_Call()) {
-    CallNode *call = n->as_Call();
-    call->clone_jvms();
+    n->as_Call()->clone_jvms(C);
   }
   return n;                     // Return the clone
 }
@@ -811,6 +811,21 @@
   return nrep;
 }
 
+/**
+ * Replace input edges in the range pointing to 'old' node.
+ */
+int Node::replace_edges_in_range(Node* old, Node* neww, int start, int end) {
+  if (old == neww)  return 0;  // nothing to do
+  uint nrep = 0;
+  for (int i = start; i < end; i++) {
+    if (in(i) == old) {
+      set_req(i, neww);
+      nrep++;
+    }
+  }
+  return nrep;
+}
+
 //-------------------------disconnect_inputs-----------------------------------
 // NULL out all inputs to eliminate incoming Def-Use edges.
 // Return the number of edges between 'n' and 'this'
@@ -1383,6 +1398,21 @@
   return NULL;
 }
 
+
+/**
+ * Return a ptr type for nodes which should have it.
+ */
+const TypePtr* Node::get_ptr_type() const {
+  const TypePtr* tp = this->bottom_type()->make_ptr();
+#ifdef ASSERT
+  if (tp == NULL) {
+    this->dump(1);
+    assert((tp != NULL), "unexpected node type");
+  }
+#endif
+  return tp;
+}
+
 // Get a double constant from a ConstNode.
 // Returns the constant if it is a double ConstNode
 jdouble Node::getd() const {
diff --git a/hotspot/src/share/vm/opto/node.hpp b/hotspot/src/share/vm/opto/node.hpp
index f8f2c24..bb5e8f2 100644
--- a/hotspot/src/share/vm/opto/node.hpp
+++ b/hotspot/src/share/vm/opto/node.hpp
@@ -410,6 +410,7 @@
   // Find first occurrence of n among my edges:
   int find_edge(Node* n);
   int replace_edge(Node* old, Node* neww);
+  int replace_edges_in_range(Node* old, Node* neww, int start, int end);
   // NULL out all inputs to eliminate incoming Def-Use edges.
   // Return the number of edges between 'n' and 'this'
   int  disconnect_inputs(Node *n, Compile *c);
@@ -964,6 +965,8 @@
   }
   const TypeLong* find_long_type() const;
 
+  const TypePtr* get_ptr_type() const;
+
   // These guys are called by code generated by ADLC:
   intptr_t get_ptr() const;
   intptr_t get_narrowcon() const;
diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp
index f5a1e08..f04ab72 100644
--- a/hotspot/src/share/vm/opto/output.cpp
+++ b/hotspot/src/share/vm/opto/output.cpp
@@ -929,7 +929,7 @@
           scval = new_loc_value( _regalloc, obj_reg, Location::oop );
         }
       } else {
-        const TypePtr *tp = obj_node->bottom_type()->make_ptr();
+        const TypePtr *tp = obj_node->get_ptr_type();
         scval = new ConstantOopWriteValue(tp->is_oopptr()->const_oop()->constant_encoding());
       }
 
diff --git a/hotspot/src/share/vm/opto/parse.hpp b/hotspot/src/share/vm/opto/parse.hpp
index c38f96b..91025bf 100644
--- a/hotspot/src/share/vm/opto/parse.hpp
+++ b/hotspot/src/share/vm/opto/parse.hpp
@@ -330,6 +330,7 @@
   bool          _wrote_final;   // Did we write a final field?
   bool          _count_invocations; // update and test invocation counter
   bool          _method_data_update; // update method data oop
+  Node*         _alloc_with_final;   // An allocation node with final field
 
   // Variables which track Java semantics during bytecode parsing:
 
@@ -370,6 +371,11 @@
   void      set_wrote_final(bool z)   { _wrote_final = z; }
   bool          count_invocations() const  { return _count_invocations; }
   bool          method_data_update() const { return _method_data_update; }
+  Node*    alloc_with_final() const   { return _alloc_with_final; }
+  void set_alloc_with_final(Node* n)  {
+    assert((_alloc_with_final == NULL) || (_alloc_with_final == n), "different init objects?");
+    _alloc_with_final = n;
+  }
 
   Block*             block()    const { return _block; }
   ciBytecodeStream&  iter()           { return _iter; }
@@ -512,7 +518,7 @@
 
   // loading from a constant field or the constant pool
   // returns false if push failed (non-perm field constants only, not ldcs)
-  bool push_constant(ciConstant con, bool require_constant = false);
+  bool push_constant(ciConstant con, bool require_constant = false, bool is_autobox_cache = false);
 
   // implementation of object creation bytecodes
   void emit_guard_for_new(ciInstanceKlass* klass);
diff --git a/hotspot/src/share/vm/opto/parse1.cpp b/hotspot/src/share/vm/opto/parse1.cpp
index f0f7c8b..10d98b9 100644
--- a/hotspot/src/share/vm/opto/parse1.cpp
+++ b/hotspot/src/share/vm/opto/parse1.cpp
@@ -390,6 +390,7 @@
   _expected_uses = expected_uses;
   _depth = 1 + (caller->has_method() ? caller->depth() : 0);
   _wrote_final = false;
+  _alloc_with_final = NULL;
   _entry_bci = InvocationEntryBci;
   _tf = NULL;
   _block = NULL;
@@ -723,6 +724,8 @@
   // Note:  iophi and memphi are not transformed until do_exits.
   Node* iophi  = new (C) PhiNode(region, Type::ABIO);
   Node* memphi = new (C) PhiNode(region, Type::MEMORY, TypePtr::BOTTOM);
+  gvn().set_type_bottom(iophi);
+  gvn().set_type_bottom(memphi);
   _exits.set_i_o(iophi);
   _exits.set_all_memory(memphi);
 
@@ -738,6 +741,7 @@
     }
     int         ret_size = type2size[ret_type->basic_type()];
     Node*       ret_phi  = new (C) PhiNode(region, ret_type);
+    gvn().set_type_bottom(ret_phi);
     _exits.ensure_stack(ret_size);
     assert((int)(tf()->range()->cnt() - TypeFunc::Parms) == ret_size, "good tf range");
     assert(method()->return_type()->size() == ret_size, "tf agrees w/ method");
@@ -917,7 +921,7 @@
     // such unusual early publications.  But no barrier is needed on
     // exceptional returns, since they cannot publish normally.
     //
-    _exits.insert_mem_bar(Op_MemBarRelease);
+    _exits.insert_mem_bar(Op_MemBarRelease, alloc_with_final());
 #ifndef PRODUCT
     if (PrintOpto && (Verbose || WizardMode)) {
       method()->print_name();
diff --git a/hotspot/src/share/vm/opto/parse2.cpp b/hotspot/src/share/vm/opto/parse2.cpp
index 73be6aa..c41ca25 100644
--- a/hotspot/src/share/vm/opto/parse2.cpp
+++ b/hotspot/src/share/vm/opto/parse2.cpp
@@ -987,7 +987,7 @@
     uncommon_trap(Deoptimization::Reason_unreached,
                   Deoptimization::Action_reinterpret,
                   NULL, "cold");
-    if (EliminateAutoBox) {
+    if (C->eliminate_boxing()) {
       // Mark the successor blocks as parsed
       branch_block->next_path_num();
       next_block->next_path_num();
@@ -1012,7 +1012,7 @@
 
     if (stopped()) {            // Path is dead?
       explicit_null_checks_elided++;
-      if (EliminateAutoBox) {
+      if (C->eliminate_boxing()) {
         // Mark the successor block as parsed
         branch_block->next_path_num();
       }
@@ -1032,7 +1032,7 @@
 
   if (stopped()) {              // Path is dead?
     explicit_null_checks_elided++;
-    if (EliminateAutoBox) {
+    if (C->eliminate_boxing()) {
       // Mark the successor block as parsed
       next_block->next_path_num();
     }
@@ -1069,7 +1069,7 @@
     uncommon_trap(Deoptimization::Reason_unreached,
                   Deoptimization::Action_reinterpret,
                   NULL, "cold");
-    if (EliminateAutoBox) {
+    if (C->eliminate_boxing()) {
       // Mark the successor blocks as parsed
       branch_block->next_path_num();
       next_block->next_path_num();
@@ -1135,7 +1135,7 @@
     set_control(taken_branch);
 
     if (stopped()) {
-      if (EliminateAutoBox) {
+      if (C->eliminate_boxing()) {
         // Mark the successor block as parsed
         branch_block->next_path_num();
       }
@@ -1154,7 +1154,7 @@
 
   // Branch not taken.
   if (stopped()) {
-    if (EliminateAutoBox) {
+    if (C->eliminate_boxing()) {
       // Mark the successor block as parsed
       next_block->next_path_num();
     }
diff --git a/hotspot/src/share/vm/opto/parse3.cpp b/hotspot/src/share/vm/opto/parse3.cpp
index 9de92a2..acabf49 100644
--- a/hotspot/src/share/vm/opto/parse3.cpp
+++ b/hotspot/src/share/vm/opto/parse3.cpp
@@ -150,6 +150,23 @@
     // final field
     if (field->is_static()) {
       // final static field
+      if (C->eliminate_boxing()) {
+        // The pointers in the autobox arrays are always non-null.
+        ciSymbol* klass_name = field->holder()->name();
+        if (field->name() == ciSymbol::cache_field_name() &&
+            field->holder()->uses_default_loader() &&
+            (klass_name == ciSymbol::java_lang_Character_CharacterCache() ||
+             klass_name == ciSymbol::java_lang_Byte_ByteCache() ||
+             klass_name == ciSymbol::java_lang_Short_ShortCache() ||
+             klass_name == ciSymbol::java_lang_Integer_IntegerCache() ||
+             klass_name == ciSymbol::java_lang_Long_LongCache())) {
+          bool require_const = true;
+          bool autobox_cache = true;
+          if (push_constant(field->constant_value(), require_const, autobox_cache)) {
+            return;
+          }
+        }
+      }
       if (push_constant(field->constant_value()))
         return;
     }
@@ -304,11 +321,18 @@
   // out of the constructor.
   if (is_field && field->is_final()) {
     set_wrote_final(true);
+    // Preserve allocation ptr to create precedent edge to it in membar
+    // generated on exit from constructor.
+    if (C->eliminate_boxing() &&
+        adr_type->isa_oopptr() && adr_type->is_oopptr()->is_ptr_to_boxed_value() &&
+        AllocateNode::Ideal_allocation(obj, &_gvn) != NULL) {
+      set_alloc_with_final(obj);
+    }
   }
 }
 
 
-bool Parse::push_constant(ciConstant constant, bool require_constant) {
+bool Parse::push_constant(ciConstant constant, bool require_constant, bool is_autobox_cache) {
   switch (constant.basic_type()) {
   case T_BOOLEAN:  push( intcon(constant.as_boolean()) ); break;
   case T_INT:      push( intcon(constant.as_int())     ); break;
@@ -329,7 +353,7 @@
       push( zerocon(T_OBJECT) );
       break;
     } else if (require_constant || oop_constant->should_be_constant()) {
-      push( makecon(TypeOopPtr::make_from_constant(oop_constant, require_constant)) );
+      push( makecon(TypeOopPtr::make_from_constant(oop_constant, require_constant, is_autobox_cache)) );
       break;
     } else {
       // we cannot inline the oop, but we can use it later to narrow a type
diff --git a/hotspot/src/share/vm/opto/parseHelper.cpp b/hotspot/src/share/vm/opto/parseHelper.cpp
index e948608..5d0c2f7 100644
--- a/hotspot/src/share/vm/opto/parseHelper.cpp
+++ b/hotspot/src/share/vm/opto/parseHelper.cpp
@@ -284,6 +284,11 @@
        klass == C->env()->StringBuffer_klass())) {
     C->set_has_stringbuilder(true);
   }
+
+  // Keep track of boxed values for EliminateAutoBox optimizations.
+  if (C->eliminate_boxing() && klass->is_box_klass()) {
+    C->set_has_boxed_value(true);
+  }
 }
 
 #ifndef PRODUCT
diff --git a/hotspot/src/share/vm/opto/phase.cpp b/hotspot/src/share/vm/opto/phase.cpp
index 0b88996..5359301 100644
--- a/hotspot/src/share/vm/opto/phase.cpp
+++ b/hotspot/src/share/vm/opto/phase.cpp
@@ -64,6 +64,7 @@
 // Subtimers for _t_optimizer
 elapsedTimer   Phase::_t_iterGVN;
 elapsedTimer   Phase::_t_iterGVN2;
+elapsedTimer   Phase::_t_incrInline;
 
 // Subtimers for _t_registerAllocation
 elapsedTimer   Phase::_t_ctorChaitin;
@@ -110,6 +111,7 @@
       tty->print_cr ("      macroEliminate : %3.3f sec", Phase::_t_macroEliminate.seconds());
     }
     tty->print_cr ("      iterGVN        : %3.3f sec", Phase::_t_iterGVN.seconds());
+    tty->print_cr ("      incrInline     : %3.3f sec", Phase::_t_incrInline.seconds());
     tty->print_cr ("      idealLoop      : %3.3f sec", Phase::_t_idealLoop.seconds());
     tty->print_cr ("      idealLoopVerify: %3.3f sec", Phase::_t_idealLoopVerify.seconds());
     tty->print_cr ("      ccp            : %3.3f sec", Phase::_t_ccp.seconds());
diff --git a/hotspot/src/share/vm/opto/phase.hpp b/hotspot/src/share/vm/opto/phase.hpp
index 9faabf5..582a126 100644
--- a/hotspot/src/share/vm/opto/phase.hpp
+++ b/hotspot/src/share/vm/opto/phase.hpp
@@ -100,6 +100,7 @@
 // Subtimers for _t_optimizer
   static elapsedTimer   _t_iterGVN;
   static elapsedTimer   _t_iterGVN2;
+  static elapsedTimer   _t_incrInline;
 
 // Subtimers for _t_registerAllocation
   static elapsedTimer   _t_ctorChaitin;
diff --git a/hotspot/src/share/vm/opto/phaseX.cpp b/hotspot/src/share/vm/opto/phaseX.cpp
index a8c9796..654c6f7 100644
--- a/hotspot/src/share/vm/opto/phaseX.cpp
+++ b/hotspot/src/share/vm/opto/phaseX.cpp
@@ -882,7 +882,7 @@
       return;
     }
     Node *n  = _worklist.pop();
-    if (++loop_count >= K * C->unique()) {
+    if (++loop_count >= K * C->live_nodes()) {
       debug_only(n->dump(4);)
       assert(false, "infinite loop in PhaseIterGVN::optimize");
       C->record_method_not_compilable("infinite loop in PhaseIterGVN::optimize");
diff --git a/hotspot/src/share/vm/opto/runtime.cpp b/hotspot/src/share/vm/opto/runtime.cpp
index 7edb97e..d0aefad 100644
--- a/hotspot/src/share/vm/opto/runtime.cpp
+++ b/hotspot/src/share/vm/opto/runtime.cpp
@@ -126,17 +126,15 @@
 
 // This should be called in an assertion at the start of OptoRuntime routines
 // which are entered from compiled code (all of them)
-#ifndef PRODUCT
+#ifdef ASSERT
 static bool check_compiled_frame(JavaThread* thread) {
   assert(thread->last_frame().is_runtime_frame(), "cannot call runtime directly from compiled code");
-#ifdef ASSERT
   RegisterMap map(thread, false);
   frame caller = thread->last_frame().sender(&map);
   assert(caller.is_compiled_frame(), "not being called from compiled like code");
-#endif  /* ASSERT */
   return true;
 }
-#endif
+#endif // ASSERT
 
 
 #define gen(env, var, type_func_gen, c_func, fancy_jump, pass_tls, save_arg_regs, return_pc) \
diff --git a/hotspot/src/share/vm/opto/subnode.cpp b/hotspot/src/share/vm/opto/subnode.cpp
index 70a64ba..275b4d8 100644
--- a/hotspot/src/share/vm/opto/subnode.cpp
+++ b/hotspot/src/share/vm/opto/subnode.cpp
@@ -863,10 +863,11 @@
   const TypePtr *r1 = t2->make_ptr();
 
   // Undefined inputs makes for an undefined result
-  if( TypePtr::above_centerline(r0->_ptr) ||
-      TypePtr::above_centerline(r1->_ptr) )
+  if ((r0 == NULL) || (r1 == NULL) ||
+      TypePtr::above_centerline(r0->_ptr) ||
+      TypePtr::above_centerline(r1->_ptr)) {
     return Type::TOP;
-
+  }
   if (r0 == r1 && r0->singleton()) {
     // Equal pointer constants (klasses, nulls, etc.)
     return TypeInt::CC_EQ;
diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp
index 68f6813..fabcf1c 100644
--- a/hotspot/src/share/vm/opto/type.cpp
+++ b/hotspot/src/share/vm/opto/type.cpp
@@ -2372,7 +2372,12 @@
     _klass_is_exact(xk),
     _is_ptr_to_narrowoop(false),
     _is_ptr_to_narrowklass(false),
+    _is_ptr_to_boxed_value(false),
     _instance_id(instance_id) {
+  if (Compile::current()->eliminate_boxing() && (t == InstPtr) &&
+      (offset > 0) && xk && (k != 0) && k->is_instance_klass()) {
+    _is_ptr_to_boxed_value = k->as_instance_klass()->is_boxed_value_offset(offset);
+  }
 #ifdef _LP64
   if (_offset != 0) {
     if (_offset == oopDesc::klass_offset_in_bytes()) {
@@ -2613,44 +2618,50 @@
 
 //------------------------------make_from_constant-----------------------------
 // Make a java pointer from an oop constant
-const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_constant) {
-    assert(!o->is_null_object(), "null object not yet handled here.");
-    ciKlass* klass = o->klass();
-    if (klass->is_instance_klass()) {
-      // Element is an instance
-      if (require_constant) {
-        if (!o->can_be_constant())  return NULL;
-      } else if (!o->should_be_constant()) {
-        return TypeInstPtr::make(TypePtr::NotNull, klass, true, NULL, 0);
-      }
-      return TypeInstPtr::make(o);
-    } else if (klass->is_obj_array_klass()) {
-      // Element is an object array. Recursively call ourself.
-    const Type *etype =
+const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o,
+                                                 bool require_constant,
+                                                 bool is_autobox_cache) {
+  assert(!o->is_null_object(), "null object not yet handled here.");
+  ciKlass* klass = o->klass();
+  if (klass->is_instance_klass()) {
+    // Element is an instance
+    if (require_constant) {
+      if (!o->can_be_constant())  return NULL;
+    } else if (!o->should_be_constant()) {
+      return TypeInstPtr::make(TypePtr::NotNull, klass, true, NULL, 0);
+    }
+    return TypeInstPtr::make(o);
+  } else if (klass->is_obj_array_klass()) {
+    // Element is an object array. Recursively call ourself.
+    const TypeOopPtr *etype =
       TypeOopPtr::make_from_klass_raw(klass->as_obj_array_klass()->element_klass());
-      const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length()));
-      // We used to pass NotNull in here, asserting that the sub-arrays
-      // are all not-null.  This is not true in generally, as code can
-      // slam NULLs down in the subarrays.
-      if (require_constant) {
-        if (!o->can_be_constant())  return NULL;
-      } else if (!o->should_be_constant()) {
-        return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
-      }
-    const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
+    if (is_autobox_cache) {
+      // The pointers in the autobox arrays are always non-null.
+      etype = etype->cast_to_ptr_type(TypePtr::NotNull)->is_oopptr();
+    }
+    const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length()));
+    // We used to pass NotNull in here, asserting that the sub-arrays
+    // are all not-null.  This is not true in generally, as code can
+    // slam NULLs down in the subarrays.
+    if (require_constant) {
+      if (!o->can_be_constant())  return NULL;
+    } else if (!o->should_be_constant()) {
+      return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
+    }
+    const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0, InstanceBot, is_autobox_cache);
     return arr;
-    } else if (klass->is_type_array_klass()) {
-      // Element is an typeArray
+  } else if (klass->is_type_array_klass()) {
+    // Element is an typeArray
     const Type* etype =
       (Type*)get_const_basic_type(klass->as_type_array_klass()->element_type());
-      const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length()));
-      // We used to pass NotNull in here, asserting that the array pointer
-      // is not-null. That was not true in general.
-      if (require_constant) {
-        if (!o->can_be_constant())  return NULL;
-      } else if (!o->should_be_constant()) {
-        return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
-      }
+    const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length()));
+    // We used to pass NotNull in here, asserting that the array pointer
+    // is not-null. That was not true in general.
+    if (require_constant) {
+      if (!o->can_be_constant())  return NULL;
+    } else if (!o->should_be_constant()) {
+      return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
+    }
     const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
     return arr;
   }
@@ -2856,6 +2867,28 @@
   return result;
 }
 
+/**
+ *  Create constant type for a constant boxed value
+ */
+const Type* TypeInstPtr::get_const_boxed_value() const {
+  assert(is_ptr_to_boxed_value(), "should be called only for boxed value");
+  assert((const_oop() != NULL), "should be called only for constant object");
+  ciConstant constant = const_oop()->as_instance()->field_value_by_offset(offset());
+  BasicType bt = constant.basic_type();
+  switch (bt) {
+    case T_BOOLEAN:  return TypeInt::make(constant.as_boolean());
+    case T_INT:      return TypeInt::make(constant.as_int());
+    case T_CHAR:     return TypeInt::make(constant.as_char());
+    case T_BYTE:     return TypeInt::make(constant.as_byte());
+    case T_SHORT:    return TypeInt::make(constant.as_short());
+    case T_FLOAT:    return TypeF::make(constant.as_float());
+    case T_DOUBLE:   return TypeD::make(constant.as_double());
+    case T_LONG:     return TypeLong::make(constant.as_long());
+    default:         break;
+  }
+  fatal(err_msg_res("Invalid boxed value type '%s'", type2name(bt)));
+  return NULL;
+}
 
 //------------------------------cast_to_ptr_type-------------------------------
 const Type *TypeInstPtr::cast_to_ptr_type(PTR ptr) const {
@@ -3330,18 +3363,18 @@
   if (!xk)  xk = ary->ary_must_be_exact();
   assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed");
   if (!UseExactTypes)  xk = (ptr == Constant);
-  return (TypeAryPtr*)(new TypeAryPtr(ptr, NULL, ary, k, xk, offset, instance_id))->hashcons();
+  return (TypeAryPtr*)(new TypeAryPtr(ptr, NULL, ary, k, xk, offset, instance_id, false))->hashcons();
 }
 
 //------------------------------make-------------------------------------------
-const TypeAryPtr *TypeAryPtr::make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id ) {
+const TypeAryPtr *TypeAryPtr::make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id, bool is_autobox_cache) {
   assert(!(k == NULL && ary->_elem->isa_int()),
          "integral arrays must be pre-equipped with a class");
   assert( (ptr==Constant && o) || (ptr!=Constant && !o), "" );
   if (!xk)  xk = (o != NULL) || ary->ary_must_be_exact();
   assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed");
   if (!UseExactTypes)  xk = (ptr == Constant);
-  return (TypeAryPtr*)(new TypeAryPtr(ptr, o, ary, k, xk, offset, instance_id))->hashcons();
+  return (TypeAryPtr*)(new TypeAryPtr(ptr, o, ary, k, xk, offset, instance_id, is_autobox_cache))->hashcons();
 }
 
 //------------------------------cast_to_ptr_type-------------------------------
@@ -3397,8 +3430,20 @@
   jint max_hi = max_array_length(elem()->basic_type());
   //if (index_not_size)  --max_hi;     // type of a valid array index, FTR
   bool chg = false;
-  if (lo < min_lo) { lo = min_lo; chg = true; }
-  if (hi > max_hi) { hi = max_hi; chg = true; }
+  if (lo < min_lo) {
+    lo = min_lo;
+    if (size->is_con()) {
+      hi = lo;
+    }
+    chg = true;
+  }
+  if (hi > max_hi) {
+    hi = max_hi;
+    if (size->is_con()) {
+      lo = hi;
+    }
+    chg = true;
+  }
   // Negative length arrays will produce weird intermediate dead fast-path code
   if (lo > hi)
     return TypeInt::ZERO;
@@ -3630,7 +3675,7 @@
 //------------------------------xdual------------------------------------------
 // Dual: compute field-by-field dual
 const Type *TypeAryPtr::xdual() const {
-  return new TypeAryPtr( dual_ptr(), _const_oop, _ary->dual()->is_ary(),_klass, _klass_is_exact, dual_offset(), dual_instance_id() );
+  return new TypeAryPtr( dual_ptr(), _const_oop, _ary->dual()->is_ary(),_klass, _klass_is_exact, dual_offset(), dual_instance_id(), is_autobox_cache() );
 }
 
 //----------------------interface_vs_oop---------------------------------------
diff --git a/hotspot/src/share/vm/opto/type.hpp b/hotspot/src/share/vm/opto/type.hpp
index 7868b2f..0626cb5 100644
--- a/hotspot/src/share/vm/opto/type.hpp
+++ b/hotspot/src/share/vm/opto/type.hpp
@@ -234,6 +234,9 @@
   bool is_ptr_to_narrowoop() const;
   bool is_ptr_to_narrowklass() const;
 
+  bool is_ptr_to_boxing_obj() const;
+
+
   // Convenience access
   float getf() const;
   double getd() const;
@@ -794,6 +797,7 @@
   bool          _klass_is_exact;
   bool          _is_ptr_to_narrowoop;
   bool          _is_ptr_to_narrowklass;
+  bool          _is_ptr_to_boxed_value;
 
   // If not InstanceTop or InstanceBot, indicates that this is
   // a particular instance of this type which is distinct.
@@ -826,7 +830,9 @@
   // If the object cannot be rendered as a constant,
   // may return a non-singleton type.
   // If require_constant, produce a NULL if a singleton is not possible.
-  static const TypeOopPtr* make_from_constant(ciObject* o, bool require_constant = false);
+  static const TypeOopPtr* make_from_constant(ciObject* o,
+                                              bool require_constant = false,
+                                              bool not_null_elements = false);
 
   // Make a generic (unclassed) pointer to an oop.
   static const TypeOopPtr* make(PTR ptr, int offset, int instance_id);
@@ -839,7 +845,7 @@
   // compressed oop references.
   bool is_ptr_to_narrowoop_nv() const { return _is_ptr_to_narrowoop; }
   bool is_ptr_to_narrowklass_nv() const { return _is_ptr_to_narrowklass; }
-
+  bool is_ptr_to_boxed_value()   const { return _is_ptr_to_boxed_value; }
   bool is_known_instance()       const { return _instance_id > 0; }
   int  instance_id()             const { return _instance_id; }
   bool is_known_instance_field() const { return is_known_instance() && _offset >= 0; }
@@ -912,6 +918,9 @@
   // Make a pointer to an oop.
   static const TypeInstPtr *make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id = InstanceBot );
 
+  /** Create constant type for a constant boxed value */
+  const Type* get_const_boxed_value() const;
+
   // If this is a java.lang.Class constant, return the type for it or NULL.
   // Pass to Type::get_const_type to turn it to a type, which will usually
   // be a TypeInstPtr, but may also be a TypeInt::INT for int.class, etc.
@@ -943,7 +952,12 @@
 //------------------------------TypeAryPtr-------------------------------------
 // Class of Java array pointers
 class TypeAryPtr : public TypeOopPtr {
-  TypeAryPtr( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id ) : TypeOopPtr(AryPtr,ptr,k,xk,o,offset, instance_id), _ary(ary) {
+  TypeAryPtr( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk,
+              int offset, int instance_id, bool is_autobox_cache )
+  : TypeOopPtr(AryPtr,ptr,k,xk,o,offset, instance_id),
+    _ary(ary),
+    _is_autobox_cache(is_autobox_cache)
+ {
 #ifdef ASSERT
     if (k != NULL) {
       // Verify that specified klass and TypeAryPtr::klass() follow the same rules.
@@ -964,6 +978,7 @@
   virtual bool eq( const Type *t ) const;
   virtual int hash() const;     // Type specific hashing
   const TypeAry *_ary;          // Array we point into
+  const bool     _is_autobox_cache;
 
   ciKlass* compute_klass(DEBUG_ONLY(bool verify = false)) const;
 
@@ -974,9 +989,11 @@
   const Type*    elem() const { return _ary->_elem; }
   const TypeInt* size() const { return _ary->_size; }
 
+  bool is_autobox_cache() const { return _is_autobox_cache; }
+
   static const TypeAryPtr *make( PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot);
   // Constant pointer to array
-  static const TypeAryPtr *make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot);
+  static const TypeAryPtr *make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot, bool is_autobox_cache = false);
 
   // Return a 'ptr' version of this type
   virtual const Type *cast_to_ptr_type(PTR ptr) const;
@@ -1504,6 +1521,13 @@
   return false;
 }
 
+inline bool Type::is_ptr_to_boxing_obj() const {
+  const TypeInstPtr* tp = isa_instptr();
+  return (tp != NULL) && (tp->offset() == 0) &&
+         tp->klass()->is_instance_klass()  &&
+         tp->klass()->as_instance_klass()->is_box_klass();
+}
+
 
 // ===============================================================
 // Things that need to be 64-bits in the 64-bit build but
diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp
index 5c31ea1..bedfc61 100644
--- a/hotspot/src/share/vm/prims/jvm.cpp
+++ b/hotspot/src/share/vm/prims/jvm.cpp
@@ -1710,7 +1710,7 @@
     for (int i = 0; i < num_params; i++) {
       MethodParametersElement* params = mh->method_parameters_start();
       // For a 0 index, give a NULL symbol
-      Symbol* const sym = 0 != params[i].name_cp_index ?
+      Symbol* sym = 0 != params[i].name_cp_index ?
         mh->constants()->symbol_at(params[i].name_cp_index) : NULL;
       int flags = params[i].flags;
       oop param = Reflection::new_parameter(reflected_method, i, sym,
diff --git a/hotspot/src/share/vm/prims/jvmtiExport.cpp b/hotspot/src/share/vm/prims/jvmtiExport.cpp
index ab66dca..1e430e9 100644
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp
@@ -619,6 +619,9 @@
         // data has been changed by the new retransformable agent
         // and it hasn't already been cached, cache it
         *_cached_data_ptr = (unsigned char *)os::malloc(_curr_len, mtInternal);
+        if (*_cached_data_ptr == NULL) {
+          vm_exit_out_of_memory(_curr_len, OOM_MALLOC_ERROR, "unable to allocate cached copy of original class bytes");
+        }
         memcpy(*_cached_data_ptr, _curr_data, _curr_len);
         *_cached_length_ptr = _curr_len;
       }
diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
index 4e8e8c0..c571534 100644
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
@@ -160,7 +160,8 @@
   if (RC_TRACE_ENABLED(0x00004000)) {
 #endif
     RC_TRACE_WITH_THREAD(0x00004000, thread, ("calling check_class"));
-    SystemDictionary::classes_do(check_class, thread);
+    CheckClass check_class(thread);
+    ClassLoaderDataGraph::classes_do(&check_class);
 #ifdef PRODUCT
   }
 #endif
@@ -2653,29 +2654,35 @@
 } // end set_new_constant_pool()
 
 
-void VM_RedefineClasses::adjust_array_vtable(Klass* k_oop) {
-  ArrayKlass* ak = ArrayKlass::cast(k_oop);
-  bool trace_name_printed = false;
-  ak->vtable()->adjust_method_entries(_matching_old_methods,
-                                      _matching_new_methods,
-                                      _matching_methods_length,
-                                      &trace_name_printed);
-}
-
 // Unevolving classes may point to methods of the_class directly
 // from their constant pool caches, itables, and/or vtables. We
-// use the SystemDictionary::classes_do() facility and this helper
+// use the ClassLoaderDataGraph::classes_do() facility and this helper
 // to fix up these pointers.
-//
-// Note: We currently don't support updating the vtable in
-// arrayKlassOops. See Open Issues in jvmtiRedefineClasses.hpp.
-void VM_RedefineClasses::adjust_cpool_cache_and_vtable(Klass* k_oop,
-       ClassLoaderData* initiating_loader,
-       TRAPS) {
-  Klass *k = k_oop;
-  if (k->oop_is_instance()) {
-    HandleMark hm(THREAD);
-    InstanceKlass *ik = (InstanceKlass *) k;
+
+// Adjust cpools and vtables closure
+void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
+
+  // This is a very busy routine. We don't want too much tracing
+  // printed out.
+  bool trace_name_printed = false;
+
+  // Very noisy: only enable this call if you are trying to determine
+  // that a specific class gets found by this routine.
+  // RC_TRACE macro has an embedded ResourceMark
+  // RC_TRACE_WITH_THREAD(0x00100000, THREAD,
+  //   ("adjust check: name=%s", k->external_name()));
+  // trace_name_printed = true;
+
+  // If the class being redefined is java.lang.Object, we need to fix all
+  // array class vtables also
+  if (k->oop_is_array() && _the_class_oop == SystemDictionary::Object_klass()) {
+    k->vtable()->adjust_method_entries(_matching_old_methods,
+                                       _matching_new_methods,
+                                       _matching_methods_length,
+                                       &trace_name_printed);
+  } else if (k->oop_is_instance()) {
+    HandleMark hm(_thread);
+    InstanceKlass *ik = InstanceKlass::cast(k);
 
     // HotSpot specific optimization! HotSpot does not currently
     // support delegation from the bootstrap class loader to a
@@ -2695,23 +2702,6 @@
       return;
     }
 
-    // If the class being redefined is java.lang.Object, we need to fix all
-    // array class vtables also
-    if (_the_class_oop == SystemDictionary::Object_klass()) {
-      ik->array_klasses_do(adjust_array_vtable);
-    }
-
-    // This is a very busy routine. We don't want too much tracing
-    // printed out.
-    bool trace_name_printed = false;
-
-    // Very noisy: only enable this call if you are trying to determine
-    // that a specific class gets found by this routine.
-    // RC_TRACE macro has an embedded ResourceMark
-    // RC_TRACE_WITH_THREAD(0x00100000, THREAD,
-    //   ("adjust check: name=%s", ik->external_name()));
-    // trace_name_printed = true;
-
     // Fix the vtable embedded in the_class and subclasses of the_class,
     // if one exists. We discard scratch_class and we don't keep an
     // InstanceKlass around to hold obsolete methods so we don't have
@@ -2719,7 +2709,7 @@
     // holds the Method*s for virtual (but not final) methods.
     if (ik->vtable_length() > 0 && ik->is_subtype_of(_the_class_oop)) {
       // ik->vtable() creates a wrapper object; rm cleans it up
-      ResourceMark rm(THREAD);
+      ResourceMark rm(_thread);
       ik->vtable()->adjust_method_entries(_matching_old_methods,
                                           _matching_new_methods,
                                           _matching_methods_length,
@@ -2735,7 +2725,7 @@
     if (ik->itable_length() > 0 && (_the_class_oop->is_interface()
         || ik->is_subclass_of(_the_class_oop))) {
       // ik->itable() creates a wrapper object; rm cleans it up
-      ResourceMark rm(THREAD);
+      ResourceMark rm(_thread);
       ik->itable()->adjust_method_entries(_matching_old_methods,
                                           _matching_new_methods,
                                           _matching_methods_length,
@@ -2758,7 +2748,7 @@
     constantPoolHandle other_cp;
     ConstantPoolCache* cp_cache;
 
-    if (k_oop != _the_class_oop) {
+    if (ik != _the_class_oop) {
       // this klass' constant pool cache may need adjustment
       other_cp = constantPoolHandle(ik->constants());
       cp_cache = other_cp->cache();
@@ -2770,7 +2760,7 @@
       }
     }
     {
-      ResourceMark rm(THREAD);
+      ResourceMark rm(_thread);
       // PreviousVersionInfo objects returned via PreviousVersionWalker
       // contain a GrowableArray of handles. We have to clean up the
       // GrowableArray _after_ the PreviousVersionWalker destructor
@@ -3208,7 +3198,7 @@
 //      parts of the_class
 //    - adjusting constant pool caches and vtables in other classes
 //      that refer to methods in the_class. These adjustments use the
-//      SystemDictionary::classes_do() facility which only allows
+//      ClassLoaderDataGraph::classes_do() facility which only allows
 //      a helper method to be specified. The interesting parameters
 //      that we would like to pass to the helper method are saved in
 //      static global fields in the VM operation.
@@ -3366,6 +3356,10 @@
   }
 #endif
 
+  // NULL out in scratch class to not delete twice.  The class to be redefined
+  // always owns these bytes.
+  scratch_class->set_cached_class_file(NULL, 0);
+
   // Replace inner_classes
   Array<u2>* old_inner_classes = the_class->inner_classes();
   the_class->set_inner_classes(scratch_class->inner_classes());
@@ -3438,7 +3432,8 @@
 
   // Adjust constantpool caches and vtables for all classes
   // that reference methods of the evolved class.
-  SystemDictionary::classes_do(adjust_cpool_cache_and_vtable, THREAD);
+  AdjustCpoolCacheAndVtable adjust_cpool_cache_and_vtable(THREAD);
+  ClassLoaderDataGraph::classes_do(&adjust_cpool_cache_and_vtable);
 
   // JSR-292 support
   MemberNameTable* mnt = the_class->member_names();
@@ -3499,34 +3494,33 @@
   }
 }
 
-void VM_RedefineClasses::check_class(Klass* k_oop,
-                                     ClassLoaderData* initiating_loader,
-                                     TRAPS) {
-  Klass *k = k_oop;
-  if (k->oop_is_instance()) {
-    HandleMark hm(THREAD);
-    InstanceKlass *ik = (InstanceKlass *) k;
-    bool no_old_methods = true;  // be optimistic
-    ResourceMark rm(THREAD);
+void VM_RedefineClasses::CheckClass::do_klass(Klass* k) {
+  bool no_old_methods = true;  // be optimistic
 
-    // a vtable should never contain old or obsolete methods
-    if (ik->vtable_length() > 0 &&
-        !ik->vtable()->check_no_old_or_obsolete_entries()) {
-      if (RC_TRACE_ENABLED(0x00004000)) {
-        RC_TRACE_WITH_THREAD(0x00004000, THREAD,
-          ("klassVtable::check_no_old_or_obsolete_entries failure"
-           " -- OLD or OBSOLETE method found -- class: %s",
-           ik->signature_name()));
-        ik->vtable()->dump_vtable();
-      }
-      no_old_methods = false;
+  // Both array and instance classes have vtables.
+  // a vtable should never contain old or obsolete methods
+  ResourceMark rm(_thread);
+  if (k->vtable_length() > 0 &&
+      !k->vtable()->check_no_old_or_obsolete_entries()) {
+    if (RC_TRACE_ENABLED(0x00004000)) {
+      RC_TRACE_WITH_THREAD(0x00004000, _thread,
+        ("klassVtable::check_no_old_or_obsolete_entries failure"
+         " -- OLD or OBSOLETE method found -- class: %s",
+         k->signature_name()));
+      k->vtable()->dump_vtable();
     }
+    no_old_methods = false;
+  }
+
+  if (k->oop_is_instance()) {
+    HandleMark hm(_thread);
+    InstanceKlass *ik = InstanceKlass::cast(k);
 
     // an itable should never contain old or obsolete methods
     if (ik->itable_length() > 0 &&
         !ik->itable()->check_no_old_or_obsolete_entries()) {
       if (RC_TRACE_ENABLED(0x00004000)) {
-        RC_TRACE_WITH_THREAD(0x00004000, THREAD,
+        RC_TRACE_WITH_THREAD(0x00004000, _thread,
           ("klassItable::check_no_old_or_obsolete_entries failure"
            " -- OLD or OBSOLETE method found -- class: %s",
            ik->signature_name()));
@@ -3540,7 +3534,7 @@
         ik->constants()->cache() != NULL &&
         !ik->constants()->cache()->check_no_old_or_obsolete_entries()) {
       if (RC_TRACE_ENABLED(0x00004000)) {
-        RC_TRACE_WITH_THREAD(0x00004000, THREAD,
+        RC_TRACE_WITH_THREAD(0x00004000, _thread,
           ("cp-cache::check_no_old_or_obsolete_entries failure"
            " -- OLD or OBSOLETE method found -- class: %s",
            ik->signature_name()));
@@ -3548,19 +3542,21 @@
       }
       no_old_methods = false;
     }
+  }
 
-    if (!no_old_methods) {
-      if (RC_TRACE_ENABLED(0x00004000)) {
-        dump_methods();
-      } else {
-        tty->print_cr("INFO: use the '-XX:TraceRedefineClasses=16384' option "
-          "to see more info about the following guarantee() failure.");
-      }
-      guarantee(false, "OLD and/or OBSOLETE method(s) found");
+  // print and fail guarantee if old methods are found.
+  if (!no_old_methods) {
+    if (RC_TRACE_ENABLED(0x00004000)) {
+      dump_methods();
+    } else {
+      tty->print_cr("INFO: use the '-XX:TraceRedefineClasses=16384' option "
+        "to see more info about the following guarantee() failure.");
     }
+    guarantee(false, "OLD and/or OBSOLETE method(s) found");
   }
 }
 
+
 void VM_RedefineClasses::dump_methods() {
   int j;
   RC_TRACE(0x00004000, ("_old_methods --"));
diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp
index ffe9a7e..3457e93 100644
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp
@@ -87,7 +87,7 @@
 //      parts of the_class
 //    - adjusting constant pool caches and vtables in other classes
 //      that refer to methods in the_class. These adjustments use the
-//      SystemDictionary::classes_do() facility which only allows
+//      ClassLoaderDataGraph::classes_do() facility which only allows
 //      a helper method to be specified. The interesting parameters
 //      that we would like to pass to the helper method are saved in
 //      static global fields in the VM operation.
@@ -333,8 +333,8 @@
 
 class VM_RedefineClasses: public VM_Operation {
  private:
-  // These static fields are needed by SystemDictionary::classes_do()
-  // facility and the adjust_cpool_cache_and_vtable() helper:
+  // These static fields are needed by ClassLoaderDataGraph::classes_do()
+  // facility and the AdjustCpoolCacheAndVtable helper:
   static Array<Method*>* _old_methods;
   static Array<Method*>* _new_methods;
   static Method**      _matching_old_methods;
@@ -408,13 +408,6 @@
          int * emcp_method_count_p);
   void transfer_old_native_function_registrations(instanceKlassHandle the_class);
 
-  // Unevolving classes may point to methods of the_class directly
-  // from their constant pool caches, itables, and/or vtables. We
-  // use the SystemDictionary::classes_do() facility and this helper
-  // to fix up these pointers.
-  static void adjust_cpool_cache_and_vtable(Klass* k_oop, ClassLoaderData* initiating_loader, TRAPS);
-  static void adjust_array_vtable(Klass* k_oop);
-
   // Install the redefinition of a class
   void redefine_single_class(jclass the_jclass,
     Klass* scratch_class_oop, TRAPS);
@@ -480,10 +473,27 @@
 
   void flush_dependent_code(instanceKlassHandle k_h, TRAPS);
 
-  static void check_class(Klass* k_oop, ClassLoaderData* initiating_loader,
-                TRAPS);
   static void dump_methods();
 
+  // Check that there are no old or obsolete methods
+  class CheckClass : public KlassClosure {
+    Thread* _thread;
+   public:
+    CheckClass(Thread* t) : _thread(t) {}
+    void do_klass(Klass* k);
+  };
+
+  // Unevolving classes may point to methods of the_class directly
+  // from their constant pool caches, itables, and/or vtables. We
+  // use the ClassLoaderDataGraph::classes_do() facility and this helper
+  // to fix up these pointers.
+  class AdjustCpoolCacheAndVtable : public KlassClosure {
+    Thread* _thread;
+   public:
+    AdjustCpoolCacheAndVtable(Thread* t) : _thread(t) {}
+    void do_klass(Klass* k);
+  };
+
  public:
   VM_RedefineClasses(jint class_count,
                      const jvmtiClassDefinition *class_defs,
diff --git a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp
index 99e4af5..eb68b42 100644
--- a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -2857,7 +2857,7 @@
 
     // references from the constant pool
     {
-      ConstantPool* const pool = ik->constants();
+      ConstantPool* pool = ik->constants();
       for (int i = 1; i < pool->length(); i++) {
         constantTag tag = pool->tag_at(i).value();
         if (tag.is_string() || tag.is_klass()) {
diff --git a/hotspot/src/share/vm/prims/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp
index 3410498..58957ee 100644
--- a/hotspot/src/share/vm/prims/methodHandles.cpp
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp
@@ -193,19 +193,15 @@
     flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
   } else if (mods.is_static()) {
     flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT);
-     // Get vindex from itable if method holder is an interface.
-     if (m->method_holder()->is_interface()) {
-       vmindex = klassItable::compute_itable_index(m);
-     }
   } else if (receiver_limit != mklass &&
              !receiver_limit->is_subtype_of(mklass)) {
     return NULL;  // bad receiver limit
-  } else if (receiver_limit->is_interface() &&
+  } else if (do_dispatch && receiver_limit->is_interface() &&
              mklass->is_interface()) {
     flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT);
     receiver_limit = mklass;  // ignore passed-in limit; interfaces are interconvertible
     vmindex = klassItable::compute_itable_index(m);
-  } else if (mklass != receiver_limit && mklass->is_interface()) {
+  } else if (do_dispatch && mklass != receiver_limit && mklass->is_interface()) {
     flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
     // it is a miranda method, so m->vtable_index is not what we want
     ResourceMark rm;
@@ -250,10 +246,25 @@
   }
   methodHandle m = info.resolved_method();
   KlassHandle defc = info.resolved_klass();
-  int vmindex = -1;
+  int vmindex = Method::invalid_vtable_index;
   if (defc->is_interface() && m->method_holder()->is_interface()) {
-    // LinkResolver does not report itable indexes!  (fix this?)
-    vmindex = klassItable::compute_itable_index(m());
+    // static interface methods do not reference vtable or itable
+    if (m->is_static()) {
+      vmindex = Method::nonvirtual_vtable_index;
+    }
+    // interface methods invoked via invokespecial also
+    // do not reference vtable or itable.
+    int ref_kind = ((java_lang_invoke_MemberName::flags(mname()) >>
+                     REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK);
+    if (ref_kind == JVM_REF_invokeSpecial) {
+      vmindex = Method::nonvirtual_vtable_index;
+    }
+    // If neither m is static nor ref_kind is invokespecial,
+    // set it to itable index.
+    if (vmindex == Method::invalid_vtable_index) {
+      // LinkResolver does not report itable indexes!  (fix this?)
+      vmindex = klassItable::compute_itable_index(m());
+    }
   } else if (m->can_be_statically_bound()) {
     // LinkResolver reports vtable index even for final methods!
     vmindex = Method::nonvirtual_vtable_index;
@@ -665,11 +676,9 @@
   case IS_METHOD:
     {
       CallInfo result;
-      bool do_dispatch = true;  // default, neutral setting
       {
         assert(!HAS_PENDING_EXCEPTION, "");
         if (ref_kind == JVM_REF_invokeStatic) {
-          //do_dispatch = false;  // no need, since statics are never dispatched
           LinkResolver::resolve_static_call(result,
                         defc, name, type, KlassHandle(), false, false, THREAD);
         } else if (ref_kind == JVM_REF_invokeInterface) {
@@ -680,7 +689,6 @@
           LinkResolver::resolve_handle_call(result,
                         defc, name, type, KlassHandle(), THREAD);
         } else if (ref_kind == JVM_REF_invokeSpecial) {
-          do_dispatch = false;  // force non-virtual linkage
           LinkResolver::resolve_special_call(result,
                         defc, name, type, KlassHandle(), false, THREAD);
         } else if (ref_kind == JVM_REF_invokeVirtual) {
@@ -1298,6 +1306,28 @@
 }
 JVM_END
 
+/**
+ * Throws a java/lang/UnsupportedOperationException unconditionally.
+ * This is required by the specification of MethodHandle.invoke if
+ * invoked directly.
+ */
+JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
+  THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invoke cannot be invoked reflectively");
+  return NULL;
+}
+JVM_END
+
+/**
+ * Throws a java/lang/UnsupportedOperationException unconditionally.
+ * This is required by the specification of MethodHandle.invokeExact if
+ * invoked directly.
+ */
+JVM_ENTRY(jobject, MH_invokeExact_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
+  THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invokeExact cannot be invoked reflectively");
+  return NULL;
+}
+JVM_END
+
 /// JVM_RegisterMethodHandleMethods
 
 #undef CS  // Solaris builds complain
@@ -1317,7 +1347,7 @@
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
 
 // These are the native methods on java.lang.invoke.MethodHandleNatives.
-static JNINativeMethod required_methods_JDK8[] = {
+static JNINativeMethod MHN_methods[] = {
   {CC"init",                      CC"("MEM""OBJ")V",                     FN_PTR(MHN_init_Mem)},
   {CC"expand",                    CC"("MEM")V",                          FN_PTR(MHN_expand_Mem)},
   {CC"resolve",                   CC"("MEM""CLS")"MEM,                   FN_PTR(MHN_resolve_Mem)},
@@ -1335,8 +1365,28 @@
   {CC"getMemberVMInfo",           CC"("MEM")"OBJ,                        FN_PTR(MHN_getMemberVMInfo)}
 };
 
-// This one function is exported, used by NativeLookup.
+static JNINativeMethod MH_methods[] = {
+  // UnsupportedOperationException throwers
+  {CC"invoke",                    CC"(["OBJ")"OBJ,                       FN_PTR(MH_invoke_UOE)},
+  {CC"invokeExact",               CC"(["OBJ")"OBJ,                       FN_PTR(MH_invokeExact_UOE)}
+};
 
+/**
+ * Helper method to register native methods.
+ */
+static bool register_natives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods) {
+  int status = env->RegisterNatives(clazz, methods, nMethods);
+  if (status != JNI_OK || env->ExceptionOccurred()) {
+    warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
+    env->ExceptionClear();
+    return false;
+  }
+  return true;
+}
+
+/**
+ * This one function is exported, used by NativeLookup.
+ */
 JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
   if (!EnableInvokeDynamic) {
     warning("JSR 292 is disabled in this JVM.  Use -XX:+UnlockDiagnosticVMOptions -XX:+EnableInvokeDynamic to enable.");
@@ -1354,16 +1404,14 @@
     MH_class = (jclass) JNIHandles::make_local(env, mirror);
   }
 
-  int status;
-
   if (enable_MH) {
     ThreadToNativeFromVM ttnfv(thread);
 
-    status = env->RegisterNatives(MHN_class, required_methods_JDK8, sizeof(required_methods_JDK8)/sizeof(JNINativeMethod));
-    if (status != JNI_OK || env->ExceptionOccurred()) {
-      warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
-      enable_MH = false;
-      env->ExceptionClear();
+    if (enable_MH) {
+      enable_MH = register_natives(env, MHN_class, MHN_methods, sizeof(MHN_methods)/sizeof(JNINativeMethod));
+    }
+    if (enable_MH) {
+      enable_MH = register_natives(env, MH_class, MH_methods, sizeof(MH_methods)/sizeof(JNINativeMethod));
     }
   }
 
diff --git a/hotspot/src/share/vm/prims/nativeLookup.cpp b/hotspot/src/share/vm/prims/nativeLookup.cpp
index 6162ae8..990600e 100644
--- a/hotspot/src/share/vm/prims/nativeLookup.cpp
+++ b/hotspot/src/share/vm/prims/nativeLookup.cpp
@@ -383,10 +383,7 @@
 
 address NativeLookup::lookup(methodHandle method, bool& in_base_library, TRAPS) {
   if (!method->has_native_function()) {
-    address entry =
-        method->intrinsic_id() == vmIntrinsics::_invokeGeneric ?
-            SharedRuntime::native_method_throw_unsupported_operation_exception_entry() :
-            lookup_base(method, in_base_library, CHECK_NULL);
+    address entry = lookup_base(method, in_base_library, CHECK_NULL);
     method->set_native_function(entry,
       Method::native_bind_event_is_interesting);
     // -verbose:jni printing
diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
index bf149fc..b1cfb3c 100644
--- a/hotspot/src/share/vm/runtime/arguments.cpp
+++ b/hotspot/src/share/vm/runtime/arguments.cpp
@@ -1089,6 +1089,10 @@
   if (FLAG_IS_DEFAULT(ReservedCodeCacheSize)) {
     FLAG_SET_DEFAULT(ReservedCodeCacheSize, ReservedCodeCacheSize * 5);
   }
+  if (!UseInterpreter) { // -Xcomp
+    Tier3InvokeNotifyFreqLog = 0;
+    Tier4InvocationThreshold = 0;
+  }
 }
 
 #if INCLUDE_ALL_GCS
@@ -1669,6 +1673,20 @@
 // Aggressive optimization flags  -XX:+AggressiveOpts
 void Arguments::set_aggressive_opts_flags() {
 #ifdef COMPILER2
+  if (AggressiveUnboxing) {
+    if (FLAG_IS_DEFAULT(EliminateAutoBox)) {
+      FLAG_SET_DEFAULT(EliminateAutoBox, true);
+    } else if (!EliminateAutoBox) {
+      // warning("AggressiveUnboxing is disabled because EliminateAutoBox is disabled");
+      AggressiveUnboxing = false;
+    }
+    if (FLAG_IS_DEFAULT(DoEscapeAnalysis)) {
+      FLAG_SET_DEFAULT(DoEscapeAnalysis, true);
+    } else if (!DoEscapeAnalysis) {
+      // warning("AggressiveUnboxing is disabled because DoEscapeAnalysis is disabled");
+      AggressiveUnboxing = false;
+    }
+  }
   if (AggressiveOpts || !FLAG_IS_DEFAULT(AutoBoxCacheMax)) {
     if (FLAG_IS_DEFAULT(EliminateAutoBox)) {
       FLAG_SET_DEFAULT(EliminateAutoBox, true);
@@ -1901,7 +1919,7 @@
     status = false;
   }
 
-  status = status && verify_percentage(AdaptiveSizePolicyWeight,
+  status = status && verify_interval(AdaptiveSizePolicyWeight, 0, 100,
                               "AdaptiveSizePolicyWeight");
   status = status && verify_percentage(ThresholdTolerance, "ThresholdTolerance");
   status = status && verify_percentage(MinHeapFreeRatio, "MinHeapFreeRatio");
@@ -1961,8 +1979,6 @@
     FLAG_SET_DEFAULT(UseGCOverheadLimit, false);
   }
 
-  status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit");
-
   status = status && check_gc_consistency();
   status = status && check_stack_pages();
 
@@ -2056,6 +2072,52 @@
     status = status && verify_interval(G1ConcRSLogCacheSize, 0, 31,
                                        "G1ConcRSLogCacheSize");
   }
+  if (UseConcMarkSweepGC) {
+    status = status && verify_min_value(CMSOldPLABNumRefills, 1, "CMSOldPLABNumRefills");
+    status = status && verify_min_value(CMSOldPLABToleranceFactor, 1, "CMSOldPLABToleranceFactor");
+    status = status && verify_min_value(CMSOldPLABMax, 1, "CMSOldPLABMax");
+    status = status && verify_interval(CMSOldPLABMin, 1, CMSOldPLABMax, "CMSOldPLABMin");
+
+    status = status && verify_min_value(CMSYoungGenPerWorker, 1, "CMSYoungGenPerWorker");
+
+    status = status && verify_min_value(CMSSamplingGrain, 1, "CMSSamplingGrain");
+    status = status && verify_interval(CMS_SweepWeight, 0, 100, "CMS_SweepWeight");
+    status = status && verify_interval(CMS_FLSWeight, 0, 100, "CMS_FLSWeight");
+
+    status = status && verify_interval(FLSCoalescePolicy, 0, 4, "FLSCoalescePolicy");
+
+    status = status && verify_min_value(CMSRescanMultiple, 1, "CMSRescanMultiple");
+    status = status && verify_min_value(CMSConcMarkMultiple, 1, "CMSConcMarkMultiple");
+
+    status = status && verify_interval(CMSPrecleanIter, 0, 9, "CMSPrecleanIter");
+    status = status && verify_min_value(CMSPrecleanDenominator, 1, "CMSPrecleanDenominator");
+    status = status && verify_interval(CMSPrecleanNumerator, 0, CMSPrecleanDenominator - 1, "CMSPrecleanNumerator");
+
+    status = status && verify_percentage(CMSBootstrapOccupancy, "CMSBootstrapOccupancy");
+
+    status = status && verify_min_value(CMSPrecleanThreshold, 100, "CMSPrecleanThreshold");
+
+    status = status && verify_percentage(CMSScheduleRemarkEdenPenetration, "CMSScheduleRemarkEdenPenetration");
+    status = status && verify_min_value(CMSScheduleRemarkSamplingRatio, 1, "CMSScheduleRemarkSamplingRatio");
+    status = status && verify_min_value(CMSBitMapYieldQuantum, 1, "CMSBitMapYieldQuantum");
+    status = status && verify_percentage(CMSTriggerRatio, "CMSTriggerRatio");
+    status = status && verify_percentage(CMSIsTooFullPercentage, "CMSIsTooFullPercentage");
+  }
+
+  if (UseParallelGC || UseParallelOldGC) {
+    status = status && verify_interval(ParallelOldDeadWoodLimiterMean, 0, 100, "ParallelOldDeadWoodLimiterMean");
+    status = status && verify_interval(ParallelOldDeadWoodLimiterStdDev, 0, 100, "ParallelOldDeadWoodLimiterStdDev");
+
+    status = status && verify_percentage(YoungGenerationSizeIncrement, "YoungGenerationSizeIncrement");
+    status = status && verify_percentage(TenuredGenerationSizeIncrement, "TenuredGenerationSizeIncrement");
+
+    status = status && verify_min_value(YoungGenerationSizeSupplementDecay, 1, "YoungGenerationSizeSupplementDecay");
+    status = status && verify_min_value(TenuredGenerationSizeSupplementDecay, 1, "TenuredGenerationSizeSupplementDecay");
+
+    status = status && verify_min_value(ParGCCardsPerStrideChunk, 1, "ParGCCardsPerStrideChunk");
+
+    status = status && verify_min_value(ParallelOldGCSplitInterval, 0, "ParallelOldGCSplitInterval");
+  }
 #endif // INCLUDE_ALL_GCS
 
   status = status && verify_interval(RefDiscoveryPolicy,
@@ -2075,7 +2137,42 @@
 
   status = status && verify_interval(MarkStackSizeMax,
                                   1, (max_jint - 1), "MarkStackSizeMax");
+  status = status && verify_interval(NUMAChunkResizeWeight, 0, 100, "NUMAChunkResizeWeight");
 
+  status = status && verify_min_value(LogEventsBufferEntries, 1, "LogEventsBufferEntries");
+
+  status = status && verify_min_value(HeapSizePerGCThread, (uintx) os::vm_page_size(), "HeapSizePerGCThread");
+
+  status = status && verify_min_value(GCTaskTimeStampEntries, 1, "GCTaskTimeStampEntries");
+
+  status = status && verify_percentage(ParallelGCBufferWastePct, "ParallelGCBufferWastePct");
+  status = status && verify_interval(TargetPLABWastePct, 1, 100, "TargetPLABWastePct");
+
+  status = status && verify_min_value(ParGCStridesPerThread, 1, "ParGCStridesPerThread");
+
+  status = status && verify_min_value(MinRAMFraction, 1, "MinRAMFraction");
+  status = status && verify_min_value(InitialRAMFraction, 1, "InitialRAMFraction");
+  status = status && verify_min_value(MaxRAMFraction, 1, "MaxRAMFraction");
+  status = status && verify_min_value(DefaultMaxRAMFraction, 1, "DefaultMaxRAMFraction");
+
+  status = status && verify_interval(AdaptiveTimeWeight, 0, 100, "AdaptiveTimeWeight");
+  status = status && verify_min_value(AdaptiveSizeDecrementScaleFactor, 1, "AdaptiveSizeDecrementScaleFactor");
+
+  status = status && verify_interval(TLABAllocationWeight, 0, 100, "TLABAllocationWeight");
+  status = status && verify_min_value(MinTLABSize, 1, "MinTLABSize");
+  status = status && verify_min_value(TLABRefillWasteFraction, 1, "TLABRefillWasteFraction");
+
+  status = status && verify_percentage(YoungGenerationSizeSupplement, "YoungGenerationSizeSupplement");
+  status = status && verify_percentage(TenuredGenerationSizeSupplement, "TenuredGenerationSizeSupplement");
+
+  // the "age" field in the oop header is 4 bits; do not want to pull in markOop.hpp
+  // just for that, so hardcode here.
+  status = status && verify_interval(MaxTenuringThreshold, 0, 15, "MaxTenuringThreshold");
+  status = status && verify_interval(InitialTenuringThreshold, 0, MaxTenuringThreshold, "MaxTenuringThreshold");
+  status = status && verify_percentage(TargetSurvivorRatio, "TargetSurvivorRatio");
+  status = status && verify_percentage(MarkSweepDeadRatio, "MarkSweepDeadRatio");
+
+  status = status && verify_min_value(MarkSweepAlwaysCompactCount, 1, "MarkSweepAlwaysCompactCount");
 #ifdef SPARC
   if (UseConcMarkSweepGC || UseG1GC) {
     // Issue a stern warning if the user has explicitly set
@@ -2100,6 +2197,26 @@
 #endif
   }
 
+  // Need to limit the extent of the padding to reasonable size.
+  // 8K is well beyond the reasonable HW cache line size, even with the
+  // aggressive prefetching, while still leaving the room for segregating
+  // among the distinct pages.
+  if (ContendedPaddingWidth < 0 || ContendedPaddingWidth > 8192) {
+    jio_fprintf(defaultStream::error_stream(),
+                "ContendedPaddingWidth=" INTX_FORMAT " must be the between %d and %d\n",
+                ContendedPaddingWidth, 0, 8192);
+    status = false;
+  }
+
+  // Need to enforce the padding not to break the existing field alignments.
+  // It is sufficient to check against the largest type size.
+  if ((ContendedPaddingWidth % BytesPerLong) != 0) {
+    jio_fprintf(defaultStream::error_stream(),
+                "ContendedPaddingWidth=" INTX_FORMAT " must be the multiple of %d\n",
+                ContendedPaddingWidth, BytesPerLong);
+    status = false;
+  }
+
   return status;
 }
 
@@ -2965,6 +3082,11 @@
     set_mode_flags(_int);
   }
 
+  // eventually fix up InitialTenuringThreshold if only MaxTenuringThreshold is set
+  if (FLAG_IS_DEFAULT(InitialTenuringThreshold) && (InitialTenuringThreshold > MaxTenuringThreshold)) {
+    FLAG_SET_ERGO(uintx, InitialTenuringThreshold, MaxTenuringThreshold);
+  }
+
 #ifndef COMPILER2
   // Don't degrade server performance for footprint
   if (FLAG_IS_DEFAULT(UseLargePages) &&
@@ -3097,36 +3219,27 @@
 }
 
 void Arguments::set_shared_spaces_flags() {
-  const bool must_share = DumpSharedSpaces || RequireSharedSpaces;
-  const bool might_share = must_share || UseSharedSpaces;
+#ifdef _LP64
+    const bool must_share = DumpSharedSpaces || RequireSharedSpaces;
 
-  // CompressedOops cannot be used with CDS.  The offsets of oopmaps and
-  // static fields are incorrect in the archive.  With some more clever
-  // initialization, this restriction can probably be lifted.
-  // ??? UseLargePages might be okay now
-  const bool cannot_share = UseCompressedOops ||
-                            (UseLargePages && FLAG_IS_CMDLINE(UseLargePages));
-  if (cannot_share) {
-    if (must_share) {
-        warning("disabling large pages %s"
-                "because of %s", "" LP64_ONLY("and compressed oops "),
-                DumpSharedSpaces ? "-Xshare:dump" : "-Xshare:on");
-        FLAG_SET_CMDLINE(bool, UseLargePages, false);
-        LP64_ONLY(FLAG_SET_CMDLINE(bool, UseCompressedOops, false));
-        LP64_ONLY(FLAG_SET_CMDLINE(bool, UseCompressedKlassPointers, false));
-    } else {
-      // Prefer compressed oops and large pages to class data sharing
-      if (UseSharedSpaces && Verbose) {
-        warning("turning off use of shared archive because of large pages%s",
-                 "" LP64_ONLY(" and/or compressed oops"));
+    // CompressedOops cannot be used with CDS.  The offsets of oopmaps and
+    // static fields are incorrect in the archive.  With some more clever
+    // initialization, this restriction can probably be lifted.
+    if (UseCompressedOops) {
+      if (must_share) {
+          warning("disabling compressed oops because of %s",
+                  DumpSharedSpaces ? "-Xshare:dump" : "-Xshare:on");
+          FLAG_SET_CMDLINE(bool, UseCompressedOops, false);
+          FLAG_SET_CMDLINE(bool, UseCompressedKlassPointers, false);
+      } else {
+        // Prefer compressed oops to class data sharing
+        if (UseSharedSpaces && Verbose) {
+          warning("turning off use of shared archive because of compressed oops");
+        }
+        no_shared_spaces();
       }
-      no_shared_spaces();
     }
-  } else if (UseLargePages && might_share) {
-    // Disable large pages to allow shared spaces.  This is sub-optimal, since
-    // there may not even be a shared archive to use.
-    FLAG_SET_DEFAULT(UseLargePages, false);
-  }
+#endif
 
   if (DumpSharedSpaces) {
     if (RequireSharedSpaces) {
@@ -3171,25 +3284,37 @@
 }
 #endif // INCLUDE_ALL_GCS
 
+// Sharing support
+// Construct the path to the archive
+static char* get_shared_archive_path() {
+  char *shared_archive_path;
+  if (SharedArchiveFile == NULL) {
+    char jvm_path[JVM_MAXPATHLEN];
+    os::jvm_path(jvm_path, sizeof(jvm_path));
+    char *end = strrchr(jvm_path, *os::file_separator());
+    if (end != NULL) *end = '\0';
+    size_t jvm_path_len = strlen(jvm_path);
+    size_t file_sep_len = strlen(os::file_separator());
+    shared_archive_path = NEW_C_HEAP_ARRAY(char, jvm_path_len +
+        file_sep_len + 20, mtInternal);
+    if (shared_archive_path != NULL) {
+      strncpy(shared_archive_path, jvm_path, jvm_path_len + 1);
+      strncat(shared_archive_path, os::file_separator(), file_sep_len);
+      strncat(shared_archive_path, "classes.jsa", 11);
+    }
+  } else {
+    shared_archive_path = NEW_C_HEAP_ARRAY(char, strlen(SharedArchiveFile) + 1, mtInternal);
+    if (shared_archive_path != NULL) {
+      strncpy(shared_archive_path, SharedArchiveFile, strlen(SharedArchiveFile) + 1);
+    }
+  }
+  return shared_archive_path;
+}
+
 // Parse entry point called from JNI_CreateJavaVM
 
 jint Arguments::parse(const JavaVMInitArgs* args) {
 
-  // Sharing support
-  // Construct the path to the archive
-  char jvm_path[JVM_MAXPATHLEN];
-  os::jvm_path(jvm_path, sizeof(jvm_path));
-  char *end = strrchr(jvm_path, *os::file_separator());
-  if (end != NULL) *end = '\0';
-  char *shared_archive_path = NEW_C_HEAP_ARRAY(char, strlen(jvm_path) +
-      strlen(os::file_separator()) + 20, mtInternal);
-  if (shared_archive_path == NULL) return JNI_ENOMEM;
-  strcpy(shared_archive_path, jvm_path);
-  strcat(shared_archive_path, os::file_separator());
-  strcat(shared_archive_path, "classes");
-  strcat(shared_archive_path, ".jsa");
-  SharedArchivePath = shared_archive_path;
-
   // Remaining part of option string
   const char* tail;
 
@@ -3280,6 +3405,12 @@
     return result;
   }
 
+  // Call get_shared_archive_path() here, after possible SharedArchiveFile option got parsed.
+  SharedArchivePath = get_shared_archive_path();
+  if (SharedArchivePath == NULL) {
+    return JNI_ENOMEM;
+  }
+
   // Delay warning until here so that we've had a chance to process
   // the -XX:-PrintWarnings flag
   if (needs_hotspotrc_warning) {
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index 54c91f6..1131c8e 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -286,12 +286,12 @@
 };
 
 
-class IntFlagSetting {
-  intx val;
-  intx* flag;
+class UIntFlagSetting {
+  uintx val;
+  uintx* flag;
  public:
-  IntFlagSetting(intx& fl, intx newValue) { flag = &fl; val = fl; fl = newValue; }
-  ~IntFlagSetting()                       { *flag = val; }
+  UIntFlagSetting(uintx& fl, uintx newValue) { flag = &fl; val = fl; fl = newValue; }
+  ~UIntFlagSetting()                         { *flag = val; }
 };
 
 
@@ -513,12 +513,12 @@
   product(bool, ForceNUMA, false,                                           \
           "Force NUMA optimizations on single-node/UMA systems")            \
                                                                             \
-  product(intx, NUMAChunkResizeWeight, 20,                                  \
-          "Percentage (0-100) used to weight the current sample when "      \
+  product(uintx, NUMAChunkResizeWeight, 20,                                 \
+          "Percentage (0-100) used to weigh the current sample when "      \
           "computing exponentially decaying average for "                   \
           "AdaptiveNUMAChunkSizing")                                        \
                                                                             \
-  product(intx, NUMASpaceResizeRate, 1*G,                                   \
+  product(uintx, NUMASpaceResizeRate, 1*G,                                  \
           "Do not reallocate more that this amount per collection")         \
                                                                             \
   product(bool, UseAdaptiveNUMAChunkSizing, true,                           \
@@ -527,7 +527,7 @@
   product(bool, NUMAStats, false,                                           \
           "Print NUMA stats in detailed heap information")                  \
                                                                             \
-  product(intx, NUMAPageScanRate, 256,                                      \
+  product(uintx, NUMAPageScanRate, 256,                                     \
           "Maximum number of pages to include in the page scan procedure")  \
                                                                             \
   product_pd(bool, NeedsDeoptSuspend,                                       \
@@ -715,7 +715,7 @@
   diagnostic(bool, LogEvents, true,                                         \
              "Enable the various ring buffer event logs")                   \
                                                                             \
-  diagnostic(intx, LogEventsBufferEntries, 10,                              \
+  diagnostic(uintx, LogEventsBufferEntries, 10,                             \
              "Enable the various ring buffer event logs")                   \
                                                                             \
   product(bool, BytecodeVerificationRemote, true,                           \
@@ -1159,9 +1159,6 @@
   product(bool, CompactFields, true,                                        \
           "Allocate nonstatic fields in gaps between previous fields")      \
                                                                             \
-  notproduct(bool, PrintCompactFieldsSavings, false,                        \
-          "Print how many words were saved with CompactFields")             \
-                                                                            \
   notproduct(bool, PrintFieldLayout, false,                                 \
           "Print field layout for each class")                              \
                                                                             \
@@ -1432,16 +1429,17 @@
   product(bool, ParallelGCVerbose, false,                                   \
           "Verbose output for parallel GC.")                                \
                                                                             \
-  product(intx, ParallelGCBufferWastePct, 10,                               \
-          "wasted fraction of parallel allocation buffer.")                 \
+  product(uintx, ParallelGCBufferWastePct, 10,                              \
+          "Wasted fraction of parallel allocation buffer.")                 \
                                                                             \
   diagnostic(bool, ParallelGCRetainPLAB, false,                             \
              "Retain parallel allocation buffers across scavenges; "        \
              " -- disabled because this currently conflicts with "          \
              " parallel card scanning under certain conditions ")           \
                                                                             \
-  product(intx, TargetPLABWastePct, 10,                                     \
-          "target wasted space in last buffer as pct of overall allocation")\
+  product(uintx, TargetPLABWastePct, 10,                                    \
+          "Target wasted space in last buffer as percent of overall "       \
+          "allocation")                                                     \
                                                                             \
   product(uintx, PLABWeight, 75,                                            \
           "Percentage (0-100) used to weight the current sample when"       \
@@ -1519,7 +1517,7 @@
   product(bool, AlwaysPreTouch, false,                                      \
           "It forces all freshly committed pages to be pre-touched.")       \
                                                                             \
-  product_pd(intx, CMSYoungGenPerWorker,                                    \
+  product_pd(uintx, CMSYoungGenPerWorker,                                   \
           "The maximum size of young gen chosen by default per GC worker "  \
           "thread available")                                               \
                                                                             \
@@ -1837,7 +1835,7 @@
   product(bool, UseCMSInitiatingOccupancyOnly, false,                       \
           "Only use occupancy as a crierion for starting a CMS collection") \
                                                                             \
-  product(intx, CMSIsTooFullPercentage, 98,                                 \
+  product(uintx, CMSIsTooFullPercentage, 98,                                \
           "An absolute ceiling above which CMS will always consider the "   \
           "unloading of classes when class unloading is enabled")           \
                                                                             \
@@ -1876,7 +1874,7 @@
   develop(uintx, PromotionFailureALotInterval, 5,                           \
           "Total collections between promotion failures alot")              \
                                                                             \
-  experimental(intx, WorkStealingSleepMillis, 1,                            \
+  experimental(uintx, WorkStealingSleepMillis, 1,                           \
           "Sleep time when sleep is used for yields")                       \
                                                                             \
   experimental(uintx, WorkStealingYieldsBeforeSleep, 5000,                  \
@@ -2020,7 +2018,7 @@
           "Number of collections before the adaptive sizing is started")    \
                                                                             \
   product(uintx, AdaptiveSizePolicyOutputInterval, 0,                       \
-          "Collecton interval for printing information; zero => never")     \
+          "Collection interval for printing information; zero means never") \
                                                                             \
   product(bool, UseAdaptiveSizePolicyFootprintGoal, true,                   \
           "Use adaptive minimum footprint as a goal")                       \
@@ -3049,7 +3047,7 @@
   product(uintx, MaxMetaspaceExpansion, ScaleForWordSize(4*M),              \
           "Max expansion of Metaspace without full GC (in bytes)")          \
                                                                             \
-  product(intx, QueuedAllocationWarningCount, 0,                            \
+  product(uintx, QueuedAllocationWarningCount, 0,                           \
           "Number of times an allocation that queues behind a GC "          \
           "will retry before printing a warning")                           \
                                                                             \
@@ -3077,7 +3075,7 @@
           "either completely full or completely empty.  Par compact also"   \
           "has a smaller default value; see arguments.cpp.")                \
                                                                             \
-  product(intx, MarkSweepAlwaysCompactCount,     4,                         \
+  product(uintx, MarkSweepAlwaysCompactCount,     4,                        \
           "How often should we fully compact the heap (ignoring the dead "  \
           "space parameters)")                                              \
                                                                             \
@@ -3680,6 +3678,9 @@
   product(bool , AllowNonVirtualCalls, false,                               \
           "Obey the ACC_SUPER flag and allow invokenonvirtual calls")       \
                                                                             \
+  diagnostic(ccstr, SharedArchiveFile, NULL,                                \
+          "Override the default location of the CDS archive file")          \
+                                                                            \
   experimental(uintx, ArrayAllocatorMallocLimit,                            \
           SOLARIS_ONLY(64*K) NOT_SOLARIS(max_uintx),                        \
           "Allocation less than this value will be allocated "              \
diff --git a/hotspot/src/share/vm/runtime/handles.cpp b/hotspot/src/share/vm/runtime/handles.cpp
index a62ff17..ebbdd9d 100644
--- a/hotspot/src/share/vm/runtime/handles.cpp
+++ b/hotspot/src/share/vm/runtime/handles.cpp
@@ -179,6 +179,22 @@
   _thread->set_last_handle_mark(previous_handle_mark());
 }
 
+void* HandleMark::operator new(size_t size) {
+  return AllocateHeap(size, mtThread);
+}
+
+void* HandleMark::operator new [] (size_t size) {
+  return AllocateHeap(size, mtThread);
+}
+
+void HandleMark::operator delete(void* p) {
+  FreeHeap(p, mtThread);
+}
+
+void HandleMark::operator delete[](void* p) {
+  FreeHeap(p, mtThread);
+}
+
 #ifdef ASSERT
 
 NoHandleMark::NoHandleMark() {
diff --git a/hotspot/src/share/vm/runtime/handles.hpp b/hotspot/src/share/vm/runtime/handles.hpp
index 8c643d7..82506bd 100644
--- a/hotspot/src/share/vm/runtime/handles.hpp
+++ b/hotspot/src/share/vm/runtime/handles.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -281,7 +281,7 @@
 // across the HandleMark boundary.
 
 // The base class of HandleMark should have been StackObj but we also heap allocate
-// a HandleMark when a thread is created.
+// a HandleMark when a thread is created. The operator new is for this special case.
 
 class HandleMark {
  private:
@@ -308,6 +308,11 @@
   void push();
   // called in the destructor of HandleMarkCleaner
   void pop_and_restore();
+  // overloaded operators
+  void* operator new(size_t size);
+  void* operator new [](size_t size);
+  void operator delete(void* p);
+  void operator delete[](void* p);
 };
 
 //------------------------------------------------------------------------------------------------------------------------
diff --git a/hotspot/src/share/vm/runtime/objectMonitor.hpp b/hotspot/src/share/vm/runtime/objectMonitor.hpp
index e4236f4..df4b027 100644
--- a/hotspot/src/share/vm/runtime/objectMonitor.hpp
+++ b/hotspot/src/share/vm/runtime/objectMonitor.hpp
@@ -303,6 +303,18 @@
  public:
   static int Knob_Verbose;
   static int Knob_SpinLimit;
+  void* operator new (size_t size) {
+    return AllocateHeap(size, mtInternal);
+  }
+  void* operator new[] (size_t size) {
+    return operator new (size);
+  }
+  void operator delete(void* p) {
+    FreeHeap(p, mtInternal);
+  }
+  void operator delete[] (void *p) {
+    operator delete(p);
+  }
 };
 
 #undef TEVENT
diff --git a/hotspot/src/share/vm/runtime/reflectionUtils.hpp b/hotspot/src/share/vm/runtime/reflectionUtils.hpp
index 7641fa7..d51b2ab 100644
--- a/hotspot/src/share/vm/runtime/reflectionUtils.hpp
+++ b/hotspot/src/share/vm/runtime/reflectionUtils.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -136,10 +136,10 @@
   }
 };
 
-class FilteredField {
+class FilteredField : public CHeapObj<mtInternal>  {
  private:
   Klass* _klass;
-  int      _field_offset;
+  int    _field_offset;
 
  public:
   FilteredField(Klass* klass, int field_offset) {
diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp
index 57af1f3..114f27d 100644
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp
@@ -883,15 +883,23 @@
 }
 
 
-JNI_ENTRY(void, throw_unsatisfied_link_error(JNIEnv* env, ...))
+/**
+ * Throws an java/lang/UnsatisfiedLinkError.  The address of this method is
+ * installed in the native function entry of all native Java methods before
+ * they get linked to their actual native methods.
+ *
+ * \note
+ * This method actually never gets called!  The reason is because
+ * the interpreter's native entries call NativeLookup::lookup() which
+ * throws the exception when the lookup fails.  The exception is then
+ * caught and forwarded on the return from NativeLookup::lookup() call
+ * before the call to the native function.  This might change in the future.
+ */
+JNI_ENTRY(void*, throw_unsatisfied_link_error(JNIEnv* env, ...))
 {
-  THROW(vmSymbols::java_lang_UnsatisfiedLinkError());
-}
-JNI_END
-
-JNI_ENTRY(void, throw_unsupported_operation_exception(JNIEnv* env, ...))
-{
-  THROW(vmSymbols::java_lang_UnsupportedOperationException());
+  // We return a bad value here to make sure that the exception is
+  // forwarded before we look at the return value.
+  THROW_(vmSymbols::java_lang_UnsatisfiedLinkError(), (void*)badJNIHandle);
 }
 JNI_END
 
@@ -899,10 +907,6 @@
   return CAST_FROM_FN_PTR(address, &throw_unsatisfied_link_error);
 }
 
-address SharedRuntime::native_method_throw_unsupported_operation_exception_entry() {
-  return CAST_FROM_FN_PTR(address, &throw_unsupported_operation_exception);
-}
-
 
 #ifndef PRODUCT
 JRT_ENTRY(intptr_t, SharedRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2))
diff --git a/hotspot/src/share/vm/runtime/unhandledOops.hpp b/hotspot/src/share/vm/runtime/unhandledOops.hpp
index 97fd854..5f65d15 100644
--- a/hotspot/src/share/vm/runtime/unhandledOops.hpp
+++ b/hotspot/src/share/vm/runtime/unhandledOops.hpp
@@ -48,7 +48,7 @@
 class oop;
 class Thread;
 
-class UnhandledOopEntry {
+class UnhandledOopEntry : public CHeapObj<mtThread> {
  friend class UnhandledOops;
  private:
   oop* _oop_ptr;
@@ -62,7 +62,7 @@
 };
 
 
-class UnhandledOops {
+class UnhandledOops : public CHeapObj<mtThread> {
  friend class Thread;
  private:
   Thread* _thread;
diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp
index b281d7a..b3fdd1e 100644
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp
@@ -1057,6 +1057,7 @@
   c2_nonstatic_field(Compile,            _save_argument_registers, const bool)                                                       \
   c2_nonstatic_field(Compile,            _subsume_loads,           const bool)                                                       \
   c2_nonstatic_field(Compile,            _do_escape_analysis,      const bool)                                                       \
+  c2_nonstatic_field(Compile,            _eliminate_boxing,        const bool)                                                       \
   c2_nonstatic_field(Compile,            _ilt,                     InlineTree*)                                                      \
                                                                                                                                      \
   c2_nonstatic_field(InlineTree,         _caller_jvms,             JVMState*)                                                        \
@@ -3119,15 +3120,15 @@
   // Search for the base type by peeling off const and *
   size_t len = strlen(typeName);
   if (typeName[len-1] == '*') {
-    char * s = new char[len];
+    char * s = NEW_C_HEAP_ARRAY(char, len, mtInternal);
     strncpy(s, typeName, len - 1);
     s[len-1] = '\0';
     // tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
     if (recursiveFindType(origtypes, s, true) == 1) {
-      delete [] s;
+      FREE_C_HEAP_ARRAY(char, s, mtInternal);
       return 1;
     }
-    delete [] s;
+    FREE_C_HEAP_ARRAY(char, s, mtInternal);
   }
   const char* start = NULL;
   if (strstr(typeName, "GrowableArray<") == typeName) {
@@ -3138,15 +3139,15 @@
   if (start != NULL) {
     const char * end = strrchr(typeName, '>');
     int len = end - start + 1;
-    char * s = new char[len];
+    char * s = NEW_C_HEAP_ARRAY(char, len, mtInternal);
     strncpy(s, start, len - 1);
     s[len-1] = '\0';
     // tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
     if (recursiveFindType(origtypes, s, true) == 1) {
-      delete [] s;
+      FREE_C_HEAP_ARRAY(char, s, mtInternal);
       return 1;
     }
-    delete [] s;
+    FREE_C_HEAP_ARRAY(char, s, mtInternal);
   }
   if (strstr(typeName, "const ") == typeName) {
     const char * s = typeName + strlen("const ");
diff --git a/hotspot/src/share/vm/utilities/events.hpp b/hotspot/src/share/vm/utilities/events.hpp
index c2e543d..804fe77 100644
--- a/hotspot/src/share/vm/utilities/events.hpp
+++ b/hotspot/src/share/vm/utilities/events.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -69,7 +69,7 @@
 // semantics aren't appropriate.  The name is used as the label of the
 // log when it is dumped during a crash.
 template <class T> class EventLogBase : public EventLog {
-  template <class X> class EventRecord {
+  template <class X> class EventRecord : public CHeapObj<mtInternal> {
    public:
     double  timestamp;
     Thread* thread;
diff --git a/hotspot/src/share/vm/utilities/quickSort.cpp b/hotspot/src/share/vm/utilities/quickSort.cpp
index e3cfa1e..0cb7f6e 100644
--- a/hotspot/src/share/vm/utilities/quickSort.cpp
+++ b/hotspot/src/share/vm/utilities/quickSort.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,8 +30,11 @@
 
 #include "runtime/os.hpp"
 #include "utilities/quickSort.hpp"
+#include "memory/allocation.hpp"
+#include "memory/allocation.inline.hpp"
 #include <stdlib.h>
 
+#ifdef ASSERT
 static int test_comparator(int a, int b) {
   if (a == b) {
     return 0;
@@ -41,6 +44,7 @@
   }
   return 1;
 }
+#endif // ASSERT
 
 static int test_even_odd_comparator(int a, int b) {
   bool a_is_odd = (a % 2) == 1;
@@ -187,8 +191,8 @@
   // test sorting random arrays
   for (int i = 0; i < 1000; i++) {
     int length = os::random() % 100;
-    int* test_array = new int[length];
-    int* expected_array = new int[length];
+    int* test_array = NEW_C_HEAP_ARRAY(int, length, mtInternal);
+    int* expected_array = NEW_C_HEAP_ARRAY(int, length, mtInternal);
     for (int j = 0; j < length; j++) {
         // Choose random values, but get a chance of getting duplicates
         test_array[j] = os::random() % (length * 2);
@@ -210,8 +214,8 @@
     sort(test_array, length, test_even_odd_comparator, true);
     assert(compare_arrays(test_array, expected_array, length), "Sorting already sorted array changed order of elements - not idempotent");
 
-    delete[] test_array;
-    delete[] expected_array;
+    FREE_C_HEAP_ARRAY(int, test_array, mtInternal);
+    FREE_C_HEAP_ARRAY(int, expected_array, mtInternal);
   }
 }
 
diff --git a/hotspot/src/share/vm/utilities/workgroup.cpp b/hotspot/src/share/vm/utilities/workgroup.cpp
index 5db6344..479cd04 100644
--- a/hotspot/src/share/vm/utilities/workgroup.cpp
+++ b/hotspot/src/share/vm/utilities/workgroup.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -529,7 +529,7 @@
 FreeIdSet::FreeIdSet(int sz, Monitor* mon) :
   _sz(sz), _mon(mon), _hd(0), _waiters(0), _index(-1), _claimed(0)
 {
-  _ids = new int[sz];
+  _ids = NEW_C_HEAP_ARRAY(int, sz, mtInternal);
   for (int i = 0; i < sz; i++) _ids[i] = i+1;
   _ids[sz-1] = end_of_list; // end of list.
   if (_stat_init) {
@@ -549,6 +549,7 @@
 
 FreeIdSet::~FreeIdSet() {
   _sets[_index] = NULL;
+  FREE_C_HEAP_ARRAY(int, _ids, mtInternal);
 }
 
 void FreeIdSet::set_safepoint(bool b) {
diff --git a/hotspot/src/share/vm/utilities/workgroup.hpp b/hotspot/src/share/vm/utilities/workgroup.hpp
index 6a93536..e1184a6 100644
--- a/hotspot/src/share/vm/utilities/workgroup.hpp
+++ b/hotspot/src/share/vm/utilities/workgroup.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -494,7 +494,7 @@
 };
 
 // Represents a set of free small integer ids.
-class FreeIdSet {
+class FreeIdSet : public CHeapObj<mtInternal> {
   enum {
     end_of_list = -1,
     claimed = -2
diff --git a/hotspot/test/compiler/6934604/TestByteBoxing.java b/hotspot/test/compiler/6934604/TestByteBoxing.java
new file mode 100644
index 0000000..ee5511a
--- /dev/null
+++ b/hotspot/test/compiler/6934604/TestByteBoxing.java
@@ -0,0 +1,777 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6934604
+ * @summary enable parts of EliminateAutoBox by default
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox TestByteBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestByteBoxing.dummy -XX:CompileCommand=exclude,TestByteBoxing.foo -XX:CompileCommand=exclude,TestByteBoxing.foob TestByteBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestByteBoxing.dummy -XX:CompileCommand=exclude,TestByteBoxing.foo -XX:CompileCommand=exclude,TestByteBoxing.foob TestByteBoxing
+ *
+ */
+
+public class TestByteBoxing {
+
+  static final Byte ibc = new Byte((byte)1);
+
+  //===============================================
+  // Non-inlined methods to test deoptimization info
+  static void dummy()      { }
+  static byte foo(byte i)  { return i; }
+  static Byte foob(byte i) { return Byte.valueOf(i); }
+
+
+  static byte simple(byte i) {
+    Byte ib = new Byte(i);
+    return ib;
+  }
+
+  static byte simpleb(byte i) {
+    Byte ib = Byte.valueOf(i);
+    return ib;
+  }
+
+  static byte simplec() {
+    Byte ib = ibc;
+    return ib;
+  }
+
+  static byte simplef(byte i) {
+    Byte ib = foob(i);
+    return ib;
+  }
+
+  static byte simplep(Byte ib) {
+    return ib;
+  }
+
+  static byte simple2(byte i) {
+    Byte ib1 = new Byte(i);
+    Byte ib2 = new Byte((byte)(i+1));
+    return (byte)(ib1 + ib2);
+  }
+
+  static byte simpleb2(byte i) {
+    Byte ib1 = Byte.valueOf(i);
+    Byte ib2 = Byte.valueOf((byte)(i+1));
+    return (byte)(ib1 + ib2);
+  }
+
+  static byte simplem2(byte i) {
+    Byte ib1 = new Byte(i);
+    Byte ib2 = Byte.valueOf((byte)(i+1));
+    return (byte)(ib1 + ib2);
+  }
+
+  static byte simplep2(byte i, Byte ib1) {
+    Byte ib2 = Byte.valueOf((byte)(i+1));
+    return (byte)(ib1 + ib2);
+  }
+
+  static byte simplec2(byte i) {
+    Byte ib1 = ibc;
+    Byte ib2 = Byte.valueOf((byte)(i+1));
+    return (byte)(ib1 + ib2);
+  }
+
+  //===============================================
+  static byte test(byte i) {
+    Byte ib = new Byte(i);
+    if ((i&1) == 0)
+      ib = (byte)(i+1);
+    return ib;
+  }
+
+  static byte testb(byte i) {
+    Byte ib = i;
+    if ((i&1) == 0)
+      ib = (byte)(i+1);
+    return ib;
+  }
+
+  static byte testm(byte i) {
+    Byte ib = i;
+    if ((i&1) == 0)
+      ib = new Byte((byte)(i+1));
+    return ib;
+  }
+
+  static byte testp(byte i, Byte ib) {
+    if ((i&1) == 0)
+      ib = new Byte((byte)(i+1));
+    return ib;
+  }
+
+  static byte testc(byte i) {
+    Byte ib = ibc;
+    if ((i&1) == 0)
+      ib = new Byte((byte)(i+1));
+    return ib;
+  }
+
+  static byte test2(byte i) {
+    Byte ib1 = new Byte(i);
+    Byte ib2 = new Byte((byte)(i+1));
+    if ((i&1) == 0) {
+      ib1 = new Byte((byte)(i+1));
+      ib2 = new Byte((byte)(i+2));
+    }
+    return (byte)(ib1+ib2);
+  }
+
+  static byte testb2(byte i) {
+    Byte ib1 = i;
+    Byte ib2 = (byte)(i+1);
+    if ((i&1) == 0) {
+      ib1 = (byte)(i+1);
+      ib2 = (byte)(i+2);
+    }
+    return (byte)(ib1 + ib2);
+  }
+
+  static byte testm2(byte i) {
+    Byte ib1 = new Byte(i);
+    Byte ib2 = (byte)(i+1);
+    if ((i&1) == 0) {
+      ib1 = new Byte((byte)(i+1));
+      ib2 = (byte)(i+2);
+    }
+    return (byte)(ib1 + ib2);
+  }
+
+  static byte testp2(byte i, Byte ib1) {
+    Byte ib2 = (byte)(i+1);
+    if ((i&1) == 0) {
+      ib1 = new Byte((byte)(i+1));
+      ib2 = (byte)(i+2);
+    }
+    return (byte)(ib1 + ib2);
+  }
+
+  static byte testc2(byte i) {
+    Byte ib1 = ibc;
+    Byte ib2 = (byte)(i+1);
+    if ((i&1) == 0) {
+      ib1 = (byte)(ibc+1);
+      ib2 = (byte)(i+2);
+    }
+    return (byte)(ib1 + ib2);
+  }
+
+  //===============================================
+  static byte sum(byte[] a) {
+    byte result = 1;
+    for (Byte i : a)
+        result += i;
+    return result;
+  }
+
+  static byte sumb(byte[] a) {
+    Byte result = 1;
+    for (Byte i : a)
+        result = (byte)(result + i);
+    return result;
+  }
+
+  static byte sumc(byte[] a) {
+    Byte result = ibc;
+    for (Byte i : a)
+        result = (byte)(result + i);
+    return result;
+  }
+
+  static byte sumf(byte[] a) {
+    Byte result = foob((byte)1);
+    for (Byte i : a)
+        result = (byte)(result + i);
+    return result;
+  }
+
+  static byte sump(byte[] a, Byte result) {
+    for (Byte i : a)
+        result = (byte)(result + i);
+    return result;
+  }
+
+  static byte sum2(byte[] a) {
+    byte result1 = 1;
+    byte result2 = 1;
+    for (Byte i : a) {
+        result1 += i;
+        result2 += i + 1;
+    }
+    return (byte)(result1 + result2);
+  }
+
+  static byte sumb2(byte[] a) {
+    Byte result1 = 1;
+    Byte result2 = 1;
+    for (Byte i : a) {
+        result1 = (byte)(result1 + i);
+        result2 = (byte)(result2 + i + 1);
+    }
+    return (byte)(result1 + result2);
+  }
+
+  static byte summ2(byte[] a) {
+    Byte result1 = 1;
+    Byte result2 = new Byte((byte)1);
+    for (Byte i : a) {
+        result1 = (byte)(result1 + i);
+        result2 = (byte)(result2 + new Byte((byte)(i + 1)));
+    }
+    return (byte)(result1 + result2);
+  }
+
+  static byte sump2(byte[] a, Byte result2) {
+    Byte result1 = 1;
+    for (Byte i : a) {
+        result1 = (byte)(result1 + i);
+        result2 = (byte)(result2 + i + 1);
+    }
+    return (byte)(result1 + result2);
+  }
+
+  static byte sumc2(byte[] a) {
+    Byte result1 = 1;
+    Byte result2 = ibc;
+    for (Byte i : a) {
+        result1 = (byte)(result1 + i);
+        result2 = (byte)(result2 + i + ibc);
+    }
+    return (byte)(result1 + result2);
+  }
+
+  //===============================================
+  static byte remi_sum() {
+    Byte j = new Byte((byte)1);
+    for (int i = 0; i< 1000; i++) {
+      j = new Byte((byte)(j + 1));
+    }
+    return j;
+  }
+
+  static byte remi_sumb() {
+    Byte j = Byte.valueOf((byte)1);
+    for (int i = 0; i< 1000; i++) {
+      j = (byte)(j + 1);
+    }
+    return j;
+  }
+
+  static byte remi_sumf() {
+    Byte j = foob((byte)1);
+    for (int i = 0; i< 1000; i++) {
+      j = (byte)(j + 1);
+    }
+    return j;
+  }
+
+  static byte remi_sump(Byte j) {
+    for (int i = 0; i< 1000; i++) {
+      j = new Byte((byte)(j + 1));
+    }
+    return j;
+  }
+
+  static byte remi_sumc() {
+    Byte j = ibc;
+    for (int i = 0; i< 1000; i++) {
+      j = (byte)(j + ibc);
+    }
+    return j;
+  }
+
+  static byte remi_sum2() {
+    Byte j1 = new Byte((byte)1);
+    Byte j2 = new Byte((byte)1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = new Byte((byte)(j1 + 1));
+      j2 = new Byte((byte)(j2 + 2));
+    }
+    return (byte)(j1 + j2);
+  }
+
+  static byte remi_sumb2() {
+    Byte j1 = Byte.valueOf((byte)1);
+    Byte j2 = Byte.valueOf((byte)1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = (byte)(j1 + 1);
+      j2 = (byte)(j2 + 2);
+    }
+    return (byte)(j1 + j2);
+  }
+
+  static byte remi_summ2() {
+    Byte j1 = new Byte((byte)1);
+    Byte j2 = Byte.valueOf((byte)1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = new Byte((byte)(j1 + 1));
+      j2 = (byte)(j2 + 2);
+    }
+    return (byte)(j1 + j2);
+  }
+
+  static byte remi_sump2(Byte j1) {
+    Byte j2 = Byte.valueOf((byte)1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = new Byte((byte)(j1 + 1));
+      j2 = (byte)(j2 + 2);
+    }
+    return (byte)(j1 + j2);
+  }
+
+  static byte remi_sumc2() {
+    Byte j1 = ibc;
+    Byte j2 = Byte.valueOf((byte)1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = (byte)(j1 + ibc);
+      j2 = (byte)(j2 + 2);
+    }
+    return (byte)(j1 + j2);
+  }
+
+
+  //===============================================
+  // Safepointa and debug info for deoptimization
+  static byte simple_deop(byte i) {
+    Byte ib = new Byte(foo(i));
+    dummy();
+    return ib;
+  }
+
+  static byte simpleb_deop(byte i) {
+    Byte ib = Byte.valueOf(foo(i));
+    dummy();
+    return ib;
+  }
+
+  static byte simplef_deop(byte i) {
+    Byte ib = foob(i);
+    dummy();
+    return ib;
+  }
+
+  static byte simplep_deop(Byte ib) {
+    dummy();
+    return ib;
+  }
+
+  static byte simplec_deop(byte i) {
+    Byte ib = ibc;
+    dummy();
+    return ib;
+  }
+
+  static byte test_deop(byte i) {
+    Byte ib = new Byte(foo(i));
+    if ((i&1) == 0)
+      ib = foo((byte)(i+1));
+    dummy();
+    return ib;
+  }
+
+  static byte testb_deop(byte i) {
+    Byte ib = foo(i);
+    if ((i&1) == 0)
+      ib = foo((byte)(i+1));
+    dummy();
+    return ib;
+  }
+
+  static byte testf_deop(byte i) {
+    Byte ib = foob(i);
+    if ((i&1) == 0)
+      ib = foo((byte)(i+1));
+    dummy();
+    return ib;
+  }
+
+  static byte testp_deop(byte i, Byte ib) {
+    if ((i&1) == 0)
+      ib = foo((byte)(i+1));
+    dummy();
+    return ib;
+  }
+
+  static byte testc_deop(byte i) {
+    Byte ib = ibc;
+    if ((i&1) == 0)
+      ib = foo((byte)(i+1));
+    dummy();
+    return ib;
+  }
+
+  static byte sum_deop(byte[] a) {
+    byte result = 1;
+    for (Byte i : a)
+        result += foo(i);
+    dummy();
+    return result;
+  }
+
+  static byte sumb_deop(byte[] a) {
+    Byte result = 1;
+    for (Byte i : a)
+        result = (byte)(result + foo(i));
+    dummy();
+    return result;
+  }
+
+  static byte sumf_deop(byte[] a) {
+    Byte result = 1;
+    for (Byte i : a)
+        result = (byte)(result + foob(i));
+    dummy();
+    return result;
+  }
+
+  static byte sump_deop(byte[] a, Byte result) {
+    for (Byte i : a)
+        result = (byte)(result + foob(i));
+    dummy();
+    return result;
+  }
+
+  static byte sumc_deop(byte[] a) {
+    Byte result = ibc;
+    for (Byte i : a)
+        result = (byte)(result + foo(i));
+    dummy();
+    return result;
+  }
+
+  static byte remi_sum_deop() {
+    Byte j = new Byte(foo((byte)1));
+    for (int i = 0; i< 1000; i++) {
+      j = new Byte(foo((byte)(j + 1)));
+    }
+    dummy();
+    return j;
+  }
+
+  static byte remi_sumb_deop() {
+    Byte j = Byte.valueOf(foo((byte)1));
+    for (int i = 0; i< 1000; i++) {
+      j = foo((byte)(j + 1));
+    }
+    dummy();
+    return j;
+  }
+
+  static byte remi_sumf_deop() {
+    Byte j = foob((byte)1);
+    for (int i = 0; i< 1000; i++) {
+      j = foo((byte)(j + 1));
+    }
+    dummy();
+    return j;
+  }
+
+  static byte remi_sump_deop(Byte j) {
+    for (int i = 0; i< 1000; i++) {
+      j = foo((byte)(j + 1));
+    }
+    dummy();
+    return j;
+  }
+
+  static byte remi_sumc_deop() {
+    Byte j = ibc;
+    for (int i = 0; i< 1000; i++) {
+      j = foo((byte)(j + 1));
+    }
+    dummy();
+    return j;
+  }
+
+  //===============================================
+  // Conditional increment
+  static byte remi_sum_cond() {
+    Byte j = new Byte((byte)1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = new Byte((byte)(j + 1));
+      }
+    }
+    return j;
+  }
+
+  static byte remi_sumb_cond() {
+    Byte j = Byte.valueOf((byte)1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = (byte)(j + 1);
+      }
+    }
+    return j;
+  }
+
+  static byte remi_sumf_cond() {
+    Byte j = foob((byte)1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = (byte)(j + 1);
+      }
+    }
+    return j;
+  }
+
+  static byte remi_sump_cond(Byte j) {
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = (byte)(j + 1);
+      }
+    }
+    return j;
+  }
+
+  static byte remi_sumc_cond() {
+    Byte j = ibc;
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = (byte)(j + ibc);
+      }
+    }
+    return j;
+  }
+
+  static byte remi_sum2_cond() {
+    Byte j1 = new Byte((byte)1);
+    Byte j2 = new Byte((byte)1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = new Byte((byte)(j1 + 1));
+      } else {
+        j2 = new Byte((byte)(j2 + 2));
+      }
+    }
+    return (byte)(j1 + j2);
+  }
+
+  static byte remi_sumb2_cond() {
+    Byte j1 = Byte.valueOf((byte)1);
+    Byte j2 = Byte.valueOf((byte)1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = (byte)(j1 + 1);
+      } else {
+        j2 = (byte)(j2 + 2);
+      }
+    }
+    return (byte)(j1 + j2);
+  }
+
+  static byte remi_summ2_cond() {
+    Byte j1 = new Byte((byte)1);
+    Byte j2 = Byte.valueOf((byte)1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = new Byte((byte)(j1 + 1));
+      } else {
+        j2 = (byte)(j2 + 2);
+      }
+    }
+    return (byte)(j1 + j2);
+  }
+
+  static byte remi_sump2_cond(Byte j1) {
+    Byte j2 = Byte.valueOf((byte)1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = new Byte((byte)(j1 + 1));
+      } else {
+        j2 = (byte)(j2 + 2);
+      }
+    }
+    return (byte)(j1 + j2);
+  }
+
+  static byte remi_sumc2_cond() {
+    Byte j1 = ibc;
+    Byte j2 = Byte.valueOf((byte)1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = (byte)(j1 + ibc);
+      } else {
+        j2 = (byte)(j2 + 2);
+      }
+    }
+    return (byte)(j1 + j2);
+  }
+
+
+  public static void main(String[] args) {
+    final int ntests = 70;
+
+    String[] test_name = new String[] {
+        "simple",      "simpleb",      "simplec",      "simplef",      "simplep",
+        "simple2",     "simpleb2",     "simplec2",     "simplem2",     "simplep2",
+        "simple_deop", "simpleb_deop", "simplec_deop", "simplef_deop", "simplep_deop",
+        "test",        "testb",        "testc",        "testm",        "testp",
+        "test2",       "testb2",       "testc2",       "testm2",       "testp2",
+        "test_deop",   "testb_deop",   "testc_deop",   "testf_deop",   "testp_deop",
+        "sum",         "sumb",         "sumc",         "sumf",         "sump",
+        "sum2",        "sumb2",        "sumc2",        "summ2",        "sump2",
+        "sum_deop",    "sumb_deop",    "sumc_deop",    "sumf_deop",    "sump_deop",
+        "remi_sum",       "remi_sumb",       "remi_sumc",       "remi_sumf",       "remi_sump",
+        "remi_sum2",      "remi_sumb2",      "remi_sumc2",      "remi_summ2",      "remi_sump2",
+        "remi_sum_deop",  "remi_sumb_deop",  "remi_sumc_deop",  "remi_sumf_deop",  "remi_sump_deop",
+        "remi_sum_cond",  "remi_sumb_cond",  "remi_sumc_cond",  "remi_sumf_cond",  "remi_sump_cond",
+        "remi_sum2_cond", "remi_sumb2_cond", "remi_sumc2_cond", "remi_summ2_cond", "remi_sump2_cond"
+    };
+
+    final int[] val = new int[] {
+      -5488, -5488, 12000, -5488, -5488,
+       1024,  1024, -5552,  1024,  1024,
+      -5488, -5488, 12000, -5488, -5488,
+        512,   512,  6256,   512,   512,
+      13024, 13024, -5584, 13024, 13024,
+        512,   512,  6256,   512,   512,
+         45,    45,    45,    45,    45,
+         66,    66,    66,    66,    66,
+         45,    45,    45,    45,    45,
+        -23,   -23,   -23,   -23,   -23,
+        -70,   -70,   -70,   -70,   -70,
+        -23,   -23,   -23,   -23,   -23,
+        -11,   -11,   -11,   -11,   -11,
+        -34,   -34,   -34,   -34,   -34
+    };
+
+    int[] res = new int[ntests];
+    for (int i = 0; i < ntests; i++) {
+      res[i] = 0;
+    }
+
+
+    for (int i = 0; i < 12000; i++) {
+      res[0] += simple((byte)i);
+      res[1] += simpleb((byte)i);
+      res[2] += simplec();
+      res[3] += simplef((byte)i);
+      res[4] += simplep((byte)i);
+
+      res[5] += simple2((byte)i);
+      res[6] += simpleb2((byte)i);
+      res[7] += simplec2((byte)i);
+      res[8] += simplem2((byte)i);
+      res[9] += simplep2((byte)i, (byte)i);
+
+      res[10] += simple_deop((byte)i);
+      res[11] += simpleb_deop((byte)i);
+      res[12] += simplec_deop((byte)i);
+      res[13] += simplef_deop((byte)i);
+      res[14] += simplep_deop((byte)i);
+
+      res[15] += test((byte)i);
+      res[16] += testb((byte)i);
+      res[17] += testc((byte)i);
+      res[18] += testm((byte)i);
+      res[19] += testp((byte)i, (byte)i);
+
+      res[20] += test2((byte)i);
+      res[21] += testb2((byte)i);
+      res[22] += testc2((byte)i);
+      res[23] += testm2((byte)i);
+      res[24] += testp2((byte)i, (byte)i);
+
+      res[25] += test_deop((byte)i);
+      res[26] += testb_deop((byte)i);
+      res[27] += testc_deop((byte)i);
+      res[28] += testf_deop((byte)i);
+      res[29] += testp_deop((byte)i, (byte)i);
+    }
+
+    byte[] ia = new byte[1000];
+    for (int i = 0; i < 1000; i++) {
+      ia[i] = (byte)i;
+    }
+
+    for (int i = 0; i < 100; i++) {
+      res[30] = sum(ia);
+      res[31] = sumb(ia);
+      res[32] = sumc(ia);
+      res[33] = sumf(ia);
+      res[34] = sump(ia, (byte)1);
+
+      res[35] = sum2(ia);
+      res[36] = sumb2(ia);
+      res[37] = sumc2(ia);
+      res[38] = summ2(ia);
+      res[39] = sump2(ia, (byte)1);
+
+      res[40] = sum_deop(ia);
+      res[41] = sumb_deop(ia);
+      res[42] = sumc_deop(ia);
+      res[43] = sumf_deop(ia);
+      res[44] = sump_deop(ia, (byte)1);
+
+      res[45] = remi_sum();
+      res[46] = remi_sumb();
+      res[47] = remi_sumc();
+      res[48] = remi_sumf();
+      res[49] = remi_sump((byte)1);
+
+      res[50] = remi_sum2();
+      res[51] = remi_sumb2();
+      res[52] = remi_sumc2();
+      res[53] = remi_summ2();
+      res[54] = remi_sump2((byte)1);
+
+      res[55] = remi_sum_deop();
+      res[56] = remi_sumb_deop();
+      res[57] = remi_sumc_deop();
+      res[58] = remi_sumf_deop();
+      res[59] = remi_sump_deop((byte)1);
+
+      res[60] = remi_sum_cond();
+      res[61] = remi_sumb_cond();
+      res[62] = remi_sumc_cond();
+      res[63] = remi_sumf_cond();
+      res[64] = remi_sump_cond((byte)1);
+
+      res[65] = remi_sum2_cond();
+      res[66] = remi_sumb2_cond();
+      res[67] = remi_sumc2_cond();
+      res[68] = remi_summ2_cond();
+      res[69] = remi_sump2_cond((byte)1);
+    }
+
+    int failed = 0;
+    for (int i = 0; i < ntests; i++) {
+      if (res[i] != val[i]) {
+        System.err.println(test_name[i] + ": " + res[i] + " != " + val[i]);
+        failed++;
+      }
+    }
+    if (failed > 0) {
+      System.err.println("Failed " + failed + " tests.");
+      throw new InternalError();
+    } else {
+      System.out.println("Passed.");
+    }
+  }
+}
diff --git a/hotspot/test/compiler/6934604/TestDoubleBoxing.java b/hotspot/test/compiler/6934604/TestDoubleBoxing.java
new file mode 100644
index 0000000..7b76ac9
--- /dev/null
+++ b/hotspot/test/compiler/6934604/TestDoubleBoxing.java
@@ -0,0 +1,777 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6934604
+ * @summary enable parts of EliminateAutoBox by default
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox TestDoubleBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestDoubleBoxing.dummy -XX:CompileCommand=exclude,TestDoubleBoxing.foo -XX:CompileCommand=exclude,TestDoubleBoxing.foob TestDoubleBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestDoubleBoxing.dummy -XX:CompileCommand=exclude,TestDoubleBoxing.foo -XX:CompileCommand=exclude,TestDoubleBoxing.foob TestDoubleBoxing
+ *
+ */
+
+public class TestDoubleBoxing {
+
+  static final Double ibc = new Double(1.);
+
+  //===============================================
+  // Non-inlined methods to test deoptimization info
+  static void   dummy()        { }
+  static double foo(double i)  { return i; }
+  static Double foob(double i) { return Double.valueOf(i); }
+
+
+  static double simple(double i) {
+    Double ib = new Double(i);
+    return ib;
+  }
+
+  static double simpleb(double i) {
+    Double ib = Double.valueOf(i);
+    return ib;
+  }
+
+  static double simplec() {
+    Double ib = ibc;
+    return ib;
+  }
+
+  static double simplef(double i) {
+    Double ib = foob(i);
+    return ib;
+  }
+
+  static double simplep(Double ib) {
+    return ib;
+  }
+
+  static double simple2(double i) {
+    Double ib1 = new Double(i);
+    Double ib2 = new Double(i+1.);
+    return ib1 + ib2;
+  }
+
+  static double simpleb2(double i) {
+    Double ib1 = Double.valueOf(i);
+    Double ib2 = Double.valueOf(i+1.);
+    return ib1 + ib2;
+  }
+
+  static double simplem2(double i) {
+    Double ib1 = new Double(i);
+    Double ib2 = Double.valueOf(i+1.);
+    return ib1 + ib2;
+  }
+
+  static double simplep2(double i, Double ib1) {
+    Double ib2 = Double.valueOf(i+1.);
+    return ib1 + ib2;
+  }
+
+  static double simplec2(double i) {
+    Double ib1 = ibc;
+    Double ib2 = Double.valueOf(i+1.);
+    return ib1 + ib2;
+  }
+
+  //===============================================
+  static double test(double f, int i) {
+    Double ib = new Double(f);
+    if ((i&1) == 0)
+      ib = f+1.;
+    return ib;
+  }
+
+  static double testb(double f, int i) {
+    Double ib = f;
+    if ((i&1) == 0)
+      ib = (f+1.);
+    return ib;
+  }
+
+  static double testm(double f, int i) {
+    Double ib = f;
+    if ((i&1) == 0)
+      ib = new Double(f+1.);
+    return ib;
+  }
+
+  static double testp(double f, int i, Double ib) {
+    if ((i&1) == 0)
+      ib = new Double(f+1.);
+    return ib;
+  }
+
+  static double testc(double f, int i) {
+    Double ib = ibc;
+    if ((i&1) == 0)
+      ib = new Double(f+1.);
+    return ib;
+  }
+
+  static double test2(double f, int i) {
+    Double ib1 = new Double(f);
+    Double ib2 = new Double(f+1.);
+    if ((i&1) == 0) {
+      ib1 = new Double(f+1.);
+      ib2 = new Double(f+2.);
+    }
+    return ib1+ib2;
+  }
+
+  static double testb2(double f, int i) {
+    Double ib1 = f;
+    Double ib2 = f+1.;
+    if ((i&1) == 0) {
+      ib1 = (f+1.);
+      ib2 = (f+2.);
+    }
+    return ib1+ib2;
+  }
+
+  static double testm2(double f, int i) {
+    Double ib1 = new Double(f);
+    Double ib2 = f+1.;
+    if ((i&1) == 0) {
+      ib1 = new Double(f+1.);
+      ib2 = (f+2.);
+    }
+    return ib1+ib2;
+  }
+
+  static double testp2(double f, int i, Double ib1) {
+    Double ib2 = f+1.;
+    if ((i&1) == 0) {
+      ib1 = new Double(f+1.);
+      ib2 = (f+2.);
+    }
+    return ib1+ib2;
+  }
+
+  static double testc2(double f, int i) {
+    Double ib1 = ibc;
+    Double ib2 = f+1.;
+    if ((i&1) == 0) {
+      ib1 = (ibc+1.);
+      ib2 = (f+2.);
+    }
+    return ib1+ib2;
+  }
+
+  //===============================================
+  static double sum(double[] a) {
+    double result = 1.;
+    for (Double i : a)
+        result += i;
+    return result;
+  }
+
+  static double sumb(double[] a) {
+    Double result = 1.;
+    for (Double i : a)
+        result += i;
+    return result;
+  }
+
+  static double sumc(double[] a) {
+    Double result = ibc;
+    for (Double i : a)
+        result += i;
+    return result;
+  }
+
+  static double sumf(double[] a) {
+    Double result = foob(1.);
+    for (Double i : a)
+        result += i;
+    return result;
+  }
+
+  static double sump(double[] a, Double result) {
+    for (Double i : a)
+        result += i;
+    return result;
+  }
+
+  static double sum2(double[] a) {
+    double result1 = 1.;
+    double result2 = 1.;
+    for (Double i : a) {
+        result1 += i;
+        result2 += i + 1.;
+    }
+    return result1 + result2;
+  }
+
+  static double sumb2(double[] a) {
+    Double result1 = 1.;
+    Double result2 = 1.;
+    for (Double i : a) {
+        result1 += i;
+        result2 += i + 1.;
+    }
+    return result1 + result2;
+  }
+
+  static double summ2(double[] a) {
+    Double result1 = 1.;
+    Double result2 = new Double(1.);
+    for (Double i : a) {
+        result1 += i;
+        result2 += new Double(i + 1.);
+    }
+    return result1 + result2;
+  }
+
+  static double sump2(double[] a, Double result2) {
+    Double result1 = 1.;
+    for (Double i : a) {
+        result1 += i;
+        result2 += i + 1.;
+    }
+    return result1 + result2;
+  }
+
+  static double sumc2(double[] a) {
+    Double result1 = 1.;
+    Double result2 = ibc;
+    for (Double i : a) {
+        result1 += i;
+        result2 += i + ibc;
+    }
+    return result1 + result2;
+  }
+
+  //===============================================
+  static double remi_sum() {
+    Double j = new Double(1.);
+    for (int i = 0; i< 1000; i++) {
+      j = new Double(j + 1.);
+    }
+    return j;
+  }
+
+  static double remi_sumb() {
+    Double j = Double.valueOf(1.);
+    for (int i = 0; i< 1000; i++) {
+      j = j + 1.;
+    }
+    return j;
+  }
+
+  static double remi_sumf() {
+    Double j = foob(1.);
+    for (int i = 0; i< 1000; i++) {
+      j = j + 1.;
+    }
+    return j;
+  }
+
+  static double remi_sump(Double j) {
+    for (int i = 0; i< 1000; i++) {
+      j = new Double(j + 1.);
+    }
+    return j;
+  }
+
+  static double remi_sumc() {
+    Double j = ibc;
+    for (int i = 0; i< 1000; i++) {
+      j = j + ibc;
+    }
+    return j;
+  }
+
+  static double remi_sum2() {
+    Double j1 = new Double(1.);
+    Double j2 = new Double(1.);
+    for (int i = 0; i< 1000; i++) {
+      j1 = new Double(j1 + 1.);
+      j2 = new Double(j2 + 2.);
+    }
+    return j1 + j2;
+  }
+
+  static double remi_sumb2() {
+    Double j1 = Double.valueOf(1.);
+    Double j2 = Double.valueOf(1.);
+    for (int i = 0; i< 1000; i++) {
+      j1 = j1 + 1.;
+      j2 = j2 + 2.;
+    }
+    return j1 + j2;
+  }
+
+  static double remi_summ2() {
+    Double j1 = new Double(1.);
+    Double j2 = Double.valueOf(1.);
+    for (int i = 0; i< 1000; i++) {
+      j1 = new Double(j1 + 1.);
+      j2 = j2 + 2.;
+    }
+    return j1 + j2;
+  }
+
+  static double remi_sump2(Double j1) {
+    Double j2 = Double.valueOf(1.);
+    for (int i = 0; i< 1000; i++) {
+      j1 = new Double(j1 + 1.);
+      j2 = j2 + 2.;
+    }
+    return j1 + j2;
+  }
+
+  static double remi_sumc2() {
+    Double j1 = ibc;
+    Double j2 = Double.valueOf(1.);
+    for (int i = 0; i< 1000; i++) {
+      j1 = j1 + ibc;
+      j2 = j2 + 2.;
+    }
+    return j1 + j2;
+  }
+
+
+  //===============================================
+  // Safepointa and debug info for deoptimization
+  static double simple_deop(double i) {
+    Double ib = new Double(foo(i));
+    dummy();
+    return ib;
+  }
+
+  static double simpleb_deop(double i) {
+    Double ib = Double.valueOf(foo(i));
+    dummy();
+    return ib;
+  }
+
+  static double simplef_deop(double i) {
+    Double ib = foob(i);
+    dummy();
+    return ib;
+  }
+
+  static double simplep_deop(Double ib) {
+    dummy();
+    return ib;
+  }
+
+  static double simplec_deop(double i) {
+    Double ib = ibc;
+    dummy();
+    return ib;
+  }
+
+  static double test_deop(double f, int i) {
+    Double ib = new Double(foo(f));
+    if ((i&1) == 0)
+      ib = foo(f+1.);
+    dummy();
+    return ib;
+  }
+
+  static double testb_deop(double f, int i) {
+    Double ib = foo(f);
+    if ((i&1) == 0)
+      ib = foo(f+1.);
+    dummy();
+    return ib;
+  }
+
+  static double testf_deop(double f, int i) {
+    Double ib = foob(f);
+    if ((i&1) == 0)
+      ib = foo(f+1.);
+    dummy();
+    return ib;
+  }
+
+  static double testp_deop(double f, int i, Double ib) {
+    if ((i&1) == 0)
+      ib = foo(f+1.);
+    dummy();
+    return ib;
+  }
+
+  static double testc_deop(double f, int i) {
+    Double ib = ibc;
+    if ((i&1) == 0)
+      ib = foo(f+1.);
+    dummy();
+    return ib;
+  }
+
+  static double sum_deop(double[] a) {
+    double result = 1.;
+    for (Double i : a)
+        result += foo(i);
+    dummy();
+    return result;
+  }
+
+  static double sumb_deop(double[] a) {
+    Double result = 1.;
+    for (Double i : a)
+        result += foo(i);
+    dummy();
+    return result;
+  }
+
+  static double sumf_deop(double[] a) {
+    Double result = 1.;
+    for (Double i : a)
+        result += foob(i);
+    dummy();
+    return result;
+  }
+
+  static double sump_deop(double[] a, Double result) {
+    for (Double i : a)
+        result += foob(i);
+    dummy();
+    return result;
+  }
+
+  static double sumc_deop(double[] a) {
+    Double result = ibc;
+    for (Double i : a)
+        result += foo(i);
+    dummy();
+    return result;
+  }
+
+  static double remi_sum_deop() {
+    Double j = new Double(foo(1.));
+    for (int i = 0; i< 1000; i++) {
+      j = new Double(foo(j + 1.));
+    }
+    dummy();
+    return j;
+  }
+
+  static double remi_sumb_deop() {
+    Double j = Double.valueOf(foo(1.));
+    for (int i = 0; i< 1000; i++) {
+      j = foo(j + 1.);
+    }
+    dummy();
+    return j;
+  }
+
+  static double remi_sumf_deop() {
+    Double j = foob(1.);
+    for (int i = 0; i< 1000; i++) {
+      j = foo(j + 1.);
+    }
+    dummy();
+    return j;
+  }
+
+  static double remi_sump_deop(Double j) {
+    for (int i = 0; i< 1000; i++) {
+      j = foo(j + 1.);
+    }
+    dummy();
+    return j;
+  }
+
+  static double remi_sumc_deop() {
+    Double j = ibc;
+    for (int i = 0; i< 1000; i++) {
+      j = foo(j + 1.);
+    }
+    dummy();
+    return j;
+  }
+
+  //===============================================
+  // Conditional increment
+  static double remi_sum_cond() {
+    Double j = new Double(1.);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = new Double(j + 1.);
+      }
+    }
+    return j;
+  }
+
+  static double remi_sumb_cond() {
+    Double j = Double.valueOf(1.);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = j + 1.;
+      }
+    }
+    return j;
+  }
+
+  static double remi_sumf_cond() {
+    Double j = foob(1.);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = j + 1.;
+      }
+    }
+    return j;
+  }
+
+  static double remi_sump_cond(Double j) {
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = j + 1.;
+      }
+    }
+    return j;
+  }
+
+  static double remi_sumc_cond() {
+    Double j = ibc;
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = j + ibc;
+      }
+    }
+    return j;
+  }
+
+  static double remi_sum2_cond() {
+    Double j1 = new Double(1.);
+    Double j2 = new Double(1.);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = new Double(j1 + 1.);
+      } else {
+        j2 = new Double(j2 + 2.);
+      }
+    }
+    return j1 + j2;
+  }
+
+  static double remi_sumb2_cond() {
+    Double j1 = Double.valueOf(1.);
+    Double j2 = Double.valueOf(1.);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = j1 + 1.;
+      } else {
+        j2 = j2 + 2.;
+      }
+    }
+    return j1 + j2;
+  }
+
+  static double remi_summ2_cond() {
+    Double j1 = new Double(1.);
+    Double j2 = Double.valueOf(1.);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = new Double(j1 + 1.);
+      } else {
+        j2 = j2 + 2.;
+      }
+    }
+    return j1 + j2;
+  }
+
+  static double remi_sump2_cond(Double j1) {
+    Double j2 = Double.valueOf(1.);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = new Double(j1 + 1.);
+      } else {
+        j2 = j2 + 2.;
+      }
+    }
+    return j1 + j2;
+  }
+
+  static double remi_sumc2_cond() {
+    Double j1 = ibc;
+    Double j2 = Double.valueOf(1.);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = j1 + ibc;
+      } else {
+        j2 = j2 + 2;
+      }
+    }
+    return j1 + j2;
+  }
+
+
+  public static void main(String[] args) {
+    final int ntests = 70;
+
+    String[] test_name = new String[] {
+        "simple",      "simpleb",      "simplec",      "simplef",      "simplep",
+        "simple2",     "simpleb2",     "simplec2",     "simplem2",     "simplep2",
+        "simple_deop", "simpleb_deop", "simplec_deop", "simplef_deop", "simplep_deop",
+        "test",        "testb",        "testc",        "testm",        "testp",
+        "test2",       "testb2",       "testc2",       "testm2",       "testp2",
+        "test_deop",   "testb_deop",   "testc_deop",   "testf_deop",   "testp_deop",
+        "sum",         "sumb",         "sumc",         "sumf",         "sump",
+        "sum2",        "sumb2",        "sumc2",        "summ2",        "sump2",
+        "sum_deop",    "sumb_deop",    "sumc_deop",    "sumf_deop",    "sump_deop",
+        "remi_sum",       "remi_sumb",       "remi_sumc",       "remi_sumf",       "remi_sump",
+        "remi_sum2",      "remi_sumb2",      "remi_sumc2",      "remi_summ2",      "remi_sump2",
+        "remi_sum_deop",  "remi_sumb_deop",  "remi_sumc_deop",  "remi_sumf_deop",  "remi_sump_deop",
+        "remi_sum_cond",  "remi_sumb_cond",  "remi_sumc_cond",  "remi_sumf_cond",  "remi_sump_cond",
+        "remi_sum2_cond", "remi_sumb2_cond", "remi_sumc2_cond", "remi_summ2_cond", "remi_sump2_cond"
+    };
+
+    final double[] val = new double[] {
+       71994000.,  71994000.,    12000.,  71994000.,  71994000.,
+      144000000., 144000000., 72018000., 144000000., 144000000.,
+       71994000.,  71994000.,    12000.,  71994000.,  71994000.,
+       72000000.,  72000000., 36006000.,  72000000.,  72000000.,
+      144012000., 144012000., 72030000., 144012000., 144012000.,
+       72000000.,  72000000., 36006000.,  72000000.,  72000000.,
+         499501.,    499501.,   499501.,    499501.,    499501.,
+        1000002.,   1000002.,  1000002.,   1000002.,   1000002.,
+         499501.,    499501.,   499501.,    499501.,    499501.,
+           1001.,      1001.,     1001.,      1001.,      1001.,
+           3002.,      3002.,     3002.,      3002.,      3002.,
+           1001.,      1001.,     1001.,      1001.,      1001.,
+            501.,       501.,      501.,       501.,       501.,
+           1502.,      1502.,     1502.,      1502.,      1502.
+    };
+
+    double[] res = new double[ntests];
+    for (int i = 0; i < ntests; i++) {
+      res[i] = 0.;
+    }
+
+
+    for (int i = 0; i < 12000; i++) {
+      res[0] += simple(i);
+      res[1] += simpleb(i);
+      res[2] += simplec();
+      res[3] += simplef(i);
+      res[4] += simplep((double)i);
+
+      res[5] += simple2((double)i);
+      res[6] += simpleb2((double)i);
+      res[7] += simplec2((double)i);
+      res[8] += simplem2((double)i);
+      res[9] += simplep2((double)i, (double)i);
+
+      res[10] += simple_deop((double)i);
+      res[11] += simpleb_deop((double)i);
+      res[12] += simplec_deop((double)i);
+      res[13] += simplef_deop((double)i);
+      res[14] += simplep_deop((double)i);
+
+      res[15] += test((double)i, i);
+      res[16] += testb((double)i, i);
+      res[17] += testc((double)i, i);
+      res[18] += testm((double)i, i);
+      res[19] += testp((double)i, i, (double)i);
+
+      res[20] += test2((double)i, i);
+      res[21] += testb2((double)i, i);
+      res[22] += testc2((double)i, i);
+      res[23] += testm2((double)i, i);
+      res[24] += testp2((double)i, i, (double)i);
+
+      res[25] += test_deop((double)i, i);
+      res[26] += testb_deop((double)i, i);
+      res[27] += testc_deop((double)i, i);
+      res[28] += testf_deop((double)i, i);
+      res[29] += testp_deop((double)i, i, (double)i);
+    }
+
+    double[] ia = new double[1000];
+    for (int i = 0; i < 1000; i++) {
+      ia[i] = i;
+    }
+
+    for (int i = 0; i < 100; i++) {
+      res[30] = sum(ia);
+      res[31] = sumb(ia);
+      res[32] = sumc(ia);
+      res[33] = sumf(ia);
+      res[34] = sump(ia, 1.);
+
+      res[35] = sum2(ia);
+      res[36] = sumb2(ia);
+      res[37] = sumc2(ia);
+      res[38] = summ2(ia);
+      res[39] = sump2(ia, 1.);
+
+      res[40] = sum_deop(ia);
+      res[41] = sumb_deop(ia);
+      res[42] = sumc_deop(ia);
+      res[43] = sumf_deop(ia);
+      res[44] = sump_deop(ia, 1.);
+
+      res[45] = remi_sum();
+      res[46] = remi_sumb();
+      res[47] = remi_sumc();
+      res[48] = remi_sumf();
+      res[49] = remi_sump(1.);
+
+      res[50] = remi_sum2();
+      res[51] = remi_sumb2();
+      res[52] = remi_sumc2();
+      res[53] = remi_summ2();
+      res[54] = remi_sump2(1.);
+
+      res[55] = remi_sum_deop();
+      res[56] = remi_sumb_deop();
+      res[57] = remi_sumc_deop();
+      res[58] = remi_sumf_deop();
+      res[59] = remi_sump_deop(1.);
+
+      res[60] = remi_sum_cond();
+      res[61] = remi_sumb_cond();
+      res[62] = remi_sumc_cond();
+      res[63] = remi_sumf_cond();
+      res[64] = remi_sump_cond(1.);
+
+      res[65] = remi_sum2_cond();
+      res[66] = remi_sumb2_cond();
+      res[67] = remi_sumc2_cond();
+      res[68] = remi_summ2_cond();
+      res[69] = remi_sump2_cond(1.);
+    }
+
+    int failed = 0;
+    for (int i = 0; i < ntests; i++) {
+      if (res[i] != val[i]) {
+        System.err.println(test_name[i] + ": " + res[i] + " != " + val[i]);
+        failed++;
+      }
+    }
+    if (failed > 0) {
+      System.err.println("Failed " + failed + " tests.");
+      throw new InternalError();
+    } else {
+      System.out.println("Passed.");
+    }
+  }
+}
diff --git a/hotspot/test/compiler/6934604/TestFloatBoxing.java b/hotspot/test/compiler/6934604/TestFloatBoxing.java
new file mode 100644
index 0000000..4571673
--- /dev/null
+++ b/hotspot/test/compiler/6934604/TestFloatBoxing.java
@@ -0,0 +1,777 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6934604
+ * @summary enable parts of EliminateAutoBox by default
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox TestFloatBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestFloatBoxing.dummy -XX:CompileCommand=exclude,TestFloatBoxing.foo -XX:CompileCommand=exclude,TestFloatBoxing.foob TestFloatBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestFloatBoxing.dummy -XX:CompileCommand=exclude,TestFloatBoxing.foo -XX:CompileCommand=exclude,TestFloatBoxing.foob TestFloatBoxing
+ *
+ */
+
+public class TestFloatBoxing {
+
+  static final Float ibc = new Float(1.f);
+
+  //===============================================
+  // Non-inlined methods to test deoptimization info
+  static void  dummy()       { }
+  static float foo(float i)  { return i; }
+  static Float foob(float i) { return Float.valueOf(i); }
+
+
+  static float simple(float i) {
+    Float ib = new Float(i);
+    return ib;
+  }
+
+  static float simpleb(float i) {
+    Float ib = Float.valueOf(i);
+    return ib;
+  }
+
+  static float simplec() {
+    Float ib = ibc;
+    return ib;
+  }
+
+  static float simplef(float i) {
+    Float ib = foob(i);
+    return ib;
+  }
+
+  static float simplep(Float ib) {
+    return ib;
+  }
+
+  static float simple2(float i) {
+    Float ib1 = new Float(i);
+    Float ib2 = new Float(i+1.f);
+    return ib1 + ib2;
+  }
+
+  static float simpleb2(float i) {
+    Float ib1 = Float.valueOf(i);
+    Float ib2 = Float.valueOf(i+1.f);
+    return ib1 + ib2;
+  }
+
+  static float simplem2(float i) {
+    Float ib1 = new Float(i);
+    Float ib2 = Float.valueOf(i+1.f);
+    return ib1 + ib2;
+  }
+
+  static float simplep2(float i, Float ib1) {
+    Float ib2 = Float.valueOf(i+1.f);
+    return ib1 + ib2;
+  }
+
+  static float simplec2(float i) {
+    Float ib1 = ibc;
+    Float ib2 = Float.valueOf(i+1.f);
+    return ib1 + ib2;
+  }
+
+  //===============================================
+  static float test(float f, int i) {
+    Float ib = new Float(f);
+    if ((i&1) == 0)
+      ib = f+1.f;
+    return ib;
+  }
+
+  static float testb(float f, int i) {
+    Float ib = f;
+    if ((i&1) == 0)
+      ib = (f+1.f);
+    return ib;
+  }
+
+  static float testm(float f, int i) {
+    Float ib = f;
+    if ((i&1) == 0)
+      ib = new Float(f+1.f);
+    return ib;
+  }
+
+  static float testp(float f, int i, Float ib) {
+    if ((i&1) == 0)
+      ib = new Float(f+1.f);
+    return ib;
+  }
+
+  static float testc(float f, int i) {
+    Float ib = ibc;
+    if ((i&1) == 0)
+      ib = new Float(f+1.f);
+    return ib;
+  }
+
+  static float test2(float f, int i) {
+    Float ib1 = new Float(f);
+    Float ib2 = new Float(f+1.f);
+    if ((i&1) == 0) {
+      ib1 = new Float(f+1.f);
+      ib2 = new Float(f+2.f);
+    }
+    return ib1+ib2;
+  }
+
+  static float testb2(float f, int i) {
+    Float ib1 = f;
+    Float ib2 = f+1.f;
+    if ((i&1) == 0) {
+      ib1 = (f+1.f);
+      ib2 = (f+2.f);
+    }
+    return ib1+ib2;
+  }
+
+  static float testm2(float f, int i) {
+    Float ib1 = new Float(f);
+    Float ib2 = f+1.f;
+    if ((i&1) == 0) {
+      ib1 = new Float(f+1.f);
+      ib2 = (f+2.f);
+    }
+    return ib1+ib2;
+  }
+
+  static float testp2(float f, int i, Float ib1) {
+    Float ib2 = f+1.f;
+    if ((i&1) == 0) {
+      ib1 = new Float(f+1.f);
+      ib2 = (f+2.f);
+    }
+    return ib1+ib2;
+  }
+
+  static float testc2(float f, int i) {
+    Float ib1 = ibc;
+    Float ib2 = f+1.f;
+    if ((i&1) == 0) {
+      ib1 = (ibc+1.f);
+      ib2 = (f+2.f);
+    }
+    return ib1+ib2;
+  }
+
+  //===============================================
+  static float sum(float[] a) {
+    float result = 1.f;
+    for (Float i : a)
+        result += i;
+    return result;
+  }
+
+  static float sumb(float[] a) {
+    Float result = 1.f;
+    for (Float i : a)
+        result += i;
+    return result;
+  }
+
+  static float sumc(float[] a) {
+    Float result = ibc;
+    for (Float i : a)
+        result += i;
+    return result;
+  }
+
+  static float sumf(float[] a) {
+    Float result = foob(1.f);
+    for (Float i : a)
+        result += i;
+    return result;
+  }
+
+  static float sump(float[] a, Float result) {
+    for (Float i : a)
+        result += i;
+    return result;
+  }
+
+  static float sum2(float[] a) {
+    float result1 = 1.f;
+    float result2 = 1.f;
+    for (Float i : a) {
+        result1 += i;
+        result2 += i + 1.f;
+    }
+    return result1 + result2;
+  }
+
+  static float sumb2(float[] a) {
+    Float result1 = 1.f;
+    Float result2 = 1.f;
+    for (Float i : a) {
+        result1 += i;
+        result2 += i + 1.f;
+    }
+    return result1 + result2;
+  }
+
+  static float summ2(float[] a) {
+    Float result1 = 1.f;
+    Float result2 = new Float(1.f);
+    for (Float i : a) {
+        result1 += i;
+        result2 += new Float(i + 1.f);
+    }
+    return result1 + result2;
+  }
+
+  static float sump2(float[] a, Float result2) {
+    Float result1 = 1.f;
+    for (Float i : a) {
+        result1 += i;
+        result2 += i + 1.f;
+    }
+    return result1 + result2;
+  }
+
+  static float sumc2(float[] a) {
+    Float result1 = 1.f;
+    Float result2 = ibc;
+    for (Float i : a) {
+        result1 += i;
+        result2 += i + ibc;
+    }
+    return result1 + result2;
+  }
+
+  //===============================================
+  static float remi_sum() {
+    Float j = new Float(1.f);
+    for (int i = 0; i< 1000; i++) {
+      j = new Float(j + 1.f);
+    }
+    return j;
+  }
+
+  static float remi_sumb() {
+    Float j = Float.valueOf(1.f);
+    for (int i = 0; i< 1000; i++) {
+      j = j + 1.f;
+    }
+    return j;
+  }
+
+  static float remi_sumf() {
+    Float j = foob(1.f);
+    for (int i = 0; i< 1000; i++) {
+      j = j + 1.f;
+    }
+    return j;
+  }
+
+  static float remi_sump(Float j) {
+    for (int i = 0; i< 1000; i++) {
+      j = new Float(j + 1.f);
+    }
+    return j;
+  }
+
+  static float remi_sumc() {
+    Float j = ibc;
+    for (int i = 0; i< 1000; i++) {
+      j = j + ibc;
+    }
+    return j;
+  }
+
+  static float remi_sum2() {
+    Float j1 = new Float(1.f);
+    Float j2 = new Float(1.f);
+    for (int i = 0; i< 1000; i++) {
+      j1 = new Float(j1 + 1.f);
+      j2 = new Float(j2 + 2.f);
+    }
+    return j1 + j2;
+  }
+
+  static float remi_sumb2() {
+    Float j1 = Float.valueOf(1.f);
+    Float j2 = Float.valueOf(1.f);
+    for (int i = 0; i< 1000; i++) {
+      j1 = j1 + 1.f;
+      j2 = j2 + 2.f;
+    }
+    return j1 + j2;
+  }
+
+  static float remi_summ2() {
+    Float j1 = new Float(1.f);
+    Float j2 = Float.valueOf(1.f);
+    for (int i = 0; i< 1000; i++) {
+      j1 = new Float(j1 + 1.f);
+      j2 = j2 + 2.f;
+    }
+    return j1 + j2;
+  }
+
+  static float remi_sump2(Float j1) {
+    Float j2 = Float.valueOf(1.f);
+    for (int i = 0; i< 1000; i++) {
+      j1 = new Float(j1 + 1.f);
+      j2 = j2 + 2.f;
+    }
+    return j1 + j2;
+  }
+
+  static float remi_sumc2() {
+    Float j1 = ibc;
+    Float j2 = Float.valueOf(1.f);
+    for (int i = 0; i< 1000; i++) {
+      j1 = j1 + ibc;
+      j2 = j2 + 2.f;
+    }
+    return j1 + j2;
+  }
+
+
+  //===============================================
+  // Safepointa and debug info for deoptimization
+  static float simple_deop(float i) {
+    Float ib = new Float(foo(i));
+    dummy();
+    return ib;
+  }
+
+  static float simpleb_deop(float i) {
+    Float ib = Float.valueOf(foo(i));
+    dummy();
+    return ib;
+  }
+
+  static float simplef_deop(float i) {
+    Float ib = foob(i);
+    dummy();
+    return ib;
+  }
+
+  static float simplep_deop(Float ib) {
+    dummy();
+    return ib;
+  }
+
+  static float simplec_deop(float i) {
+    Float ib = ibc;
+    dummy();
+    return ib;
+  }
+
+  static float test_deop(float f, int i) {
+    Float ib = new Float(foo(f));
+    if ((i&1) == 0)
+      ib = foo(f+1.f);
+    dummy();
+    return ib;
+  }
+
+  static float testb_deop(float f, int i) {
+    Float ib = foo(f);
+    if ((i&1) == 0)
+      ib = foo(f+1.f);
+    dummy();
+    return ib;
+  }
+
+  static float testf_deop(float f, int i) {
+    Float ib = foob(f);
+    if ((i&1) == 0)
+      ib = foo(f+1.f);
+    dummy();
+    return ib;
+  }
+
+  static float testp_deop(float f, int i, Float ib) {
+    if ((i&1) == 0)
+      ib = foo(f+1.f);
+    dummy();
+    return ib;
+  }
+
+  static float testc_deop(float f, int i) {
+    Float ib = ibc;
+    if ((i&1) == 0)
+      ib = foo(f+1.f);
+    dummy();
+    return ib;
+  }
+
+  static float sum_deop(float[] a) {
+    float result = 1.f;
+    for (Float i : a)
+        result += foo(i);
+    dummy();
+    return result;
+  }
+
+  static float sumb_deop(float[] a) {
+    Float result = 1.f;
+    for (Float i : a)
+        result += foo(i);
+    dummy();
+    return result;
+  }
+
+  static float sumf_deop(float[] a) {
+    Float result = 1.f;
+    for (Float i : a)
+        result += foob(i);
+    dummy();
+    return result;
+  }
+
+  static float sump_deop(float[] a, Float result) {
+    for (Float i : a)
+        result += foob(i);
+    dummy();
+    return result;
+  }
+
+  static float sumc_deop(float[] a) {
+    Float result = ibc;
+    for (Float i : a)
+        result += foo(i);
+    dummy();
+    return result;
+  }
+
+  static float remi_sum_deop() {
+    Float j = new Float(foo(1.f));
+    for (int i = 0; i< 1000; i++) {
+      j = new Float(foo(j + 1.f));
+    }
+    dummy();
+    return j;
+  }
+
+  static float remi_sumb_deop() {
+    Float j = Float.valueOf(foo(1.f));
+    for (int i = 0; i< 1000; i++) {
+      j = foo(j + 1.f);
+    }
+    dummy();
+    return j;
+  }
+
+  static float remi_sumf_deop() {
+    Float j = foob(1.f);
+    for (int i = 0; i< 1000; i++) {
+      j = foo(j + 1.f);
+    }
+    dummy();
+    return j;
+  }
+
+  static float remi_sump_deop(Float j) {
+    for (int i = 0; i< 1000; i++) {
+      j = foo(j + 1.f);
+    }
+    dummy();
+    return j;
+  }
+
+  static float remi_sumc_deop() {
+    Float j = ibc;
+    for (int i = 0; i< 1000; i++) {
+      j = foo(j + 1.f);
+    }
+    dummy();
+    return j;
+  }
+
+  //===============================================
+  // Conditional increment
+  static float remi_sum_cond() {
+    Float j = new Float(1.f);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = new Float(j + 1.f);
+      }
+    }
+    return j;
+  }
+
+  static float remi_sumb_cond() {
+    Float j = Float.valueOf(1.f);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = j + 1.f;
+      }
+    }
+    return j;
+  }
+
+  static float remi_sumf_cond() {
+    Float j = foob(1.f);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = j + 1.f;
+      }
+    }
+    return j;
+  }
+
+  static float remi_sump_cond(Float j) {
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = j + 1.f;
+      }
+    }
+    return j;
+  }
+
+  static float remi_sumc_cond() {
+    Float j = ibc;
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = j + ibc;
+      }
+    }
+    return j;
+  }
+
+  static float remi_sum2_cond() {
+    Float j1 = new Float(1.f);
+    Float j2 = new Float(1.f);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = new Float(j1 + 1.f);
+      } else {
+        j2 = new Float(j2 + 2.f);
+      }
+    }
+    return j1 + j2;
+  }
+
+  static float remi_sumb2_cond() {
+    Float j1 = Float.valueOf(1.f);
+    Float j2 = Float.valueOf(1.f);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = j1 + 1.f;
+      } else {
+        j2 = j2 + 2.f;
+      }
+    }
+    return j1 + j2;
+  }
+
+  static float remi_summ2_cond() {
+    Float j1 = new Float(1.f);
+    Float j2 = Float.valueOf(1.f);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = new Float(j1 + 1.f);
+      } else {
+        j2 = j2 + 2.f;
+      }
+    }
+    return j1 + j2;
+  }
+
+  static float remi_sump2_cond(Float j1) {
+    Float j2 = Float.valueOf(1.f);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = new Float(j1 + 1.f);
+      } else {
+        j2 = j2 + 2.f;
+      }
+    }
+    return j1 + j2;
+  }
+
+  static float remi_sumc2_cond() {
+    Float j1 = ibc;
+    Float j2 = Float.valueOf(1.f);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = j1 + ibc;
+      } else {
+        j2 = j2 + 2;
+      }
+    }
+    return j1 + j2;
+  }
+
+
+  public static void main(String[] args) {
+    final int ntests = 70;
+
+    String[] test_name = new String[] {
+        "simple",      "simpleb",      "simplec",      "simplef",      "simplep",
+        "simple2",     "simpleb2",     "simplec2",     "simplem2",     "simplep2",
+        "simple_deop", "simpleb_deop", "simplec_deop", "simplef_deop", "simplep_deop",
+        "test",        "testb",        "testc",        "testm",        "testp",
+        "test2",       "testb2",       "testc2",       "testm2",       "testp2",
+        "test_deop",   "testb_deop",   "testc_deop",   "testf_deop",   "testp_deop",
+        "sum",         "sumb",         "sumc",         "sumf",         "sump",
+        "sum2",        "sumb2",        "sumc2",        "summ2",        "sump2",
+        "sum_deop",    "sumb_deop",    "sumc_deop",    "sumf_deop",    "sump_deop",
+        "remi_sum",       "remi_sumb",       "remi_sumc",       "remi_sumf",       "remi_sump",
+        "remi_sum2",      "remi_sumb2",      "remi_sumc2",      "remi_summ2",      "remi_sump2",
+        "remi_sum_deop",  "remi_sumb_deop",  "remi_sumc_deop",  "remi_sumf_deop",  "remi_sump_deop",
+        "remi_sum_cond",  "remi_sumb_cond",  "remi_sumc_cond",  "remi_sumf_cond",  "remi_sump_cond",
+        "remi_sum2_cond", "remi_sumb2_cond", "remi_sumc2_cond", "remi_summ2_cond", "remi_sump2_cond"
+    };
+
+    final float[] val = new float[] {
+       71990896.f,  71990896.f,    12000.f,  71990896.f,  71990896.f,
+      144000000.f, 144000000.f, 72014896.f, 144000000.f, 144000000.f,
+       71990896.f,  71990896.f,    12000.f,  71990896.f,  71990896.f,
+       72000000.f,  72000000.f, 36004096.f,  72000000.f,  72000000.f,
+      144012288.f, 144012288.f, 72033096.f, 144012288.f, 144012288.f,
+       72000000.f,  72000000.f, 36004096.f,  72000000.f,  72000000.f,
+         499501.f,    499501.f,   499501.f,    499501.f,    499501.f,
+        1000002.f,   1000002.f,  1000002.f,   1000002.f,   1000002.f,
+         499501.f,    499501.f,   499501.f,    499501.f,    499501.f,
+           1001.f,      1001.f,     1001.f,      1001.f,      1001.f,
+           3002.f,      3002.f,     3002.f,      3002.f,      3002.f,
+           1001.f,      1001.f,     1001.f,      1001.f,      1001.f,
+            501.f,       501.f,      501.f,       501.f,       501.f,
+           1502.f,      1502.f,     1502.f,      1502.f,      1502.f
+    };
+
+    float[] res = new float[ntests];
+    for (int i = 0; i < ntests; i++) {
+      res[i] = 0.f;
+    }
+
+
+    for (int i = 0; i < 12000; i++) {
+      res[0] += simple(i);
+      res[1] += simpleb(i);
+      res[2] += simplec();
+      res[3] += simplef(i);
+      res[4] += simplep((float)i);
+
+      res[5] += simple2((float)i);
+      res[6] += simpleb2((float)i);
+      res[7] += simplec2((float)i);
+      res[8] += simplem2((float)i);
+      res[9] += simplep2((float)i, (float)i);
+
+      res[10] += simple_deop((float)i);
+      res[11] += simpleb_deop((float)i);
+      res[12] += simplec_deop((float)i);
+      res[13] += simplef_deop((float)i);
+      res[14] += simplep_deop((float)i);
+
+      res[15] += test((float)i, i);
+      res[16] += testb((float)i, i);
+      res[17] += testc((float)i, i);
+      res[18] += testm((float)i, i);
+      res[19] += testp((float)i, i, (float)i);
+
+      res[20] += test2((float)i, i);
+      res[21] += testb2((float)i, i);
+      res[22] += testc2((float)i, i);
+      res[23] += testm2((float)i, i);
+      res[24] += testp2((float)i, i, (float)i);
+
+      res[25] += test_deop((float)i, i);
+      res[26] += testb_deop((float)i, i);
+      res[27] += testc_deop((float)i, i);
+      res[28] += testf_deop((float)i, i);
+      res[29] += testp_deop((float)i, i, (float)i);
+    }
+
+    float[] ia = new float[1000];
+    for (int i = 0; i < 1000; i++) {
+      ia[i] = i;
+    }
+
+    for (int i = 0; i < 100; i++) {
+      res[30] = sum(ia);
+      res[31] = sumb(ia);
+      res[32] = sumc(ia);
+      res[33] = sumf(ia);
+      res[34] = sump(ia, 1.f);
+
+      res[35] = sum2(ia);
+      res[36] = sumb2(ia);
+      res[37] = sumc2(ia);
+      res[38] = summ2(ia);
+      res[39] = sump2(ia, 1.f);
+
+      res[40] = sum_deop(ia);
+      res[41] = sumb_deop(ia);
+      res[42] = sumc_deop(ia);
+      res[43] = sumf_deop(ia);
+      res[44] = sump_deop(ia, 1.f);
+
+      res[45] = remi_sum();
+      res[46] = remi_sumb();
+      res[47] = remi_sumc();
+      res[48] = remi_sumf();
+      res[49] = remi_sump(1.f);
+
+      res[50] = remi_sum2();
+      res[51] = remi_sumb2();
+      res[52] = remi_sumc2();
+      res[53] = remi_summ2();
+      res[54] = remi_sump2(1.f);
+
+      res[55] = remi_sum_deop();
+      res[56] = remi_sumb_deop();
+      res[57] = remi_sumc_deop();
+      res[58] = remi_sumf_deop();
+      res[59] = remi_sump_deop(1.f);
+
+      res[60] = remi_sum_cond();
+      res[61] = remi_sumb_cond();
+      res[62] = remi_sumc_cond();
+      res[63] = remi_sumf_cond();
+      res[64] = remi_sump_cond(1.f);
+
+      res[65] = remi_sum2_cond();
+      res[66] = remi_sumb2_cond();
+      res[67] = remi_sumc2_cond();
+      res[68] = remi_summ2_cond();
+      res[69] = remi_sump2_cond(1.f);
+    }
+
+    int failed = 0;
+    for (int i = 0; i < ntests; i++) {
+      if (res[i] != val[i]) {
+        System.err.println(test_name[i] + ": " + res[i] + " != " + val[i]);
+        failed++;
+      }
+    }
+    if (failed > 0) {
+      System.err.println("Failed " + failed + " tests.");
+      throw new InternalError();
+    } else {
+      System.out.println("Passed.");
+    }
+  }
+}
diff --git a/hotspot/test/compiler/6934604/TestIntBoxing.java b/hotspot/test/compiler/6934604/TestIntBoxing.java
new file mode 100644
index 0000000..d1ad10b
--- /dev/null
+++ b/hotspot/test/compiler/6934604/TestIntBoxing.java
@@ -0,0 +1,777 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6934604
+ * @summary enable parts of EliminateAutoBox by default
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox TestIntBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestIntBoxing.dummy -XX:CompileCommand=exclude,TestIntBoxing.foo -XX:CompileCommand=exclude,TestIntBoxing.foob TestIntBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestIntBoxing.dummy -XX:CompileCommand=exclude,TestIntBoxing.foo -XX:CompileCommand=exclude,TestIntBoxing.foob TestIntBoxing
+ *
+ */
+
+public class TestIntBoxing {
+
+  static final Integer ibc = new Integer(1);
+
+  //===============================================
+  // Non-inlined methods to test deoptimization info
+  static void    dummy()     { }
+  static int     foo(int i)  { return i; }
+  static Integer foob(int i) { return Integer.valueOf(i); }
+
+
+  static int simple(int i) {
+    Integer ib = new Integer(i);
+    return ib;
+  }
+
+  static int simpleb(int i) {
+    Integer ib = Integer.valueOf(i);
+    return ib;
+  }
+
+  static int simplec() {
+    Integer ib = ibc;
+    return ib;
+  }
+
+  static int simplef(int i) {
+    Integer ib = foob(i);
+    return ib;
+  }
+
+  static int simplep(Integer ib) {
+    return ib;
+  }
+
+  static int simple2(int i) {
+    Integer ib1 = new Integer(i);
+    Integer ib2 = new Integer(i+1);
+    return ib1 + ib2;
+  }
+
+  static int simpleb2(int i) {
+    Integer ib1 = Integer.valueOf(i);
+    Integer ib2 = Integer.valueOf(i+1);
+    return ib1 + ib2;
+  }
+
+  static int simplem2(int i) {
+    Integer ib1 = new Integer(i);
+    Integer ib2 = Integer.valueOf(i+1);
+    return ib1 + ib2;
+  }
+
+  static int simplep2(int i, Integer ib1) {
+    Integer ib2 = Integer.valueOf(i+1);
+    return ib1 + ib2;
+  }
+
+  static int simplec2(int i) {
+    Integer ib1 = ibc;
+    Integer ib2 = Integer.valueOf(i+1);
+    return ib1 + ib2;
+  }
+
+  //===============================================
+  static int test(int i) {
+    Integer ib = new Integer(i);
+    if ((i&1) == 0)
+      ib = i+1;
+    return ib;
+  }
+
+  static int testb(int i) {
+    Integer ib = i;
+    if ((i&1) == 0)
+      ib = (i+1);
+    return ib;
+  }
+
+  static int testm(int i) {
+    Integer ib = i;
+    if ((i&1) == 0)
+      ib = new Integer(i+1);
+    return ib;
+  }
+
+  static int testp(int i, Integer ib) {
+    if ((i&1) == 0)
+      ib = new Integer(i+1);
+    return ib;
+  }
+
+  static int testc(int i) {
+    Integer ib = ibc;
+    if ((i&1) == 0)
+      ib = new Integer(i+1);
+    return ib;
+  }
+
+  static int test2(int i) {
+    Integer ib1 = new Integer(i);
+    Integer ib2 = new Integer(i+1);
+    if ((i&1) == 0) {
+      ib1 = new Integer(i+1);
+      ib2 = new Integer(i+2);
+    }
+    return ib1+ib2;
+  }
+
+  static int testb2(int i) {
+    Integer ib1 = i;
+    Integer ib2 = i+1;
+    if ((i&1) == 0) {
+      ib1 = (i+1);
+      ib2 = (i+2);
+    }
+    return ib1+ib2;
+  }
+
+  static int testm2(int i) {
+    Integer ib1 = new Integer(i);
+    Integer ib2 = i+1;
+    if ((i&1) == 0) {
+      ib1 = new Integer(i+1);
+      ib2 = (i+2);
+    }
+    return ib1+ib2;
+  }
+
+  static int testp2(int i, Integer ib1) {
+    Integer ib2 = i+1;
+    if ((i&1) == 0) {
+      ib1 = new Integer(i+1);
+      ib2 = (i+2);
+    }
+    return ib1+ib2;
+  }
+
+  static int testc2(int i) {
+    Integer ib1 = ibc;
+    Integer ib2 = i+1;
+    if ((i&1) == 0) {
+      ib1 = (ibc+1);
+      ib2 = (i+2);
+    }
+    return ib1+ib2;
+  }
+
+  //===============================================
+  static int sum(int[] a) {
+    int result = 1;
+    for (Integer i : a)
+        result += i;
+    return result;
+  }
+
+  static int sumb(int[] a) {
+    Integer result = 1;
+    for (Integer i : a)
+        result += i;
+    return result;
+  }
+
+  static int sumc(int[] a) {
+    Integer result = ibc;
+    for (Integer i : a)
+        result += i;
+    return result;
+  }
+
+  static int sumf(int[] a) {
+    Integer result = foob(1);
+    for (Integer i : a)
+        result += i;
+    return result;
+  }
+
+  static int sump(int[] a, Integer result) {
+    for (Integer i : a)
+        result += i;
+    return result;
+  }
+
+  static int sum2(int[] a) {
+    int result1 = 1;
+    int result2 = 1;
+    for (Integer i : a) {
+        result1 += i;
+        result2 += i + 1;
+    }
+    return result1 + result2;
+  }
+
+  static int sumb2(int[] a) {
+    Integer result1 = 1;
+    Integer result2 = 1;
+    for (Integer i : a) {
+        result1 += i;
+        result2 += i + 1;
+    }
+    return result1 + result2;
+  }
+
+  static int summ2(int[] a) {
+    Integer result1 = 1;
+    Integer result2 = new Integer(1);
+    for (Integer i : a) {
+        result1 += i;
+        result2 += new Integer(i + 1);
+    }
+    return result1 + result2;
+  }
+
+  static int sump2(int[] a, Integer result2) {
+    Integer result1 = 1;
+    for (Integer i : a) {
+        result1 += i;
+        result2 += i + 1;
+    }
+    return result1 + result2;
+  }
+
+  static int sumc2(int[] a) {
+    Integer result1 = 1;
+    Integer result2 = ibc;
+    for (Integer i : a) {
+        result1 += i;
+        result2 += i + ibc;
+    }
+    return result1 + result2;
+  }
+
+  //===============================================
+  static int remi_sum() {
+    Integer j = new Integer(1);
+    for (int i = 0; i< 1000; i++) {
+      j = new Integer(j + 1);
+    }
+    return j;
+  }
+
+  static int remi_sumb() {
+    Integer j = Integer.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      j = j + 1;
+    }
+    return j;
+  }
+
+  static int remi_sumf() {
+    Integer j = foob(1);
+    for (int i = 0; i< 1000; i++) {
+      j = j + 1;
+    }
+    return j;
+  }
+
+  static int remi_sump(Integer j) {
+    for (int i = 0; i< 1000; i++) {
+      j = new Integer(j + 1);
+    }
+    return j;
+  }
+
+  static int remi_sumc() {
+    Integer j = ibc;
+    for (int i = 0; i< 1000; i++) {
+      j = j + ibc;
+    }
+    return j;
+  }
+
+  static int remi_sum2() {
+    Integer j1 = new Integer(1);
+    Integer j2 = new Integer(1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = new Integer(j1 + 1);
+      j2 = new Integer(j2 + 2);
+    }
+    return j1 + j2;
+  }
+
+  static int remi_sumb2() {
+    Integer j1 = Integer.valueOf(1);
+    Integer j2 = Integer.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = j1 + 1;
+      j2 = j2 + 2;
+    }
+    return j1 + j2;
+  }
+
+  static int remi_summ2() {
+    Integer j1 = new Integer(1);
+    Integer j2 = Integer.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = new Integer(j1 + 1);
+      j2 = j2 + 2;
+    }
+    return j1 + j2;
+  }
+
+  static int remi_sump2(Integer j1) {
+    Integer j2 = Integer.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = new Integer(j1 + 1);
+      j2 = j2 + 2;
+    }
+    return j1 + j2;
+  }
+
+  static int remi_sumc2() {
+    Integer j1 = ibc;
+    Integer j2 = Integer.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = j1 + ibc;
+      j2 = j2 + 2;
+    }
+    return j1 + j2;
+  }
+
+
+  //===============================================
+  // Safepointa and debug info for deoptimization
+  static int simple_deop(int i) {
+    Integer ib = new Integer(foo(i));
+    dummy();
+    return ib;
+  }
+
+  static int simpleb_deop(int i) {
+    Integer ib = Integer.valueOf(foo(i));
+    dummy();
+    return ib;
+  }
+
+  static int simplef_deop(int i) {
+    Integer ib = foob(i);
+    dummy();
+    return ib;
+  }
+
+  static int simplep_deop(Integer ib) {
+    dummy();
+    return ib;
+  }
+
+  static int simplec_deop(int i) {
+    Integer ib = ibc;
+    dummy();
+    return ib;
+  }
+
+  static int test_deop(int i) {
+    Integer ib = new Integer(foo(i));
+    if ((i&1) == 0)
+      ib = foo(i+1);
+    dummy();
+    return ib;
+  }
+
+  static int testb_deop(int i) {
+    Integer ib = foo(i);
+    if ((i&1) == 0)
+      ib = foo(i+1);
+    dummy();
+    return ib;
+  }
+
+  static int testf_deop(int i) {
+    Integer ib = foob(i);
+    if ((i&1) == 0)
+      ib = foo(i+1);
+    dummy();
+    return ib;
+  }
+
+  static int testp_deop(int i, Integer ib) {
+    if ((i&1) == 0)
+      ib = foo(i+1);
+    dummy();
+    return ib;
+  }
+
+  static int testc_deop(int i) {
+    Integer ib = ibc;
+    if ((i&1) == 0)
+      ib = foo(i+1);
+    dummy();
+    return ib;
+  }
+
+  static int sum_deop(int[] a) {
+    int result = 1;
+    for (Integer i : a)
+        result += foo(i);
+    dummy();
+    return result;
+  }
+
+  static int sumb_deop(int[] a) {
+    Integer result = 1;
+    for (Integer i : a)
+        result += foo(i);
+    dummy();
+    return result;
+  }
+
+  static int sumf_deop(int[] a) {
+    Integer result = 1;
+    for (Integer i : a)
+        result += foob(i);
+    dummy();
+    return result;
+  }
+
+  static int sump_deop(int[] a, Integer result) {
+    for (Integer i : a)
+        result += foob(i);
+    dummy();
+    return result;
+  }
+
+  static int sumc_deop(int[] a) {
+    Integer result = ibc;
+    for (Integer i : a)
+        result += foo(i);
+    dummy();
+    return result;
+  }
+
+  static int remi_sum_deop() {
+    Integer j = new Integer(foo(1));
+    for (int i = 0; i< 1000; i++) {
+      j = new Integer(foo(j + 1));
+    }
+    dummy();
+    return j;
+  }
+
+  static int remi_sumb_deop() {
+    Integer j = Integer.valueOf(foo(1));
+    for (int i = 0; i< 1000; i++) {
+      j = foo(j + 1);
+    }
+    dummy();
+    return j;
+  }
+
+  static int remi_sumf_deop() {
+    Integer j = foob(1);
+    for (int i = 0; i< 1000; i++) {
+      j = foo(j + 1);
+    }
+    dummy();
+    return j;
+  }
+
+  static int remi_sump_deop(Integer j) {
+    for (int i = 0; i< 1000; i++) {
+      j = foo(j + 1);
+    }
+    dummy();
+    return j;
+  }
+
+  static int remi_sumc_deop() {
+    Integer j = ibc;
+    for (int i = 0; i< 1000; i++) {
+      j = foo(j + 1);
+    }
+    dummy();
+    return j;
+  }
+
+  //===============================================
+  // Conditional increment
+  static int remi_sum_cond() {
+    Integer j = new Integer(1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = new Integer(j + 1);
+      }
+    }
+    return j;
+  }
+
+  static int remi_sumb_cond() {
+    Integer j = Integer.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = j + 1;
+      }
+    }
+    return j;
+  }
+
+  static int remi_sumf_cond() {
+    Integer j = foob(1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = j + 1;
+      }
+    }
+    return j;
+  }
+
+  static int remi_sump_cond(Integer j) {
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = j + 1;
+      }
+    }
+    return j;
+  }
+
+  static int remi_sumc_cond() {
+    Integer j = ibc;
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = j + ibc;
+      }
+    }
+    return j;
+  }
+
+  static int remi_sum2_cond() {
+    Integer j1 = new Integer(1);
+    Integer j2 = new Integer(1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = new Integer(j1 + 1);
+      } else {
+        j2 = new Integer(j2 + 2);
+      }
+    }
+    return j1 + j2;
+  }
+
+  static int remi_sumb2_cond() {
+    Integer j1 = Integer.valueOf(1);
+    Integer j2 = Integer.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = j1 + 1;
+      } else {
+        j2 = j2 + 2;
+      }
+    }
+    return j1 + j2;
+  }
+
+  static int remi_summ2_cond() {
+    Integer j1 = new Integer(1);
+    Integer j2 = Integer.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = new Integer(j1 + 1);
+      } else {
+        j2 = j2 + 2;
+      }
+    }
+    return j1 + j2;
+  }
+
+  static int remi_sump2_cond(Integer j1) {
+    Integer j2 = Integer.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = new Integer(j1 + 1);
+      } else {
+        j2 = j2 + 2;
+      }
+    }
+    return j1 + j2;
+  }
+
+  static int remi_sumc2_cond() {
+    Integer j1 = ibc;
+    Integer j2 = Integer.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = j1 + ibc;
+      } else {
+        j2 = j2 + 2;
+      }
+    }
+    return j1 + j2;
+  }
+
+
+  public static void main(String[] args) {
+    final int ntests = 70;
+
+    String[] test_name = new String[] {
+        "simple",      "simpleb",      "simplec",      "simplef",      "simplep",
+        "simple2",     "simpleb2",     "simplec2",     "simplem2",     "simplep2",
+        "simple_deop", "simpleb_deop", "simplec_deop", "simplef_deop", "simplep_deop",
+        "test",        "testb",        "testc",        "testm",        "testp",
+        "test2",       "testb2",       "testc2",       "testm2",       "testp2",
+        "test_deop",   "testb_deop",   "testc_deop",   "testf_deop",   "testp_deop",
+        "sum",         "sumb",         "sumc",         "sumf",         "sump",
+        "sum2",        "sumb2",        "sumc2",        "summ2",        "sump2",
+        "sum_deop",    "sumb_deop",    "sumc_deop",    "sumf_deop",    "sump_deop",
+        "remi_sum",       "remi_sumb",       "remi_sumc",       "remi_sumf",       "remi_sump",
+        "remi_sum2",      "remi_sumb2",      "remi_sumc2",      "remi_summ2",      "remi_sump2",
+        "remi_sum_deop",  "remi_sumb_deop",  "remi_sumc_deop",  "remi_sumf_deop",  "remi_sump_deop",
+        "remi_sum_cond",  "remi_sumb_cond",  "remi_sumc_cond",  "remi_sumf_cond",  "remi_sump_cond",
+        "remi_sum2_cond", "remi_sumb2_cond", "remi_sumc2_cond", "remi_summ2_cond", "remi_sump2_cond"
+    };
+
+    final int[] val = new int[] {
+       71994000,  71994000,    12000,  71994000,  71994000,
+      144000000, 144000000, 72018000, 144000000, 144000000,
+       71994000,  71994000,    12000,  71994000,  71994000,
+       72000000,  72000000, 36006000,  72000000,  72000000,
+      144012000, 144012000, 72030000, 144012000, 144012000,
+       72000000,  72000000, 36006000,  72000000,  72000000,
+         499501,    499501,   499501,    499501,    499501,
+        1000002,   1000002,  1000002,   1000002,   1000002,
+         499501,    499501,   499501,    499501,    499501,
+           1001,      1001,     1001,      1001,      1001,
+           3002,      3002,     3002,      3002,      3002,
+           1001,      1001,     1001,      1001,      1001,
+            501,       501,      501,       501,       501,
+           1502,      1502,     1502,      1502,      1502
+    };
+
+    int[] res = new int[ntests];
+    for (int i = 0; i < ntests; i++) {
+      res[i] = 0;
+    }
+
+
+    for (int i = 0; i < 12000; i++) {
+      res[0] += simple(i);
+      res[1] += simpleb(i);
+      res[2] += simplec();
+      res[3] += simplef(i);
+      res[4] += simplep(i);
+
+      res[5] += simple2(i);
+      res[6] += simpleb2(i);
+      res[7] += simplec2(i);
+      res[8] += simplem2(i);
+      res[9] += simplep2(i, i);
+
+      res[10] += simple_deop(i);
+      res[11] += simpleb_deop(i);
+      res[12] += simplec_deop(i);
+      res[13] += simplef_deop(i);
+      res[14] += simplep_deop(i);
+
+      res[15] += test(i);
+      res[16] += testb(i);
+      res[17] += testc(i);
+      res[18] += testm(i);
+      res[19] += testp(i, i);
+
+      res[20] += test2(i);
+      res[21] += testb2(i);
+      res[22] += testc2(i);
+      res[23] += testm2(i);
+      res[24] += testp2(i, i);
+
+      res[25] += test_deop(i);
+      res[26] += testb_deop(i);
+      res[27] += testc_deop(i);
+      res[28] += testf_deop(i);
+      res[29] += testp_deop(i, i);
+    }
+
+    int[] ia = new int[1000];
+    for (int i = 0; i < 1000; i++) {
+      ia[i] = i;
+    }
+
+    for (int i = 0; i < 100; i++) {
+      res[30] = sum(ia);
+      res[31] = sumb(ia);
+      res[32] = sumc(ia);
+      res[33] = sumf(ia);
+      res[34] = sump(ia, 1);
+
+      res[35] = sum2(ia);
+      res[36] = sumb2(ia);
+      res[37] = sumc2(ia);
+      res[38] = summ2(ia);
+      res[39] = sump2(ia, 1);
+
+      res[40] = sum_deop(ia);
+      res[41] = sumb_deop(ia);
+      res[42] = sumc_deop(ia);
+      res[43] = sumf_deop(ia);
+      res[44] = sump_deop(ia, 1);
+
+      res[45] = remi_sum();
+      res[46] = remi_sumb();
+      res[47] = remi_sumc();
+      res[48] = remi_sumf();
+      res[49] = remi_sump(1);
+
+      res[50] = remi_sum2();
+      res[51] = remi_sumb2();
+      res[52] = remi_sumc2();
+      res[53] = remi_summ2();
+      res[54] = remi_sump2(1);
+
+      res[55] = remi_sum_deop();
+      res[56] = remi_sumb_deop();
+      res[57] = remi_sumc_deop();
+      res[58] = remi_sumf_deop();
+      res[59] = remi_sump_deop(1);
+
+      res[60] = remi_sum_cond();
+      res[61] = remi_sumb_cond();
+      res[62] = remi_sumc_cond();
+      res[63] = remi_sumf_cond();
+      res[64] = remi_sump_cond(1);
+
+      res[65] = remi_sum2_cond();
+      res[66] = remi_sumb2_cond();
+      res[67] = remi_sumc2_cond();
+      res[68] = remi_summ2_cond();
+      res[69] = remi_sump2_cond(1);
+    }
+
+    int failed = 0;
+    for (int i = 0; i < ntests; i++) {
+      if (res[i] != val[i]) {
+        System.err.println(test_name[i] + ": " + res[i] + " != " + val[i]);
+        failed++;
+      }
+    }
+    if (failed > 0) {
+      System.err.println("Failed " + failed + " tests.");
+      throw new InternalError();
+    } else {
+      System.out.println("Passed.");
+    }
+  }
+}
diff --git a/hotspot/test/compiler/6934604/TestLongBoxing.java b/hotspot/test/compiler/6934604/TestLongBoxing.java
new file mode 100644
index 0000000..b92a01c
--- /dev/null
+++ b/hotspot/test/compiler/6934604/TestLongBoxing.java
@@ -0,0 +1,777 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6934604
+ * @summary enable parts of EliminateAutoBox by default
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox TestLongBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestLongBoxing.dummy -XX:CompileCommand=exclude,TestLongBoxing.foo -XX:CompileCommand=exclude,TestLongBoxing.foob TestLongBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestLongBoxing.dummy -XX:CompileCommand=exclude,TestLongBoxing.foo -XX:CompileCommand=exclude,TestLongBoxing.foob TestLongBoxing
+ *
+ */
+
+public class TestLongBoxing {
+
+  static final Long ibc = new Long(1);
+
+  //===============================================
+  // Non-inlined methods to test deoptimization info
+  static void dummy()     { }
+  static long  foo(long i)  { return i; }
+  static Long  foob(long i) { return Long.valueOf(i); }
+
+
+  static long simple(long i) {
+    Long ib = new Long(i);
+    return ib;
+  }
+
+  static long simpleb(long i) {
+    Long ib = Long.valueOf(i);
+    return ib;
+  }
+
+  static long simplec() {
+    Long ib = ibc;
+    return ib;
+  }
+
+  static long simplef(long i) {
+    Long ib = foob(i);
+    return ib;
+  }
+
+  static long simplep(Long ib) {
+    return ib;
+  }
+
+  static long simple2(long i) {
+    Long ib1 = new Long(i);
+    Long ib2 = new Long(i+1);
+    return ib1 + ib2;
+  }
+
+  static long simpleb2(long i) {
+    Long ib1 = Long.valueOf(i);
+    Long ib2 = Long.valueOf(i+1);
+    return ib1 + ib2;
+  }
+
+  static long simplem2(long i) {
+    Long ib1 = new Long(i);
+    Long ib2 = Long.valueOf(i+1);
+    return ib1 + ib2;
+  }
+
+  static long simplep2(long i, Long ib1) {
+    Long ib2 = Long.valueOf(i+1);
+    return ib1 + ib2;
+  }
+
+  static long simplec2(long i) {
+    Long ib1 = ibc;
+    Long ib2 = Long.valueOf(i+1);
+    return ib1 + ib2;
+  }
+
+  //===============================================
+  static long test(long i) {
+    Long ib = new Long(i);
+    if ((i&1) == 0)
+      ib = i+1;
+    return ib;
+  }
+
+  static long testb(long i) {
+    Long ib = i;
+    if ((i&1) == 0)
+      ib = (i+1);
+    return ib;
+  }
+
+  static long testm(long i) {
+    Long ib = i;
+    if ((i&1) == 0)
+      ib = new Long(i+1);
+    return ib;
+  }
+
+  static long testp(long i, Long ib) {
+    if ((i&1) == 0)
+      ib = new Long(i+1);
+    return ib;
+  }
+
+  static long testc(long i) {
+    Long ib = ibc;
+    if ((i&1) == 0)
+      ib = new Long(i+1);
+    return ib;
+  }
+
+  static long test2(long i) {
+    Long ib1 = new Long(i);
+    Long ib2 = new Long(i+1);
+    if ((i&1) == 0) {
+      ib1 = new Long(i+1);
+      ib2 = new Long(i+2);
+    }
+    return ib1+ib2;
+  }
+
+  static long testb2(long i) {
+    Long ib1 = i;
+    Long ib2 = i+1;
+    if ((i&1) == 0) {
+      ib1 = (i+1);
+      ib2 = (i+2);
+    }
+    return ib1+ib2;
+  }
+
+  static long testm2(long i) {
+    Long ib1 = new Long(i);
+    Long ib2 = i+1;
+    if ((i&1) == 0) {
+      ib1 = new Long(i+1);
+      ib2 = (i+2);
+    }
+    return ib1+ib2;
+  }
+
+  static long testp2(long i, Long ib1) {
+    Long ib2 = i+1;
+    if ((i&1) == 0) {
+      ib1 = new Long(i+1);
+      ib2 = (i+2);
+    }
+    return ib1+ib2;
+  }
+
+  static long testc2(long i) {
+    Long ib1 = ibc;
+    Long ib2 = i+1;
+    if ((i&1) == 0) {
+      ib1 = (ibc+1);
+      ib2 = (i+2);
+    }
+    return ib1+ib2;
+  }
+
+  //===============================================
+  static long sum(long[] a) {
+    long result = 1;
+    for (Long i : a)
+        result += i;
+    return result;
+  }
+
+  static long sumb(long[] a) {
+    Long result = 1l;
+    for (Long i : a)
+        result += i;
+    return result;
+  }
+
+  static long sumc(long[] a) {
+    Long result = ibc;
+    for (Long i : a)
+        result += i;
+    return result;
+  }
+
+  static long sumf(long[] a) {
+    Long result = foob(1);
+    for (Long i : a)
+        result += i;
+    return result;
+  }
+
+  static long sump(long[] a, Long result) {
+    for (Long i : a)
+        result += i;
+    return result;
+  }
+
+  static long sum2(long[] a) {
+    long result1 = 1;
+    long result2 = 1;
+    for (Long i : a) {
+        result1 += i;
+        result2 += i + 1;
+    }
+    return result1 + result2;
+  }
+
+  static long sumb2(long[] a) {
+    Long result1 = 1l;
+    Long result2 = 1l;
+    for (Long i : a) {
+        result1 += i;
+        result2 += i + 1;
+    }
+    return result1 + result2;
+  }
+
+  static long summ2(long[] a) {
+    Long result1 = 1l;
+    Long result2 = new Long(1);
+    for (Long i : a) {
+        result1 += i;
+        result2 += new Long(i + 1);
+    }
+    return result1 + result2;
+  }
+
+  static long sump2(long[] a, Long result2) {
+    Long result1 = 1l;
+    for (Long i : a) {
+        result1 += i;
+        result2 += i + 1;
+    }
+    return result1 + result2;
+  }
+
+  static long sumc2(long[] a) {
+    Long result1 = 1l;
+    Long result2 = ibc;
+    for (Long i : a) {
+        result1 += i;
+        result2 += i + ibc;
+    }
+    return result1 + result2;
+  }
+
+  //===============================================
+  static long remi_sum() {
+    Long j = new Long(1);
+    for (int i = 0; i< 1000; i++) {
+      j = new Long(j + 1);
+    }
+    return j;
+  }
+
+  static long remi_sumb() {
+    Long j = Long.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      j = j + 1;
+    }
+    return j;
+  }
+
+  static long remi_sumf() {
+    Long j = foob(1);
+    for (int i = 0; i< 1000; i++) {
+      j = j + 1;
+    }
+    return j;
+  }
+
+  static long remi_sump(Long j) {
+    for (int i = 0; i< 1000; i++) {
+      j = new Long(j + 1);
+    }
+    return j;
+  }
+
+  static long remi_sumc() {
+    Long j = ibc;
+    for (int i = 0; i< 1000; i++) {
+      j = j + ibc;
+    }
+    return j;
+  }
+
+  static long remi_sum2() {
+    Long j1 = new Long(1);
+    Long j2 = new Long(1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = new Long(j1 + 1);
+      j2 = new Long(j2 + 2);
+    }
+    return j1 + j2;
+  }
+
+  static long remi_sumb2() {
+    Long j1 = Long.valueOf(1);
+    Long j2 = Long.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = j1 + 1;
+      j2 = j2 + 2;
+    }
+    return j1 + j2;
+  }
+
+  static long remi_summ2() {
+    Long j1 = new Long(1);
+    Long j2 = Long.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = new Long(j1 + 1);
+      j2 = j2 + 2;
+    }
+    return j1 + j2;
+  }
+
+  static long remi_sump2(Long j1) {
+    Long j2 = Long.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = new Long(j1 + 1);
+      j2 = j2 + 2;
+    }
+    return j1 + j2;
+  }
+
+  static long remi_sumc2() {
+    Long j1 = ibc;
+    Long j2 = Long.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = j1 + ibc;
+      j2 = j2 + 2;
+    }
+    return j1 + j2;
+  }
+
+
+  //===============================================
+  // Safepointa and debug info for deoptimization
+  static long simple_deop(long i) {
+    Long ib = new Long(foo(i));
+    dummy();
+    return ib;
+  }
+
+  static long simpleb_deop(long i) {
+    Long ib = Long.valueOf(foo(i));
+    dummy();
+    return ib;
+  }
+
+  static long simplef_deop(long i) {
+    Long ib = foob(i);
+    dummy();
+    return ib;
+  }
+
+  static long simplep_deop(Long ib) {
+    dummy();
+    return ib;
+  }
+
+  static long simplec_deop(long i) {
+    Long ib = ibc;
+    dummy();
+    return ib;
+  }
+
+  static long test_deop(long i) {
+    Long ib = new Long(foo(i));
+    if ((i&1) == 0)
+      ib = foo(i+1);
+    dummy();
+    return ib;
+  }
+
+  static long testb_deop(long i) {
+    Long ib = foo(i);
+    if ((i&1) == 0)
+      ib = foo(i+1);
+    dummy();
+    return ib;
+  }
+
+  static long testf_deop(long i) {
+    Long ib = foob(i);
+    if ((i&1) == 0)
+      ib = foo(i+1);
+    dummy();
+    return ib;
+  }
+
+  static long testp_deop(long i, Long ib) {
+    if ((i&1) == 0)
+      ib = foo(i+1);
+    dummy();
+    return ib;
+  }
+
+  static long testc_deop(long i) {
+    Long ib = ibc;
+    if ((i&1) == 0)
+      ib = foo(i+1);
+    dummy();
+    return ib;
+  }
+
+  static long sum_deop(long[] a) {
+    long result = 1;
+    for (Long i : a)
+        result += foo(i);
+    dummy();
+    return result;
+  }
+
+  static long sumb_deop(long[] a) {
+    Long result = 1l;
+    for (Long i : a)
+        result += foo(i);
+    dummy();
+    return result;
+  }
+
+  static long sumf_deop(long[] a) {
+    Long result = 1l;
+    for (Long i : a)
+        result += foob(i);
+    dummy();
+    return result;
+  }
+
+  static long sump_deop(long[] a, Long result) {
+    for (Long i : a)
+        result += foob(i);
+    dummy();
+    return result;
+  }
+
+  static long sumc_deop(long[] a) {
+    Long result = ibc;
+    for (Long i : a)
+        result += foo(i);
+    dummy();
+    return result;
+  }
+
+  static long remi_sum_deop() {
+    Long j = new Long(foo(1));
+    for (int i = 0; i< 1000; i++) {
+      j = new Long(foo(j + 1));
+    }
+    dummy();
+    return j;
+  }
+
+  static long remi_sumb_deop() {
+    Long j = Long.valueOf(foo(1));
+    for (int i = 0; i< 1000; i++) {
+      j = foo(j + 1);
+    }
+    dummy();
+    return j;
+  }
+
+  static long remi_sumf_deop() {
+    Long j = foob(1);
+    for (int i = 0; i< 1000; i++) {
+      j = foo(j + 1);
+    }
+    dummy();
+    return j;
+  }
+
+  static long remi_sump_deop(Long j) {
+    for (int i = 0; i< 1000; i++) {
+      j = foo(j + 1);
+    }
+    dummy();
+    return j;
+  }
+
+  static long remi_sumc_deop() {
+    Long j = ibc;
+    for (int i = 0; i< 1000; i++) {
+      j = foo(j + 1);
+    }
+    dummy();
+    return j;
+  }
+
+  //===============================================
+  // Conditional increment
+  static long remi_sum_cond() {
+    Long j = new Long(1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = new Long(j + 1);
+      }
+    }
+    return j;
+  }
+
+  static long remi_sumb_cond() {
+    Long j = Long.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = j + 1;
+      }
+    }
+    return j;
+  }
+
+  static long remi_sumf_cond() {
+    Long j = foob(1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = j + 1;
+      }
+    }
+    return j;
+  }
+
+  static long remi_sump_cond(Long j) {
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = j + 1;
+      }
+    }
+    return j;
+  }
+
+  static long remi_sumc_cond() {
+    Long j = ibc;
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = j + ibc;
+      }
+    }
+    return j;
+  }
+
+  static long remi_sum2_cond() {
+    Long j1 = new Long(1);
+    Long j2 = new Long(1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = new Long(j1 + 1);
+      } else {
+        j2 = new Long(j2 + 2);
+      }
+    }
+    return j1 + j2;
+  }
+
+  static long remi_sumb2_cond() {
+    Long j1 = Long.valueOf(1);
+    Long j2 = Long.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = j1 + 1;
+      } else {
+        j2 = j2 + 2;
+      }
+    }
+    return j1 + j2;
+  }
+
+  static long remi_summ2_cond() {
+    Long j1 = new Long(1);
+    Long j2 = Long.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = new Long(j1 + 1);
+      } else {
+        j2 = j2 + 2;
+      }
+    }
+    return j1 + j2;
+  }
+
+  static long remi_sump2_cond(Long j1) {
+    Long j2 = Long.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = new Long(j1 + 1);
+      } else {
+        j2 = j2 + 2;
+      }
+    }
+    return j1 + j2;
+  }
+
+  static long remi_sumc2_cond() {
+    Long j1 = ibc;
+    Long j2 = Long.valueOf(1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = j1 + ibc;
+      } else {
+        j2 = j2 + 2;
+      }
+    }
+    return j1 + j2;
+  }
+
+
+  public static void main(String[] args) {
+    final int ntests = 70;
+
+    String[] test_name = new String[] {
+        "simple",      "simpleb",      "simplec",      "simplef",      "simplep",
+        "simple2",     "simpleb2",     "simplec2",     "simplem2",     "simplep2",
+        "simple_deop", "simpleb_deop", "simplec_deop", "simplef_deop", "simplep_deop",
+        "test",        "testb",        "testc",        "testm",        "testp",
+        "test2",       "testb2",       "testc2",       "testm2",       "testp2",
+        "test_deop",   "testb_deop",   "testc_deop",   "testf_deop",   "testp_deop",
+        "sum",         "sumb",         "sumc",         "sumf",         "sump",
+        "sum2",        "sumb2",        "sumc2",        "summ2",        "sump2",
+        "sum_deop",    "sumb_deop",    "sumc_deop",    "sumf_deop",    "sump_deop",
+        "remi_sum",       "remi_sumb",       "remi_sumc",       "remi_sumf",       "remi_sump",
+        "remi_sum2",      "remi_sumb2",      "remi_sumc2",      "remi_summ2",      "remi_sump2",
+        "remi_sum_deop",  "remi_sumb_deop",  "remi_sumc_deop",  "remi_sumf_deop",  "remi_sump_deop",
+        "remi_sum_cond",  "remi_sumb_cond",  "remi_sumc_cond",  "remi_sumf_cond",  "remi_sump_cond",
+        "remi_sum2_cond", "remi_sumb2_cond", "remi_sumc2_cond", "remi_summ2_cond", "remi_sump2_cond"
+    };
+
+    final long[] val = new long[] {
+       71994000,  71994000,    12000,  71994000,  71994000,
+      144000000, 144000000, 72018000, 144000000, 144000000,
+       71994000,  71994000,    12000,  71994000,  71994000,
+       72000000,  72000000, 36006000,  72000000,  72000000,
+      144012000, 144012000, 72030000, 144012000, 144012000,
+       72000000,  72000000, 36006000,  72000000,  72000000,
+         499501,    499501,   499501,    499501,    499501,
+        1000002,   1000002,  1000002,   1000002,   1000002,
+         499501,    499501,   499501,    499501,    499501,
+           1001,      1001,     1001,      1001,      1001,
+           3002,      3002,     3002,      3002,      3002,
+           1001,      1001,     1001,      1001,      1001,
+            501,       501,      501,       501,       501,
+           1502,      1502,     1502,      1502,      1502
+    };
+
+    long[] res = new long[ntests];
+    for (int i = 0; i < ntests; i++) {
+      res[i] = 0;
+    }
+
+
+    for (long i = 0; i < 12000; i++) {
+      res[0] += simple(i);
+      res[1] += simpleb(i);
+      res[2] += simplec();
+      res[3] += simplef(i);
+      res[4] += simplep(i);
+
+      res[5] += simple2(i);
+      res[6] += simpleb2(i);
+      res[7] += simplec2(i);
+      res[8] += simplem2(i);
+      res[9] += simplep2(i, i);
+
+      res[10] += simple_deop(i);
+      res[11] += simpleb_deop(i);
+      res[12] += simplec_deop(i);
+      res[13] += simplef_deop(i);
+      res[14] += simplep_deop(i);
+
+      res[15] += test(i);
+      res[16] += testb(i);
+      res[17] += testc(i);
+      res[18] += testm(i);
+      res[19] += testp(i, i);
+
+      res[20] += test2(i);
+      res[21] += testb2(i);
+      res[22] += testc2(i);
+      res[23] += testm2(i);
+      res[24] += testp2(i, i);
+
+      res[25] += test_deop(i);
+      res[26] += testb_deop(i);
+      res[27] += testc_deop(i);
+      res[28] += testf_deop(i);
+      res[29] += testp_deop(i, i);
+    }
+
+    long[] ia = new long[1000];
+    for (int i = 0; i < 1000; i++) {
+      ia[i] = i;
+    }
+
+    for (int i = 0; i < 100; i++) {
+      res[30] = sum(ia);
+      res[31] = sumb(ia);
+      res[32] = sumc(ia);
+      res[33] = sumf(ia);
+      res[34] = sump(ia, (long)1);
+
+      res[35] = sum2(ia);
+      res[36] = sumb2(ia);
+      res[37] = sumc2(ia);
+      res[38] = summ2(ia);
+      res[39] = sump2(ia, (long)1);
+
+      res[40] = sum_deop(ia);
+      res[41] = sumb_deop(ia);
+      res[42] = sumc_deop(ia);
+      res[43] = sumf_deop(ia);
+      res[44] = sump_deop(ia, (long)1);
+
+      res[45] = remi_sum();
+      res[46] = remi_sumb();
+      res[47] = remi_sumc();
+      res[48] = remi_sumf();
+      res[49] = remi_sump((long)1);
+
+      res[50] = remi_sum2();
+      res[51] = remi_sumb2();
+      res[52] = remi_sumc2();
+      res[53] = remi_summ2();
+      res[54] = remi_sump2((long)1);
+
+      res[55] = remi_sum_deop();
+      res[56] = remi_sumb_deop();
+      res[57] = remi_sumc_deop();
+      res[58] = remi_sumf_deop();
+      res[59] = remi_sump_deop((long)1);
+
+      res[60] = remi_sum_cond();
+      res[61] = remi_sumb_cond();
+      res[62] = remi_sumc_cond();
+      res[63] = remi_sumf_cond();
+      res[64] = remi_sump_cond((long)1);
+
+      res[65] = remi_sum2_cond();
+      res[66] = remi_sumb2_cond();
+      res[67] = remi_sumc2_cond();
+      res[68] = remi_summ2_cond();
+      res[69] = remi_sump2_cond((long)1);
+    }
+
+    int failed = 0;
+    for (int i = 0; i < ntests; i++) {
+      if (res[i] != val[i]) {
+        System.err.println(test_name[i] + ": " + res[i] + " != " + val[i]);
+        failed++;
+      }
+    }
+    if (failed > 0) {
+      System.err.println("Failed " + failed + " tests.");
+      throw new InternalError();
+    } else {
+      System.out.println("Passed.");
+    }
+  }
+}
diff --git a/hotspot/test/compiler/6934604/TestShortBoxing.java b/hotspot/test/compiler/6934604/TestShortBoxing.java
new file mode 100644
index 0000000..0f065af
--- /dev/null
+++ b/hotspot/test/compiler/6934604/TestShortBoxing.java
@@ -0,0 +1,777 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6934604
+ * @summary enable parts of EliminateAutoBox by default
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox TestShortBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestShortBoxing.dummy -XX:CompileCommand=exclude,TestShortBoxing.foo -XX:CompileCommand=exclude,TestShortBoxing.foob TestShortBoxing
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-EliminateAutoBox
+ * -XX:CompileCommand=exclude,TestShortBoxing.dummy -XX:CompileCommand=exclude,TestShortBoxing.foo -XX:CompileCommand=exclude,TestShortBoxing.foob TestShortBoxing
+ *
+ */
+
+public class TestShortBoxing {
+
+  static final Short ibc = new Short((short)1);
+
+  //===============================================
+  // Non-inlined methods to test deoptimization info
+  static void dummy()      { }
+  static short foo(short i)  { return i; }
+  static Short foob(short i) { return Short.valueOf(i); }
+
+
+  static short simple(short i) {
+    Short ib = new Short(i);
+    return ib;
+  }
+
+  static short simpleb(short i) {
+    Short ib = Short.valueOf(i);
+    return ib;
+  }
+
+  static short simplec() {
+    Short ib = ibc;
+    return ib;
+  }
+
+  static short simplef(short i) {
+    Short ib = foob(i);
+    return ib;
+  }
+
+  static short simplep(Short ib) {
+    return ib;
+  }
+
+  static short simple2(short i) {
+    Short ib1 = new Short(i);
+    Short ib2 = new Short((short)(i+1));
+    return (short)(ib1 + ib2);
+  }
+
+  static short simpleb2(short i) {
+    Short ib1 = Short.valueOf(i);
+    Short ib2 = Short.valueOf((short)(i+1));
+    return (short)(ib1 + ib2);
+  }
+
+  static short simplem2(short i) {
+    Short ib1 = new Short(i);
+    Short ib2 = Short.valueOf((short)(i+1));
+    return (short)(ib1 + ib2);
+  }
+
+  static short simplep2(short i, Short ib1) {
+    Short ib2 = Short.valueOf((short)(i+1));
+    return (short)(ib1 + ib2);
+  }
+
+  static short simplec2(short i) {
+    Short ib1 = ibc;
+    Short ib2 = Short.valueOf((short)(i+1));
+    return (short)(ib1 + ib2);
+  }
+
+  //===============================================
+  static short test(short i) {
+    Short ib = new Short(i);
+    if ((i&1) == 0)
+      ib = (short)(i+1);
+    return ib;
+  }
+
+  static short testb(short i) {
+    Short ib = i;
+    if ((i&1) == 0)
+      ib = (short)(i+1);
+    return ib;
+  }
+
+  static short testm(short i) {
+    Short ib = i;
+    if ((i&1) == 0)
+      ib = new Short((short)(i+1));
+    return ib;
+  }
+
+  static short testp(short i, Short ib) {
+    if ((i&1) == 0)
+      ib = new Short((short)(i+1));
+    return ib;
+  }
+
+  static short testc(short i) {
+    Short ib = ibc;
+    if ((i&1) == 0)
+      ib = new Short((short)(i+1));
+    return ib;
+  }
+
+  static short test2(short i) {
+    Short ib1 = new Short(i);
+    Short ib2 = new Short((short)(i+1));
+    if ((i&1) == 0) {
+      ib1 = new Short((short)(i+1));
+      ib2 = new Short((short)(i+2));
+    }
+    return (short)(ib1+ib2);
+  }
+
+  static short testb2(short i) {
+    Short ib1 = i;
+    Short ib2 = (short)(i+1);
+    if ((i&1) == 0) {
+      ib1 = (short)(i+1);
+      ib2 = (short)(i+2);
+    }
+    return (short)(ib1 + ib2);
+  }
+
+  static short testm2(short i) {
+    Short ib1 = new Short(i);
+    Short ib2 = (short)(i+1);
+    if ((i&1) == 0) {
+      ib1 = new Short((short)(i+1));
+      ib2 = (short)(i+2);
+    }
+    return (short)(ib1 + ib2);
+  }
+
+  static short testp2(short i, Short ib1) {
+    Short ib2 = (short)(i+1);
+    if ((i&1) == 0) {
+      ib1 = new Short((short)(i+1));
+      ib2 = (short)(i+2);
+    }
+    return (short)(ib1 + ib2);
+  }
+
+  static short testc2(short i) {
+    Short ib1 = ibc;
+    Short ib2 = (short)(i+1);
+    if ((i&1) == 0) {
+      ib1 = (short)(ibc+1);
+      ib2 = (short)(i+2);
+    }
+    return (short)(ib1 + ib2);
+  }
+
+  //===============================================
+  static short sum(short[] a) {
+    short result = 1;
+    for (Short i : a)
+        result += i;
+    return result;
+  }
+
+  static short sumb(short[] a) {
+    Short result = 1;
+    for (Short i : a)
+        result = (short)(result + i);
+    return result;
+  }
+
+  static short sumc(short[] a) {
+    Short result = ibc;
+    for (Short i : a)
+        result = (short)(result + i);
+    return result;
+  }
+
+  static short sumf(short[] a) {
+    Short result = foob((short)1);
+    for (Short i : a)
+        result = (short)(result + i);
+    return result;
+  }
+
+  static short sump(short[] a, Short result) {
+    for (Short i : a)
+        result = (short)(result + i);
+    return result;
+  }
+
+  static short sum2(short[] a) {
+    short result1 = 1;
+    short result2 = 1;
+    for (Short i : a) {
+        result1 += i;
+        result2 += i + 1;
+    }
+    return (short)(result1 + result2);
+  }
+
+  static short sumb2(short[] a) {
+    Short result1 = 1;
+    Short result2 = 1;
+    for (Short i : a) {
+        result1 = (short)(result1 + i);
+        result2 = (short)(result2 + i + 1);
+    }
+    return (short)(result1 + result2);
+  }
+
+  static short summ2(short[] a) {
+    Short result1 = 1;
+    Short result2 = new Short((short)1);
+    for (Short i : a) {
+        result1 = (short)(result1 + i);
+        result2 = (short)(result2 + new Short((short)(i + 1)));
+    }
+    return (short)(result1 + result2);
+  }
+
+  static short sump2(short[] a, Short result2) {
+    Short result1 = 1;
+    for (Short i : a) {
+        result1 = (short)(result1 + i);
+        result2 = (short)(result2 + i + 1);
+    }
+    return (short)(result1 + result2);
+  }
+
+  static short sumc2(short[] a) {
+    Short result1 = 1;
+    Short result2 = ibc;
+    for (Short i : a) {
+        result1 = (short)(result1 + i);
+        result2 = (short)(result2 + i + ibc);
+    }
+    return (short)(result1 + result2);
+  }
+
+  //===============================================
+  static short remi_sum() {
+    Short j = new Short((short)1);
+    for (int i = 0; i< 1000; i++) {
+      j = new Short((short)(j + 1));
+    }
+    return j;
+  }
+
+  static short remi_sumb() {
+    Short j = Short.valueOf((short)1);
+    for (int i = 0; i< 1000; i++) {
+      j = (short)(j + 1);
+    }
+    return j;
+  }
+
+  static short remi_sumf() {
+    Short j = foob((short)1);
+    for (int i = 0; i< 1000; i++) {
+      j = (short)(j + 1);
+    }
+    return j;
+  }
+
+  static short remi_sump(Short j) {
+    for (int i = 0; i< 1000; i++) {
+      j = new Short((short)(j + 1));
+    }
+    return j;
+  }
+
+  static short remi_sumc() {
+    Short j = ibc;
+    for (int i = 0; i< 1000; i++) {
+      j = (short)(j + ibc);
+    }
+    return j;
+  }
+
+  static short remi_sum2() {
+    Short j1 = new Short((short)1);
+    Short j2 = new Short((short)1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = new Short((short)(j1 + 1));
+      j2 = new Short((short)(j2 + 2));
+    }
+    return (short)(j1 + j2);
+  }
+
+  static short remi_sumb2() {
+    Short j1 = Short.valueOf((short)1);
+    Short j2 = Short.valueOf((short)1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = (short)(j1 + 1);
+      j2 = (short)(j2 + 2);
+    }
+    return (short)(j1 + j2);
+  }
+
+  static short remi_summ2() {
+    Short j1 = new Short((short)1);
+    Short j2 = Short.valueOf((short)1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = new Short((short)(j1 + 1));
+      j2 = (short)(j2 + 2);
+    }
+    return (short)(j1 + j2);
+  }
+
+  static short remi_sump2(Short j1) {
+    Short j2 = Short.valueOf((short)1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = new Short((short)(j1 + 1));
+      j2 = (short)(j2 + 2);
+    }
+    return (short)(j1 + j2);
+  }
+
+  static short remi_sumc2() {
+    Short j1 = ibc;
+    Short j2 = Short.valueOf((short)1);
+    for (int i = 0; i< 1000; i++) {
+      j1 = (short)(j1 + ibc);
+      j2 = (short)(j2 + 2);
+    }
+    return (short)(j1 + j2);
+  }
+
+
+  //===============================================
+  // Safepointa and debug info for deoptimization
+  static short simple_deop(short i) {
+    Short ib = new Short(foo(i));
+    dummy();
+    return ib;
+  }
+
+  static short simpleb_deop(short i) {
+    Short ib = Short.valueOf(foo(i));
+    dummy();
+    return ib;
+  }
+
+  static short simplef_deop(short i) {
+    Short ib = foob(i);
+    dummy();
+    return ib;
+  }
+
+  static short simplep_deop(Short ib) {
+    dummy();
+    return ib;
+  }
+
+  static short simplec_deop(short i) {
+    Short ib = ibc;
+    dummy();
+    return ib;
+  }
+
+  static short test_deop(short i) {
+    Short ib = new Short(foo(i));
+    if ((i&1) == 0)
+      ib = foo((short)(i+1));
+    dummy();
+    return ib;
+  }
+
+  static short testb_deop(short i) {
+    Short ib = foo(i);
+    if ((i&1) == 0)
+      ib = foo((short)(i+1));
+    dummy();
+    return ib;
+  }
+
+  static short testf_deop(short i) {
+    Short ib = foob(i);
+    if ((i&1) == 0)
+      ib = foo((short)(i+1));
+    dummy();
+    return ib;
+  }
+
+  static short testp_deop(short i, Short ib) {
+    if ((i&1) == 0)
+      ib = foo((short)(i+1));
+    dummy();
+    return ib;
+  }
+
+  static short testc_deop(short i) {
+    Short ib = ibc;
+    if ((i&1) == 0)
+      ib = foo((short)(i+1));
+    dummy();
+    return ib;
+  }
+
+  static short sum_deop(short[] a) {
+    short result = 1;
+    for (Short i : a)
+        result += foo(i);
+    dummy();
+    return result;
+  }
+
+  static short sumb_deop(short[] a) {
+    Short result = 1;
+    for (Short i : a)
+        result = (short)(result + foo(i));
+    dummy();
+    return result;
+  }
+
+  static short sumf_deop(short[] a) {
+    Short result = 1;
+    for (Short i : a)
+        result = (short)(result + foob(i));
+    dummy();
+    return result;
+  }
+
+  static short sump_deop(short[] a, Short result) {
+    for (Short i : a)
+        result = (short)(result + foob(i));
+    dummy();
+    return result;
+  }
+
+  static short sumc_deop(short[] a) {
+    Short result = ibc;
+    for (Short i : a)
+        result = (short)(result + foo(i));
+    dummy();
+    return result;
+  }
+
+  static short remi_sum_deop() {
+    Short j = new Short(foo((short)1));
+    for (int i = 0; i< 1000; i++) {
+      j = new Short(foo((short)(j + 1)));
+    }
+    dummy();
+    return j;
+  }
+
+  static short remi_sumb_deop() {
+    Short j = Short.valueOf(foo((short)1));
+    for (int i = 0; i< 1000; i++) {
+      j = foo((short)(j + 1));
+    }
+    dummy();
+    return j;
+  }
+
+  static short remi_sumf_deop() {
+    Short j = foob((short)1);
+    for (int i = 0; i< 1000; i++) {
+      j = foo((short)(j + 1));
+    }
+    dummy();
+    return j;
+  }
+
+  static short remi_sump_deop(Short j) {
+    for (int i = 0; i< 1000; i++) {
+      j = foo((short)(j + 1));
+    }
+    dummy();
+    return j;
+  }
+
+  static short remi_sumc_deop() {
+    Short j = ibc;
+    for (int i = 0; i< 1000; i++) {
+      j = foo((short)(j + 1));
+    }
+    dummy();
+    return j;
+  }
+
+  //===============================================
+  // Conditional increment
+  static short remi_sum_cond() {
+    Short j = new Short((short)1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = new Short((short)(j + 1));
+      }
+    }
+    return j;
+  }
+
+  static short remi_sumb_cond() {
+    Short j = Short.valueOf((short)1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = (short)(j + 1);
+      }
+    }
+    return j;
+  }
+
+  static short remi_sumf_cond() {
+    Short j = foob((short)1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = (short)(j + 1);
+      }
+    }
+    return j;
+  }
+
+  static short remi_sump_cond(Short j) {
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = (short)(j + 1);
+      }
+    }
+    return j;
+  }
+
+  static short remi_sumc_cond() {
+    Short j = ibc;
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j = (short)(j + ibc);
+      }
+    }
+    return j;
+  }
+
+  static short remi_sum2_cond() {
+    Short j1 = new Short((short)1);
+    Short j2 = new Short((short)1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = new Short((short)(j1 + 1));
+      } else {
+        j2 = new Short((short)(j2 + 2));
+      }
+    }
+    return (short)(j1 + j2);
+  }
+
+  static short remi_sumb2_cond() {
+    Short j1 = Short.valueOf((short)1);
+    Short j2 = Short.valueOf((short)1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = (short)(j1 + 1);
+      } else {
+        j2 = (short)(j2 + 2);
+      }
+    }
+    return (short)(j1 + j2);
+  }
+
+  static short remi_summ2_cond() {
+    Short j1 = new Short((short)1);
+    Short j2 = Short.valueOf((short)1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = new Short((short)(j1 + 1));
+      } else {
+        j2 = (short)(j2 + 2);
+      }
+    }
+    return (short)(j1 + j2);
+  }
+
+  static short remi_sump2_cond(Short j1) {
+    Short j2 = Short.valueOf((short)1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = new Short((short)(j1 + 1));
+      } else {
+        j2 = (short)(j2 + 2);
+      }
+    }
+    return (short)(j1 + j2);
+  }
+
+  static short remi_sumc2_cond() {
+    Short j1 = ibc;
+    Short j2 = Short.valueOf((short)1);
+    for (int i = 0; i< 1000; i++) {
+      if ((i&1) == 0) {
+        j1 = (short)(j1 + ibc);
+      } else {
+        j2 = (short)(j2 + 2);
+      }
+    }
+    return (short)(j1 + j2);
+  }
+
+
+  public static void main(String[] args) {
+    final int ntests = 70;
+
+    String[] test_name = new String[] {
+        "simple",      "simpleb",      "simplec",      "simplef",      "simplep",
+        "simple2",     "simpleb2",     "simplec2",     "simplem2",     "simplep2",
+        "simple_deop", "simpleb_deop", "simplec_deop", "simplef_deop", "simplep_deop",
+        "test",        "testb",        "testc",        "testm",        "testp",
+        "test2",       "testb2",       "testc2",       "testm2",       "testp2",
+        "test_deop",   "testb_deop",   "testc_deop",   "testf_deop",   "testp_deop",
+        "sum",         "sumb",         "sumc",         "sumf",         "sump",
+        "sum2",        "sumb2",        "sumc2",        "summ2",        "sump2",
+        "sum_deop",    "sumb_deop",    "sumc_deop",    "sumf_deop",    "sump_deop",
+        "remi_sum",       "remi_sumb",       "remi_sumc",       "remi_sumf",       "remi_sump",
+        "remi_sum2",      "remi_sumb2",      "remi_sumc2",      "remi_summ2",      "remi_sump2",
+        "remi_sum_deop",  "remi_sumb_deop",  "remi_sumc_deop",  "remi_sumf_deop",  "remi_sump_deop",
+        "remi_sum_cond",  "remi_sumb_cond",  "remi_sumc_cond",  "remi_sumf_cond",  "remi_sump_cond",
+        "remi_sum2_cond", "remi_sumb2_cond", "remi_sumc2_cond", "remi_summ2_cond", "remi_sump2_cond"
+    };
+
+    final int[] val = new int[] {
+       71994000,  71994000,    12000,  71994000,  71994000,
+      144000000, 144000000, 72018000, 144000000, 144000000,
+       71994000,  71994000,    12000,  71994000,  71994000,
+       72000000,  72000000, 36006000,  72000000,  72000000,
+      144012000, 144012000, 72030000, 144012000, 144012000,
+       72000000,  72000000, 36006000,  72000000,  72000000,
+         -24787,    -24787,   -24787,    -24787,    -24787,
+          16962,     16962,    16962,     16962,     16962,
+         -24787,    -24787,   -24787,    -24787,    -24787,
+           1001,      1001,     1001,      1001,      1001,
+           3002,      3002,     3002,      3002,      3002,
+           1001,      1001,     1001,      1001,      1001,
+            501,       501,      501,       501,       501,
+           1502,      1502,     1502,      1502,      1502
+    };
+
+    int[] res = new int[ntests];
+    for (int i = 0; i < ntests; i++) {
+      res[i] = 0;
+    }
+
+
+    for (int i = 0; i < 12000; i++) {
+      res[0] += simple((short)i);
+      res[1] += simpleb((short)i);
+      res[2] += simplec();
+      res[3] += simplef((short)i);
+      res[4] += simplep((short)i);
+
+      res[5] += simple2((short)i);
+      res[6] += simpleb2((short)i);
+      res[7] += simplec2((short)i);
+      res[8] += simplem2((short)i);
+      res[9] += simplep2((short)i, (short)i);
+
+      res[10] += simple_deop((short)i);
+      res[11] += simpleb_deop((short)i);
+      res[12] += simplec_deop((short)i);
+      res[13] += simplef_deop((short)i);
+      res[14] += simplep_deop((short)i);
+
+      res[15] += test((short)i);
+      res[16] += testb((short)i);
+      res[17] += testc((short)i);
+      res[18] += testm((short)i);
+      res[19] += testp((short)i, (short)i);
+
+      res[20] += test2((short)i);
+      res[21] += testb2((short)i);
+      res[22] += testc2((short)i);
+      res[23] += testm2((short)i);
+      res[24] += testp2((short)i, (short)i);
+
+      res[25] += test_deop((short)i);
+      res[26] += testb_deop((short)i);
+      res[27] += testc_deop((short)i);
+      res[28] += testf_deop((short)i);
+      res[29] += testp_deop((short)i, (short)i);
+    }
+
+    short[] ia = new short[1000];
+    for (int i = 0; i < 1000; i++) {
+      ia[i] = (short)i;
+    }
+
+    for (int i = 0; i < 100; i++) {
+      res[30] = sum(ia);
+      res[31] = sumb(ia);
+      res[32] = sumc(ia);
+      res[33] = sumf(ia);
+      res[34] = sump(ia, (short)1);
+
+      res[35] = sum2(ia);
+      res[36] = sumb2(ia);
+      res[37] = sumc2(ia);
+      res[38] = summ2(ia);
+      res[39] = sump2(ia, (short)1);
+
+      res[40] = sum_deop(ia);
+      res[41] = sumb_deop(ia);
+      res[42] = sumc_deop(ia);
+      res[43] = sumf_deop(ia);
+      res[44] = sump_deop(ia, (short)1);
+
+      res[45] = remi_sum();
+      res[46] = remi_sumb();
+      res[47] = remi_sumc();
+      res[48] = remi_sumf();
+      res[49] = remi_sump((short)1);
+
+      res[50] = remi_sum2();
+      res[51] = remi_sumb2();
+      res[52] = remi_sumc2();
+      res[53] = remi_summ2();
+      res[54] = remi_sump2((short)1);
+
+      res[55] = remi_sum_deop();
+      res[56] = remi_sumb_deop();
+      res[57] = remi_sumc_deop();
+      res[58] = remi_sumf_deop();
+      res[59] = remi_sump_deop((short)1);
+
+      res[60] = remi_sum_cond();
+      res[61] = remi_sumb_cond();
+      res[62] = remi_sumc_cond();
+      res[63] = remi_sumf_cond();
+      res[64] = remi_sump_cond((short)1);
+
+      res[65] = remi_sum2_cond();
+      res[66] = remi_sumb2_cond();
+      res[67] = remi_sumc2_cond();
+      res[68] = remi_summ2_cond();
+      res[69] = remi_sump2_cond((short)1);
+    }
+
+    int failed = 0;
+    for (int i = 0; i < ntests; i++) {
+      if (res[i] != val[i]) {
+        System.err.println(test_name[i] + ": " + res[i] + " != " + val[i]);
+        failed++;
+      }
+    }
+    if (failed > 0) {
+      System.err.println("Failed " + failed + " tests.");
+      throw new InternalError();
+    } else {
+      System.out.println("Passed.");
+    }
+  }
+}
diff --git a/hotspot/test/compiler/8009761/Test8009761.java b/hotspot/test/compiler/8009761/Test8009761.java
index f588b82..401458b 100644
--- a/hotspot/test/compiler/8009761/Test8009761.java
+++ b/hotspot/test/compiler/8009761/Test8009761.java
@@ -25,7 +25,7 @@
  * @test
  * @bug 8009761
  * @summary Deoptimization on sparc doesn't set Llast_SP correctly in the interpreter frames it creates
- * @run main/othervm -Xmixed -XX:-UseOnStackReplacement -XX:-BackgroundCompilation Test8009761
+ * @run main/othervm -XX:CompileCommand=exclude,Test8009761::m2 -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -Xss256K Test8009761
  *
  */
 
@@ -249,7 +249,7 @@
             System.out.println("Failed: init recursive calls: " + c1 + ". After deopt " + count);
             System.exit(97);
         } else {
-            System.out.println("PASSED");
+            System.out.println("PASSED " + c1);
         }
     }
 }
diff --git a/hotspot/test/compiler/ciReplay/TestSA.sh b/hotspot/test/compiler/ciReplay/TestSA.sh
index daaec61..6ea2c53 100644
--- a/hotspot/test/compiler/ciReplay/TestSA.sh
+++ b/hotspot/test/compiler/ciReplay/TestSA.sh
@@ -77,10 +77,11 @@
         "replay data wasn't generated by SA"
 fi
 
-diff --brief ${replay_data} replay_vm.txt
-if [ $? -ne 0 ]
+diff ${replay_data} replay_vm.txt > replay.diff 2>&1
+if [ -s replay.diff ]
 then
-    echo WARNING: replay.txt from SA != replay.txt from VM
+    echo WARNING: replay.txt from SA != replay.txt from VM:
+    cat replay.diff
 fi
 
 common_tests 10 
diff --git a/hotspot/test/compiler/ciReplay/common.sh b/hotspot/test/compiler/ciReplay/common.sh
index 6b6ccd0..ec3b7fe 100644
--- a/hotspot/test/compiler/ciReplay/common.sh
+++ b/hotspot/test/compiler/ciReplay/common.sh
@@ -182,8 +182,11 @@
 # crash vm in compiler thread with generation replay data and 'small' dump-file
 # $@ - additional vm opts
 generate_replay() {
-    # enable core dump
-    ulimit -c unlimited
+    if [ $VM_OS != "windows" ]
+    then
+        # enable core dump
+        ulimit -c unlimited
+    fi
 
     cmd="${JAVA} ${TESTVMOPTS} $@ \
             -Xms8m \
@@ -206,29 +209,24 @@
     echo GENERATION OF REPLAY.TXT:
     echo $cmd
 
-    ${cmd} 2>&1 > crash.out
+    ${cmd} > crash.out 2>&1
     
     core_locations=`grep -i core crash.out | grep "location:" | \
             sed -e 's/.*location: //'`
     rm crash.out 
     # processing core locations for *nix
-    if [ $OS != "windows" ]
+    if [ $VM_OS != "windows" ]
     then
         # remove 'or' between '/core.<pid>' and 'core'
         core_locations=`echo $core_locations | \
                 sed -e 's/\([^ ]*\) or \([^ ]*\)/\1 \2/'`
         # add <core_path>/core.<pid> core.<pid>
-        core=`echo $core_locations | awk '{print $1}'`
-        dir=`dirname $core`
-        core=`basename $core`
-        if [ -n ${core} ]
+        core_with_dir=`echo $core_locations | awk '{print $1}'`
+        dir=`dirname $core_with_dir`
+        core_with_pid=`echo $core_locations | awk '{print $2}'`
+        if [ -n ${core_with_pid} ]
         then
-            core_locations="$core_locations $dir${FS}$core"
-        fi
-        core=`echo $core_locations | awk '{print $2}'`
-        if [ -n ${core} ]
-        then
-            core_locations="$core_locations $dir${FS}$core"
+            core_locations="$core_locations $dir${FS}$core_with_pid $core_with_pid"
         fi
     fi
 
diff --git a/hotspot/test/gc/arguments/TestCMSHeapSizeFlags.java b/hotspot/test/gc/arguments/TestCMSHeapSizeFlags.java
new file mode 100644
index 0000000..3dc688c
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestCMSHeapSizeFlags.java
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+ * @test TestCMSHeapSizeFlags
+ * @key gc
+ * @bug 8006088
+ * @summary Tests argument processing for initial and maximum heap size for the CMS collector
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestCMSHeapSizeFlags TestMaxHeapSizeTools
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm TestCMSHeapSizeFlags
+ * @author thomas.schatzl@oracle.com
+ */
+
+public class TestCMSHeapSizeFlags {
+
+  public static void main(String args[]) throws Exception {
+    final String gcName = "-XX:+UseConcMarkSweepGC";
+
+    TestMaxHeapSizeTools.checkMinInitialMaxHeapFlags(gcName);
+
+    TestMaxHeapSizeTools.checkGenMaxHeapErgo(gcName);
+  }
+}
+
diff --git a/hotspot/test/gc/arguments/TestG1HeapSizeFlags.java b/hotspot/test/gc/arguments/TestG1HeapSizeFlags.java
new file mode 100644
index 0000000..31ab5e3
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestG1HeapSizeFlags.java
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+ * @test TestG1HeapSizeFlags
+ * @key gc
+ * @bug 8006088
+ * @summary Tests argument processing for initial and maximum heap size for the G1 collector
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestG1HeapSizeFlags TestMaxHeapSizeTools
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm TestG1HeapSizeFlags
+ * @author thomas.schatzl@oracle.com
+ */
+
+public class TestG1HeapSizeFlags {
+
+  public static void main(String args[]) throws Exception {
+    final String gcName = "-XX:+UseG1GC";
+
+    TestMaxHeapSizeTools.checkMinInitialMaxHeapFlags(gcName);
+
+    TestMaxHeapSizeTools.checkGenMaxHeapErgo(gcName);
+  }
+}
+
diff --git a/hotspot/test/gc/arguments/TestInitialTenuringThreshold.java b/hotspot/test/gc/arguments/TestInitialTenuringThreshold.java
new file mode 100644
index 0000000..2c97ccd
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestInitialTenuringThreshold.java
@@ -0,0 +1,75 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+ * @test TestInitialTenuringThreshold
+ * @key gc
+ * @bug 8014765
+ * @summary Tests argument processing for initial tenuring threshold
+ * @library /testlibrary
+ * @run main/othervm TestInitialTenuringThreshold
+ * @author thomas.schatzl@oracle.com
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class TestInitialTenuringThreshold {
+
+  public static void runWithThresholds(int initial, int max, boolean shouldfail) throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+      "-XX:InitialTenuringThreshold=" + String.valueOf(initial),
+      "-XX:MaxTenuringThreshold=" + String.valueOf(max),
+      "-version"
+      );
+
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    if (shouldfail) {
+      output.shouldHaveExitValue(1);
+    } else {
+      output.shouldHaveExitValue(0);
+    }
+  }
+
+
+  public static void main(String args[]) throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+      // some value below the default value of InitialTenuringThreshold of 7
+      "-XX:MaxTenuringThreshold=1",
+      "-version"
+      );
+
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldHaveExitValue(0);
+    // successful tests
+    runWithThresholds(0, 10, false);
+    runWithThresholds(5, 5, false);
+    // failing tests
+    runWithThresholds(10, 0, true);
+    runWithThresholds(9, 8, true);
+    runWithThresholds(-1, 8, true);
+    runWithThresholds(8, -1, true);
+    runWithThresholds(8, 16, true);
+    runWithThresholds(16, 8, true);
+  }
+}
+
diff --git a/hotspot/test/gc/arguments/TestMaxHeapSizeTools.java b/hotspot/test/gc/arguments/TestMaxHeapSizeTools.java
new file mode 100644
index 0000000..cb7d841
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestMaxHeapSizeTools.java
@@ -0,0 +1,295 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import com.oracle.java.testlibrary.*;
+import sun.hotspot.WhiteBox;
+
+class ErgoArgsPrinter {
+  public static void main(String[] args) throws Exception {
+    WhiteBox wb = WhiteBox.getWhiteBox();
+    wb.printHeapSizes();
+  }
+}
+
+final class MinInitialMaxValues {
+  public long minHeapSize;
+  public long initialHeapSize;
+  public long maxHeapSize;
+
+  public long minAlignment;
+  public long maxAlignment;
+}
+
+class TestMaxHeapSizeTools {
+
+  public static void checkMinInitialMaxHeapFlags(String gcflag) throws Exception {
+    checkInvalidMinInitialHeapCombinations(gcflag);
+    checkValidMinInitialHeapCombinations(gcflag);
+    checkInvalidInitialMaxHeapCombinations(gcflag);
+    checkValidInitialMaxHeapCombinations(gcflag);
+  }
+
+  public static void checkMinInitialErgonomics(String gcflag) throws Exception {
+    // heap sizing ergonomics use the value NewSize + OldSize as default values
+    // for ergonomics calculation. Retrieve these values.
+    long[] values = new long[2];
+    getNewOldSize(gcflag, values);
+
+    // we check cases with values smaller and larger than this default value.
+    long newPlusOldSize = values[0] + values[1];
+    long smallValue = newPlusOldSize / 2;
+    long largeValue = newPlusOldSize * 2;
+
+    // -Xms is not set
+    checkErgonomics(new String[] { gcflag, "-Xmx16M" }, values, -1, -1);
+    checkErgonomics(new String[] { gcflag, "-Xmx16M", "-XX:InitialHeapSize=" + smallValue }, values, smallValue, smallValue);
+    checkErgonomics(new String[] { gcflag, "-Xmx16M", "-XX:InitialHeapSize=" + largeValue }, values, -1, largeValue);
+    checkErgonomics(new String[] { gcflag, "-Xmx16M", "-XX:InitialHeapSize=0" }, values, -1, -1);
+
+    // -Xms is set to zero
+    checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms0" }, values, -1, -1);
+    checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms0", "-XX:InitialHeapSize=" + smallValue }, values, smallValue, smallValue);
+    checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms0", "-XX:InitialHeapSize=" + largeValue }, values, -1, largeValue);
+    checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms0", "-XX:InitialHeapSize=0" }, values, -1, -1);
+
+    // -Xms is set to small value
+    checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + smallValue }, values, -1, -1);
+    checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + smallValue, "-XX:InitialHeapSize=" + smallValue }, values, smallValue, smallValue);
+    checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + smallValue, "-XX:InitialHeapSize=" + largeValue }, values, smallValue, largeValue);
+    checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + smallValue, "-XX:InitialHeapSize=0" }, values, smallValue, -1);
+
+    // -Xms is set to large value
+    checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + largeValue }, values, largeValue, largeValue);
+    // the next case has already been checked elsewhere and gives an error
+    // checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + largeValue, "-XX:InitialHeapSize=" + smallValue }, values, smallValue, smallValue);
+    // the next case has already been checked elsewhere too
+    // checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + largeValue, "-XX:InitialHeapSize=" + largeValue }, values, values[0], largeValue);
+    checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + largeValue, "-XX:InitialHeapSize=0" }, values, largeValue, -1);
+  }
+
+  private static long align_up(long value, long alignment) {
+    long alignmentMinusOne = alignment - 1;
+    return (value + alignmentMinusOne) & ~alignmentMinusOne;
+  }
+
+  private static void getNewOldSize(String gcflag, long[] values) throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(gcflag,
+      "-XX:+PrintFlagsFinal", "-version");
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldHaveExitValue(0);
+
+    String stdout = output.getStdout();
+    values[0] = getFlagValue(" NewSize", stdout);
+    values[1] = getFlagValue(" OldSize", stdout);
+  }
+
+  public static void checkGenMaxHeapErgo(String gcflag) throws Exception {
+    TestMaxHeapSizeTools.checkGenMaxHeapSize(gcflag, 3);
+    TestMaxHeapSizeTools.checkGenMaxHeapSize(gcflag, 4);
+    TestMaxHeapSizeTools.checkGenMaxHeapSize(gcflag, 5);
+  }
+
+  private static void checkInvalidMinInitialHeapCombinations(String gcflag) throws Exception {
+    expectError(new String[] { gcflag, "-Xms8M", "-XX:InitialHeapSize=4M", "-version" });
+  }
+
+  private static void checkValidMinInitialHeapCombinations(String gcflag) throws Exception {
+    expectValid(new String[] { gcflag, "-XX:InitialHeapSize=8M", "-Xms4M", "-version" });
+    expectValid(new String[] { gcflag, "-Xms4M", "-XX:InitialHeapSize=8M", "-version" });
+    expectValid(new String[] { gcflag, "-XX:InitialHeapSize=8M", "-Xms8M", "-version" });
+    // the following is not an error as -Xms sets both minimal and initial heap size
+    expectValid(new String[] { gcflag, "-XX:InitialHeapSize=4M", "-Xms8M", "-version" });
+  }
+
+  private static void checkInvalidInitialMaxHeapCombinations(String gcflag) throws Exception {
+    expectError(new String[] { gcflag, "-XX:MaxHeapSize=4M", "-XX:InitialHeapSize=8M", "-version" });
+    expectError(new String[] { gcflag, "-XX:InitialHeapSize=8M", "-XX:MaxHeapSize=4M", "-version" });
+  }
+
+  private static void checkValidInitialMaxHeapCombinations(String gcflag) throws Exception {
+    expectValid(new String[] { gcflag, "-XX:InitialHeapSize=4M", "-XX:MaxHeapSize=8M", "-version" });
+    expectValid(new String[] { gcflag, "-XX:MaxHeapSize=8M", "-XX:InitialHeapSize=4M", "-version" });
+    expectValid(new String[] { gcflag, "-XX:MaxHeapSize=4M", "-XX:InitialHeapSize=4M", "-version" });
+    // a value of "0" for initial heap size means auto-detect
+    expectValid(new String[] { gcflag, "-XX:MaxHeapSize=4M", "-XX:InitialHeapSize=0M", "-version" });
+  }
+
+  private static long valueAfter(String source, String match) {
+    int start = source.indexOf(match) + match.length();
+    String tail = source.substring(start).split(" ")[0];
+    return Long.parseLong(tail);
+  }
+
+  /**
+   * Executes a new VM process with the given class and parameters.
+   * @param vmargs Arguments to the VM to run
+   * @param classname Name of the class to run
+   * @param arguments Arguments to the class
+   * @param useTestDotJavaDotOpts Use test.java.opts as part of the VM argument string
+   * @return The OutputAnalyzer with the results for the invocation.
+   */
+  public static OutputAnalyzer runWhiteBoxTest(String[] vmargs, String classname, String[] arguments, boolean useTestDotJavaDotOpts) throws Exception {
+    ArrayList<String> finalargs = new ArrayList<String>();
+
+    String[] whiteboxOpts = new String[] {
+      "-Xbootclasspath/a:.",
+      "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
+      "-cp", System.getProperty("java.class.path"),
+    };
+
+    if (useTestDotJavaDotOpts) {
+      // System.getProperty("test.java.opts") is '' if no options is set,
+      // we need to skip such a result
+      String[] externalVMOpts = new String[0];
+      if (System.getProperty("test.java.opts") != null && System.getProperty("test.java.opts").length() != 0) {
+        externalVMOpts = System.getProperty("test.java.opts").split(" ");
+      }
+      finalargs.addAll(Arrays.asList(externalVMOpts));
+    }
+
+    finalargs.addAll(Arrays.asList(vmargs));
+    finalargs.addAll(Arrays.asList(whiteboxOpts));
+    finalargs.add(classname);
+    finalargs.addAll(Arrays.asList(arguments));
+
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(finalargs.toArray(new String[0]));
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldHaveExitValue(0);
+
+    return output;
+  }
+
+  private static void getMinInitialMaxHeap(String[] args, MinInitialMaxValues val) throws Exception {
+    OutputAnalyzer output = runWhiteBoxTest(args, ErgoArgsPrinter.class.getName(), new String[] {}, false);
+
+    // the output we watch for has the following format:
+    //
+    // "Minimum heap X Initial heap Y Maximum heap Z Min alignment A Max Alignment B"
+    //
+    // where A, B, X, Y and Z are sizes in bytes.
+    // Unfortunately there is no other way to retrieve the minimum heap size and
+    // the alignments.
+
+    Matcher m = Pattern.compile("Minimum heap \\d+ Initial heap \\d+ Maximum heap \\d+ Min alignment \\d+ Max alignment \\d+").
+      matcher(output.getStdout());
+    if (!m.find()) {
+      throw new RuntimeException("Could not find heap size string.");
+    }
+
+    String match = m.group();
+
+    // actual values
+    val.minHeapSize = valueAfter(match, "Minimum heap ");
+    val.initialHeapSize = valueAfter(match, "Initial heap ");
+    val.maxHeapSize = valueAfter(match, "Maximum heap ");
+    val.minAlignment = valueAfter(match, "Min alignment ");
+    val.maxAlignment = valueAfter(match, "Max alignment ");
+  }
+
+  /**
+   * Verify whether the VM automatically synchronizes minimum and initial heap size if only
+   * one is given for the GC specified.
+   */
+  public static void checkErgonomics(String[] args, long[] newoldsize,
+    long expectedMin, long expectedInitial) throws Exception {
+
+    MinInitialMaxValues v = new MinInitialMaxValues();
+    getMinInitialMaxHeap(args, v);
+
+    if ((expectedMin != -1) && (align_up(expectedMin, v.minAlignment) != v.minHeapSize)) {
+      throw new RuntimeException("Actual minimum heap size of " + v.minHeapSize +
+        " differs from expected minimum heap size of " + expectedMin);
+    }
+
+    if ((expectedInitial != -1) && (align_up(expectedInitial, v.minAlignment) != v.initialHeapSize)) {
+      throw new RuntimeException("Actual initial heap size of " + v.initialHeapSize +
+        " differs from expected initial heap size of " + expectedInitial);
+    }
+
+    // always check the invariant min <= initial <= max heap size
+    if (!(v.minHeapSize <= v.initialHeapSize && v.initialHeapSize <= v.maxHeapSize)) {
+      throw new RuntimeException("Inconsistent min/initial/max heap sizes, they are " +
+        v.minHeapSize + "/" + v.initialHeapSize + "/" + v.maxHeapSize);
+    }
+  }
+
+  /**
+   * Verify whether the VM respects the given maximum heap size in MB for the
+   * GC specified.
+   * @param gcflag The garbage collector to test as command line flag. E.g. -XX:+UseG1GC
+   * @param maxHeapSize the maximum heap size to verify, in MB.
+   */
+  public static void checkGenMaxHeapSize(String gcflag, long maxHeapsize) throws Exception {
+    final long K = 1024;
+
+    MinInitialMaxValues v = new MinInitialMaxValues();
+    getMinInitialMaxHeap(new String[] { gcflag, "-XX:MaxHeapSize=" + maxHeapsize + "M" }, v);
+
+    long expectedHeapSize = align_up(maxHeapsize * K * K, v.maxAlignment);
+    long actualHeapSize = v.maxHeapSize;
+
+    if (actualHeapSize > expectedHeapSize) {
+      throw new RuntimeException("Heap has " + actualHeapSize  +
+        " bytes, expected to be less than " + expectedHeapSize);
+    }
+  }
+
+  private static long getFlagValue(String flag, String where) {
+    Matcher m = Pattern.compile(flag + "\\s+:?=\\s+\\d+").matcher(where);
+    if (!m.find()) {
+      throw new RuntimeException("Could not find value for flag " + flag + " in output string");
+    }
+    String match = m.group();
+    return Long.parseLong(match.substring(match.lastIndexOf(" ") + 1, match.length()));
+  }
+
+  private static void shouldContainOrNot(OutputAnalyzer output, boolean contains, String message) throws Exception {
+    if (contains) {
+      output.shouldContain(message);
+    } else {
+      output.shouldNotContain(message);
+    }
+  }
+
+  private static void expect(String[] flags, boolean hasWarning, boolean hasError, int errorcode) throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flags);
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    shouldContainOrNot(output, hasWarning, "Warning");
+    shouldContainOrNot(output, hasError, "Error");
+    output.shouldHaveExitValue(errorcode);
+  }
+
+  private static void expectError(String[] flags) throws Exception {
+    expect(flags, false, true, 1);
+  }
+
+  private static void expectValid(String[] flags) throws Exception {
+    expect(flags, false, false, 0);
+  }
+}
+
diff --git a/hotspot/test/gc/arguments/TestMinInitialErgonomics.java b/hotspot/test/gc/arguments/TestMinInitialErgonomics.java
new file mode 100644
index 0000000..8352d92
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestMinInitialErgonomics.java
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/**
+ * @test TestMinInitialErgonomics
+ * @key gc
+ * @bug 8006088
+ * @summary Test ergonomics decisions related to minimum and initial heap size.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestMinInitialErgonomics TestMaxHeapSizeTools
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm TestMinInitialErgonomics
+ * @author thomas.schatzl@oracle.com
+ */
+
+public class TestMinInitialErgonomics {
+
+  public static void main(String args[]) throws Exception {
+    final String gcName = "-XX:+UseParallelGC";
+    // check ergonomic decisions about minimum and initial heap size in
+    // a single gc only as ergonomics are the same everywhere.
+    TestMaxHeapSizeTools.checkMinInitialErgonomics(gcName);
+  }
+}
+
diff --git a/hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java b/hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java
new file mode 100644
index 0000000..2de2826
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+ * @test TestParallelHeapSizeFlags
+ * @key gc
+ * @bug 8006088
+ * @summary Tests argument processing for initial and maximum heap size for the
+ * parallel collectors.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestParallelHeapSizeFlags TestMaxHeapSizeTools
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm TestParallelHeapSizeFlags
+ * @author thomas.schatzl@oracle.com
+ */
+
+public class TestParallelHeapSizeFlags {
+
+  public static void main(String args[]) throws Exception {
+    // just pick one of the parallel generational collectors. Sizing logic is the
+    // same.
+    final String gcName = "-XX:+UseParallelOldGC";
+
+    TestMaxHeapSizeTools.checkMinInitialMaxHeapFlags(gcName);
+
+    TestMaxHeapSizeTools.checkGenMaxHeapErgo(gcName);
+  }
+}
+
diff --git a/hotspot/test/gc/arguments/TestSerialHeapSizeFlags.java b/hotspot/test/gc/arguments/TestSerialHeapSizeFlags.java
new file mode 100644
index 0000000..967adf6
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestSerialHeapSizeFlags.java
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+ * @test TestSerialHeapSizeFlags
+ * @key gc
+ * @bug 8006088
+ * @summary Tests argument processing for initial and maximum heap size for the Serial collector
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestSerialHeapSizeFlags TestMaxHeapSizeTools
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm TestSerialHeapSizeFlags
+ * @author thomas.schatzl@oracle.com
+ */
+
+public class TestSerialHeapSizeFlags {
+
+  public static void main(String args[]) throws Exception {
+    final String gcName = "-XX:+UseSerialGC";
+
+    TestMaxHeapSizeTools.checkMinInitialMaxHeapFlags(gcName);
+
+    TestMaxHeapSizeTools.checkGenMaxHeapErgo(gcName);
+  }
+}
+
diff --git a/hotspot/test/gc/g1/TestPrintGCDetails.java b/hotspot/test/gc/g1/TestPrintGCDetails.java
new file mode 100644
index 0000000..4280a19
--- /dev/null
+++ b/hotspot/test/gc/g1/TestPrintGCDetails.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestPrintGCDetails
+ * @bug 8010738
+ * @summary Ensure that the PrintGCDetails for a full GC with G1 includes Metaspace.
+ * @key gc
+ * @key regression
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.ProcessTools;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class TestPrintGCDetails {
+  public static void main(String[] args) throws Exception {
+
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
+                                                              "-XX:+PrintGCDetails",
+                                                              SystemGCTest.class.getName());
+
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+    System.out.println("Output:\n" + output.getOutput());
+
+    output.shouldContain("Metaspace");
+    output.shouldHaveExitValue(0);
+  }
+
+  static class SystemGCTest {
+    public static void main(String [] args) {
+      System.out.println("Calling System.gc()");
+      System.gc();
+    }
+  }
+}
diff --git a/hotspot/test/gc/g1/TestPrintRegionRememberedSetInfo.java b/hotspot/test/gc/g1/TestPrintRegionRememberedSetInfo.java
new file mode 100644
index 0000000..417b2cc
--- /dev/null
+++ b/hotspot/test/gc/g1/TestPrintRegionRememberedSetInfo.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test TestPrintRegionRememberedSetInfo
+ * @key gc
+ * @bug 8014240
+ * @summary Test output of G1PrintRegionRememberedSetInfo
+ * @library /testlibrary
+ * @build TestPrintRegionRememberedSetInfo
+ * @author thomas.schatzl@oracle.com
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.lang.Thread;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+class RunAndWaitForMarking {
+    public static void main(String[] args) {
+        System.gc();
+        try {
+            Thread.sleep(200);
+        } catch (InterruptedException e) {
+        }
+    }
+}
+
+public class TestPrintRegionRememberedSetInfo {
+
+    public static String runTest(String arg) throws Exception {
+        ArrayList<String> finalargs = new ArrayList<String>();
+        String[] defaultArgs = new String[] {
+            "-XX:+UseG1GC",
+            "-Xmx10m",
+            "-XX:+ExplicitGCInvokesConcurrent",
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:+G1PrintRegionLivenessInfo",
+            "-XX:G1HeapRegionSize=1M",
+            "-XX:InitiatingHeapOccupancyPercent=0",
+        };
+
+        finalargs.addAll(Arrays.asList(defaultArgs));
+        finalargs.add(arg);
+
+        finalargs.add(RunAndWaitForMarking.class.getName());
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            finalargs.toArray(new String[0]));
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldHaveExitValue(0);
+
+        String result = output.getStdout();
+        return result;
+    }
+
+    public static void main(String[] args) throws Exception {
+        String result;
+
+        result = runTest("-XX:+G1PrintRegionLivenessInfo");
+        // check that we got region statistics output
+        if (result.indexOf("PHASE") == -1) {
+            throw new RuntimeException("Unexpected output from -XX:+PrintRegionLivenessInfo found.");
+        }
+
+        result = runTest("-XX:-G1PrintRegionLivenessInfo");
+        if (result.indexOf("remset") != -1) {
+            throw new RuntimeException("Should find remembered set information in output.");
+        }
+    }
+}
+
diff --git a/hotspot/test/runtime/RedefineObject/Agent.java b/hotspot/test/runtime/RedefineObject/Agent.java
new file mode 100644
index 0000000..7927094
--- /dev/null
+++ b/hotspot/test/runtime/RedefineObject/Agent.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.security.*;
+import java.lang.instrument.*;
+
+public class Agent implements ClassFileTransformer {
+    public synchronized byte[] transform(final ClassLoader classLoader,
+                                         final String className,
+                                         Class<?> classBeingRedefined,
+                                         ProtectionDomain protectionDomain,
+                                         byte[] classfileBuffer) {
+        //System.out.println("Transforming class " + className);
+        return classfileBuffer;
+    }
+
+    public static void premain(String agentArgs, Instrumentation instrumentation) {
+
+        Agent transformer = new Agent();
+
+        instrumentation.addTransformer(transformer, true);
+
+        Class c = Object.class;
+        try {
+            instrumentation.retransformClasses(c);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        instrumentation.removeTransformer(transformer);
+    }
+
+    public static void main(String[] args) {
+        byte[] ba = new byte[0];
+
+        // If it survives 1000 GC's, it's good.
+        for (int i = 0; i < 1000 ; i++) {
+            System.gc();
+            ba.clone();
+        }
+    }
+}
diff --git a/hotspot/test/runtime/RedefineObject/TestRedefineObject.java b/hotspot/test/runtime/RedefineObject/TestRedefineObject.java
new file mode 100644
index 0000000..37ba6a3
--- /dev/null
+++ b/hotspot/test/runtime/RedefineObject/TestRedefineObject.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.io.PrintWriter;
+import com.oracle.java.testlibrary.*;
+
+/*
+ * Test to redefine java/lang/Object and verify that it doesn't crash on vtable
+ * call on basic array type.
+ *
+ * @test
+ * @bug 8005056
+ * @library /testlibrary
+ * @build Agent
+ * @run main ClassFileInstaller Agent
+ * @run main Test
+ * @run main/othervm -javaagent:agent.jar Agent
+ */
+public class Test {
+    public static void main(String[] args) throws Exception  {
+
+      PrintWriter pw = new PrintWriter("MANIFEST.MF");
+      pw.println("Premain-Class: Agent");
+      pw.println("Can-Retransform-Classes: true");
+      pw.close();
+
+      ProcessBuilder pb = new ProcessBuilder();
+      pb.command(new String[] { JDKToolFinder.getJDKTool("jar"), "cmf", "MANIFEST.MF", "agent.jar", "Agent.class"});
+      pb.start().waitFor();
+    }
+}
diff --git a/hotspot/test/runtime/SharedArchiveFile/SharedArchiveFile.java b/hotspot/test/runtime/SharedArchiveFile/SharedArchiveFile.java
new file mode 100644
index 0000000..802e251
--- /dev/null
+++ b/hotspot/test/runtime/SharedArchiveFile/SharedArchiveFile.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8014138
+ * @summary Testing new -XX:SharedArchiveFile=<file-name> option
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class SharedArchiveFile {
+  public static void main(String[] args) throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+        "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    try {
+      output.shouldContain("Loading classes to share");
+      output.shouldHaveExitValue(0);
+
+      pb = ProcessTools.createJavaProcessBuilder(
+        "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
+      output = new OutputAnalyzer(pb.start());
+      output.shouldContain("sharing");
+      output.shouldHaveExitValue(0);
+
+    } catch (RuntimeException e) {
+      output.shouldContain("Unable to use shared archive");
+      output.shouldHaveExitValue(1);
+    }
+  }
+}
diff --git a/hotspot/test/testlibrary/ClassFileInstaller.java b/hotspot/test/testlibrary/ClassFileInstaller.java
index 694223e..303e96e 100644
--- a/hotspot/test/testlibrary/ClassFileInstaller.java
+++ b/hotspot/test/testlibrary/ClassFileInstaller.java
@@ -45,7 +45,9 @@
 
             // Create the class file's package directory
             Path p = Paths.get(pathName);
-            Files.createDirectories(p.getParent());
+            if (pathName.contains("/")) {
+                Files.createDirectories(p.getParent());
+            }
             // Create the class file
             Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING);
         }
diff --git a/jaxp/.hgtags b/jaxp/.hgtags
index 62e9fbe..7ba8153 100644
--- a/jaxp/.hgtags
+++ b/jaxp/.hgtags
@@ -211,3 +211,4 @@
 eddbc8ad2435a89f64729512337c9f2669e4dd85 jdk8-b87
 7122f7bb0fcc8a39e5254402119b2ee3fa0ad313 jdk8-b88
 893d2ba8bbea3a8d090e51d8eaea285b390789ea jdk8-b89
+668acc0e1034bc1bec6d02be92e0dd4a63d0667e jdk8-b90
diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/generic/BasicType.java b/jaxp/src/com/sun/org/apache/bcel/internal/generic/BasicType.java
index 9784784..c7340a6 100644
--- a/jaxp/src/com/sun/org/apache/bcel/internal/generic/BasicType.java
+++ b/jaxp/src/com/sun/org/apache/bcel/internal/generic/BasicType.java
@@ -97,8 +97,14 @@
 
   /** @return true if both type objects refer to the same type
    */
+  @Override
   public boolean equals(Object type) {
     return (type instanceof BasicType)?
       ((BasicType)type).type == this.type : false;
   }
+
+  @Override
+  public int hashCode() {
+      return type;
+  }
 }
diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java b/jaxp/src/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java
index d9a7625..36960f8 100644
--- a/jaxp/src/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java
+++ b/jaxp/src/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java
@@ -93,6 +93,7 @@
    * Dump instruction as byte code to stream out.
    * @param out Output stream
    */
+  @Override
   public void dump(DataOutputStream out) throws IOException {
     out.writeByte(opcode);
 
@@ -153,6 +154,7 @@
    * @param verbose long/short format switch
    * @return mnemonic for instruction
    */
+  @Override
   public String toString(boolean verbose) {
     String s = super.toString(verbose);
     String t = "null";
@@ -184,6 +186,7 @@
    * @param wide wide prefix?
    * @see InstructionList
    */
+  @Override
   protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException
   {
     length = 3;
@@ -204,26 +207,41 @@
    * Set branch target
    * @param target branch target
    */
-  public void setTarget(InstructionHandle target) {
-    notifyTarget(this.target, target, this);
+  public final void setTarget(InstructionHandle target) {
+    notifyTargetChanging(this.target, this);
     this.target = target;
+    notifyTargetChanged(this.target, this);
   }
 
   /**
-   * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen
+   * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen.
+   * Must be called before the target is actually changed in the
+   * InstructionTargeter.
    */
-  static final void notifyTarget(InstructionHandle old_ih, InstructionHandle new_ih,
+  static void notifyTargetChanging(InstructionHandle old_ih,
                                  InstructionTargeter t) {
-    if(old_ih != null)
+    if(old_ih != null) {
       old_ih.removeTargeter(t);
-    if(new_ih != null)
+    }
+  }
+
+  /**
+   * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen.
+   * Must be called after the target is actually changed in the
+   * InstructionTargeter.
+   */
+  static void notifyTargetChanged(InstructionHandle new_ih,
+                                 InstructionTargeter t) {
+    if(new_ih != null) {
       new_ih.addTargeter(t);
+    }
   }
 
   /**
    * @param old_ih old target
    * @param new_ih new target
    */
+  @Override
   public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
     if(target == old_ih)
       setTarget(new_ih);
@@ -234,6 +252,7 @@
   /**
    * @return true, if ih is target of this instruction
    */
+  @Override
   public boolean containsTarget(InstructionHandle ih) {
     return (target == ih);
   }
@@ -241,6 +260,7 @@
   /**
    * Inform target that it's not targeted anymore.
    */
+  @Override
   void dispose() {
     setTarget(null);
     index=-1;
diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java b/jaxp/src/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java
index 96c32fa..0fb252b 100644
--- a/jaxp/src/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java
+++ b/jaxp/src/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java
@@ -58,7 +58,6 @@
  * <http://www.apache.org/>.
  */
 
-import com.sun.org.apache.bcel.internal.Constants;
 import com.sun.org.apache.bcel.internal.classfile.*;
 
 /**
@@ -118,31 +117,35 @@
   /* Set start of handler
    * @param start_pc Start of handled region (inclusive)
    */
-  public void setStartPC(InstructionHandle start_pc) {
-    BranchInstruction.notifyTarget(this.start_pc, start_pc, this);
+  public final void setStartPC(InstructionHandle start_pc) {
+    BranchInstruction.notifyTargetChanging(this.start_pc, this);
     this.start_pc = start_pc;
+    BranchInstruction.notifyTargetChanged(this.start_pc, this);
   }
 
   /* Set end of handler
    * @param end_pc End of handled region (inclusive)
    */
-  public void setEndPC(InstructionHandle end_pc) {
-    BranchInstruction.notifyTarget(this.end_pc, end_pc, this);
+  public final void setEndPC(InstructionHandle end_pc) {
+    BranchInstruction.notifyTargetChanging(this.end_pc, this);
     this.end_pc = end_pc;
+    BranchInstruction.notifyTargetChanged(this.end_pc, this);
   }
 
   /* Set handler code
    * @param handler_pc Start of handler
    */
-  public void setHandlerPC(InstructionHandle handler_pc) {
-    BranchInstruction.notifyTarget(this.handler_pc, handler_pc, this);
+  public final void setHandlerPC(InstructionHandle handler_pc) {
+    BranchInstruction.notifyTargetChanging(this.handler_pc, this);
     this.handler_pc = handler_pc;
+    BranchInstruction.notifyTargetChanged(this.handler_pc, this);
   }
 
   /**
    * @param old_ih old target, either start or end
    * @param new_ih new target
    */
+  @Override
   public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
     boolean targeted = false;
 
@@ -169,6 +172,7 @@
   /**
    * @return true, if ih is target of this handler
    */
+  @Override
   public boolean containsTarget(InstructionHandle ih) {
     return (start_pc == ih) || (end_pc == ih) || (handler_pc == ih);
   }
@@ -190,10 +194,12 @@
    */
   public InstructionHandle getHandlerPC()                             { return handler_pc; }
 
+  @Override
   public String toString() {
     return "CodeExceptionGen(" + start_pc + ", " + end_pc + ", " + handler_pc + ")";
   }
 
+  @Override
   public Object clone() {
     try {
       return super.clone();
diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java b/jaxp/src/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java
index e191e01..a8427a8 100644
--- a/jaxp/src/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java
+++ b/jaxp/src/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java
@@ -58,7 +58,6 @@
  * <http://www.apache.org/>.
  */
 
-import com.sun.org.apache.bcel.internal.Constants;
 import com.sun.org.apache.bcel.internal.classfile.*;
 
 /**
@@ -88,6 +87,7 @@
   /**
    * @return true, if ih is target of this line number
    */
+  @Override
   public boolean containsTarget(InstructionHandle ih) {
     return this.ih == ih;
   }
@@ -96,6 +96,7 @@
    * @param old_ih old target
    * @param new_ih new target
    */
+  @Override
   public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
     if(old_ih != ih)
       throw new ClassGenException("Not targeting " + old_ih + ", but " + ih + "}");
@@ -113,12 +114,13 @@
     return new LineNumber(ih.getPosition(), src_line);
   }
 
-  public void setInstruction(InstructionHandle ih) {
-    BranchInstruction.notifyTarget(this.ih, ih, this);
-
+  public final void setInstruction(InstructionHandle ih) {
+    BranchInstruction.notifyTargetChanging(this.ih, this);
     this.ih = ih;
+    BranchInstruction.notifyTargetChanged(this.ih, this);
   }
 
+  @Override
   public Object clone() {
     try {
       return super.clone();
diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java b/jaxp/src/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java
index d9a7130..1f2fd86 100644
--- a/jaxp/src/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java
+++ b/jaxp/src/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java
@@ -60,6 +60,7 @@
 
 import com.sun.org.apache.bcel.internal.Constants;
 import com.sun.org.apache.bcel.internal.classfile.*;
+import java.util.Objects;
 
 /**
  * This class represents a local variable within a method. It contains its
@@ -75,7 +76,7 @@
   implements InstructionTargeter, NamedAndTyped, Cloneable,
              java.io.Serializable
 {
-  private int         index;
+  private final int   index;
   private String      name;
   private Type        type;
   private InstructionHandle start, end;
@@ -131,30 +132,96 @@
                              signature_index, index, cp.getConstantPool());
   }
 
-  public void        setIndex(int index)           { this.index = index; }
-  public int         getIndex()                   { return index; }
+  public int         getIndex()                  { return index; }
+  @Override
   public void        setName(String name)        { this.name = name; }
+  @Override
   public String      getName()                   { return name; }
+  @Override
   public void        setType(Type type)          { this.type = type; }
+  @Override
   public Type        getType()                   { return type; }
 
   public InstructionHandle getStart()                  { return start; }
   public InstructionHandle getEnd()                    { return end; }
 
-  public void setStart(InstructionHandle start) {
-    BranchInstruction.notifyTarget(this.start, start, this);
-    this.start = start;
+  /**
+   * Remove this from any known HashSet in which it might be registered.
+   */
+  void notifyTargetChanging() {
+    // hashCode depends on 'index', 'start', and 'end'.
+    // Therefore before changing any of these values we
+    // need to unregister 'this' from any HashSet where
+    // this is registered, and then we need to add it
+    // back...
+
+    // Unregister 'this' from the HashSet held by 'start'.
+    BranchInstruction.notifyTargetChanging(this.start, this);
+    if (this.end != this.start) {
+        // Since hashCode() is going to change we need to unregister
+        // 'this' both form 'start' and 'end'.
+        // Unregister 'this' from the HashSet held by 'end'.
+        BranchInstruction.notifyTargetChanging(this.end, this);
+    }
   }
 
-  public void setEnd(InstructionHandle end) {
-    BranchInstruction.notifyTarget(this.end, end, this);
+  /**
+   * Add back 'this' in all HashSet in which it should be registered.
+   **/
+  void notifyTargetChanged() {
+    // hashCode depends on 'index', 'start', and 'end'.
+    // Therefore before changing any of these values we
+    // need to unregister 'this' from any HashSet where
+    // this is registered, and then we need to add it
+    // back...
+
+    // Register 'this' in the HashSet held by start.
+    BranchInstruction.notifyTargetChanged(this.start, this);
+    if (this.end != this.start) {
+        // Since hashCode() has changed we need to register
+        // 'this' again in 'end'.
+        // Add back 'this' in the HashSet held by 'end'.
+        BranchInstruction.notifyTargetChanged(this.end, this);
+    }
+  }
+
+  public final void setStart(InstructionHandle start) {
+
+    // Call notifyTargetChanging *before* modifying this,
+    // as the code triggered by notifyTargetChanging
+    // depends on this pointing to the 'old' start.
+    notifyTargetChanging();
+
+    this.start = start;
+
+    // call notifyTargetChanged *after* modifying this,
+    // as the code triggered by notifyTargetChanged
+    // depends on this pointing to the 'new' start.
+    notifyTargetChanged();
+  }
+
+  public final void setEnd(InstructionHandle end) {
+    // call notifyTargetChanging *before* modifying this,
+    // as the code triggered by notifyTargetChanging
+    // depends on this pointing to the 'old' end.
+    // Unregister 'this' from the HashSet held by the 'old' end.
+    notifyTargetChanging();
+
     this.end = end;
+
+    // call notifyTargetChanged *after* modifying this,
+    // as the code triggered by notifyTargetChanged
+    // depends on this pointing to the 'new' end.
+    // Register 'this' in the HashSet held by the 'new' end.
+    notifyTargetChanged();
+
   }
 
   /**
    * @param old_ih old target, either start or end
    * @param new_ih new target
    */
+  @Override
   public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
     boolean targeted = false;
 
@@ -176,15 +243,20 @@
   /**
    * @return true, if ih is target of this variable
    */
+  @Override
   public boolean containsTarget(InstructionHandle ih) {
     return (start == ih) || (end == ih);
   }
 
   /**
-   * We consider to local variables to be equal, if the use the same index and
+   * We consider two local variables to be equal, if they use the same index and
    * are valid in the same range.
    */
+  @Override
   public boolean equals(Object o) {
+    if (o==this)
+      return true;
+
     if(!(o instanceof LocalVariableGen))
       return false;
 
@@ -192,10 +264,21 @@
     return (l.index == index) && (l.start == start) && (l.end == end);
   }
 
+  @Override
+  public int hashCode() {
+    int hash = 7;
+    hash = 59 * hash + this.index;
+    hash = 59 * hash + Objects.hashCode(this.start);
+    hash = 59 * hash + Objects.hashCode(this.end);
+    return hash;
+  }
+
+  @Override
   public String toString() {
     return "LocalVariableGen(" + name +  ", " + type +  ", " + start + ", " + end + ")";
   }
 
+  @Override
   public Object clone() {
     try {
       return super.clone();
diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java b/jaxp/src/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java
index 659d724..501efdd 100644
--- a/jaxp/src/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java
+++ b/jaxp/src/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java
@@ -58,7 +58,7 @@
  * <http://www.apache.org/>.
  */
 import com.sun.org.apache.bcel.internal.Constants;
-import com.sun.org.apache.bcel.internal.generic.InstructionHandle;
+import java.util.Objects;
 
 /**
  * Returnaddress, the type JSR or JSR_W instructions push upon the stack.
@@ -86,9 +86,15 @@
         this.returnTarget = returnTarget;
   }
 
+  @Override
+  public int hashCode() {
+      return Objects.hashCode(this.returnTarget);
+  }
+
   /**
    * Returns if the two Returnaddresses refer to the same target.
    */
+  @Override
   public boolean equals(Object rat){
     if(!(rat instanceof ReturnaddressType))
       return false;
diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/generic/Select.java b/jaxp/src/com/sun/org/apache/bcel/internal/generic/Select.java
index dfdf8a7..0cf47f6 100644
--- a/jaxp/src/com/sun/org/apache/bcel/internal/generic/Select.java
+++ b/jaxp/src/com/sun/org/apache/bcel/internal/generic/Select.java
@@ -97,8 +97,9 @@
     super(opcode, target);
 
     this.targets = targets;
-    for(int i=0; i < targets.length; i++)
-      notifyTarget(null, targets[i], this);
+    for(int i=0; i < targets.length; i++) {
+      BranchInstruction.notifyTargetChanged(targets[i], this);
+    }
 
     this.match = match;
 
@@ -121,6 +122,7 @@
    * @param max_offset the maximum offset that may be caused by these instructions
    * @return additional offset caused by possible change of this instruction's length
    */
+  @Override
   protected int updatePosition(int offset, int max_offset) {
     position += offset; // Additional offset caused by preceding SWITCHs, GOTOs, etc.
 
@@ -138,6 +140,7 @@
    * Dump instruction as byte code to stream out.
    * @param out Output stream
    */
+  @Override
   public void dump(DataOutputStream out) throws IOException {
     out.writeByte(opcode);
 
@@ -151,6 +154,7 @@
   /**
    * Read needed data (e.g. index) from file.
    */
+  @Override
   protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException
   {
     padding = (4 - (bytes.getIndex() % 4)) % 4; // Compute number of pad bytes
@@ -166,8 +170,9 @@
   /**
    * @return mnemonic for instruction
    */
+  @Override
   public String toString(boolean verbose) {
-    StringBuffer buf = new StringBuffer(super.toString(verbose));
+    final StringBuilder buf = new StringBuilder(super.toString(verbose));
 
     if(verbose) {
       for(int i=0; i < match_length; i++) {
@@ -176,7 +181,8 @@
         if(targets[i] != null)
           s = targets[i].getInstruction().toString();
 
-        buf.append("(" + match[i] + ", " + s + " = {" + indices[i] + "})");
+          buf.append("(").append(match[i]).append(", ")
+             .append(s).append(" = {").append(indices[i]).append("})");
       }
     }
     else
@@ -188,15 +194,17 @@
   /**
    * Set branch target for `i'th case
    */
-  public void setTarget(int i, InstructionHandle target) {
-    notifyTarget(targets[i], target, this);
+  public final void setTarget(int i, InstructionHandle target) {
+    notifyTargetChanging(targets[i], this);
     targets[i] = target;
+    notifyTargetChanged(targets[i], this);
   }
 
   /**
    * @param old_ih old target
    * @param new_ih new target
    */
+  @Override
   public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
     boolean targeted = false;
 
@@ -219,6 +227,7 @@
   /**
    * @return true, if ih is target of this instruction
    */
+  @Override
   public boolean containsTarget(InstructionHandle ih) {
     if(target == ih)
       return true;
@@ -233,6 +242,7 @@
   /**
    * Inform targets that they're not targeted anymore.
    */
+  @Override
   void dispose() {
     super.dispose();
 
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java b/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java
index 6fdccc0..82756c1 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java
@@ -25,9 +25,7 @@
 
 package com.sun.org.apache.xalan.internal;
 
-import com.sun.org.apache.xerces.internal.impl.*;
-import java.util.Enumeration;
-import java.util.NoSuchElementException;
+import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
 
 /**
  * Commonly used constants.
@@ -42,19 +40,99 @@
     // Constants
     //
     // Oracle Feature:
-        /**
-         * <p>Use Service Mechanism</p>
-         *
-         * <ul>
-         *   <li>
-         *     <code>true</code> instructs the implementation to use service mechanism to find implementation.
-         *     This is the default behavior.
+    /**
+     * <p>Use Service Mechanism</p>
+     *
+     * <ul>
+     *   <li>
+         * {@code true} instruct an object to use service mechanism to
+         * find a service implementation. This is the default behavior.
          *   </li>
          *   <li>
-         *     <code>false</code> instructs the implementation to skip service mechanism and use the default implementation.
-         *   </li>
-         * </ul>
-         */
+         * {@code false} instruct an object to skip service mechanism and
+         * use the default implementation for that service.
+     *   </li>
+     * </ul>
+    */
+
     public static final String ORACLE_FEATURE_SERVICE_MECHANISM = "http://www.oracle.com/feature/use-service-mechanism";
 
+    /** Oracle JAXP property prefix ("http://www.oracle.com/xml/jaxp/properties/"). */
+    public static final String ORACLE_JAXP_PROPERTY_PREFIX =
+        "http://www.oracle.com/xml/jaxp/properties/";
+
+    //System Properties corresponding to ACCESS_EXTERNAL_* properties
+    public static final String SP_ACCESS_EXTERNAL_STYLESHEET = "javax.xml.accessExternalStylesheet";
+    public static final String SP_ACCESS_EXTERNAL_DTD = "javax.xml.accessExternalDTD";
+
+
+    //all access keyword
+    public static final String ACCESS_EXTERNAL_ALL = "all";
+
+    /**
+     * Default value when FEATURE_SECURE_PROCESSING (FSP) is set to true
+     */
+    public static final String EXTERNAL_ACCESS_DEFAULT_FSP = "";
+    /**
+     * JDK version by which the default is to restrict external connection
+     */
+    public static final int RESTRICT_BY_DEFAULT_JDK_VERSION = 8;
+    /**
+     * FEATURE_SECURE_PROCESSING (FSP) is false by default
+     */
+    public static final String EXTERNAL_ACCESS_DEFAULT = getExternalAccessDefault(false);
+
+    /**
+     * Determine the default value of the external access properties
+     *
+     * jaxp 1.5 does not require implementations to restrict by default
+     *
+     * For JDK8:
+     * The default value is 'file' (including jar:file); The keyword "all" grants permission
+     * to all protocols. When {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} is on,
+     * the default value is an empty string indicating no access is allowed.
+     *
+     * For JDK7:
+     * The default value is 'all' granting permission to all protocols. If by default,
+     * {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} is true, it should
+     * not change the default value. However, if {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING}
+     * is set explicitly, the values of the properties shall be set to an empty string
+     * indicating no access is allowed.
+     *
+     * @param isSecureProcessing indicating if Secure Processing is set
+     * @return default value
+     */
+    public static String getExternalAccessDefault(boolean isSecureProcessing) {
+        String defaultValue = "all";
+        if (isJDKandAbove(RESTRICT_BY_DEFAULT_JDK_VERSION)) {
+            defaultValue = "file";
+            if (isSecureProcessing) {
+                defaultValue = EXTERNAL_ACCESS_DEFAULT_FSP;
+            }
+        }
+        return defaultValue;
+    }
+
+    /*
+     * Check the version of the current JDK against that specified in the
+     * parameter
+     *
+     * There is a proposal to change the java version string to:
+     * MAJOR.MINOR.FU.CPU.PSU-BUILDNUMBER_BUGIDNUMBER_OPTIONAL
+     * This method would work with both the current format and that proposed
+     *
+     * @param compareTo a JDK version to be compared to
+     * @return true if the current version is the same or above that represented
+     * by the parameter
+     */
+    public static boolean isJDKandAbove(int compareTo) {
+        String javaVersion = SecuritySupport.getSystemProperty("java.version");
+        String versions[] = javaVersion.split("\\.", 3);
+        if (Integer.parseInt(versions[0]) >= compareTo ||
+            Integer.parseInt(versions[1]) >= compareTo) {
+            return true;
+        }
+        return false;
+    }
+
 } // class Constants
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java b/jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java
index b813b4c..e418fd5 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java
@@ -26,7 +26,9 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.io.InputStream;
+import java.net.URL;
 
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -36,6 +38,7 @@
 import java.util.Locale;
 import java.util.MissingResourceException;
 import java.util.ResourceBundle;
+import java.util.Properties;
 
 /**
  * This class is duplicated for each subpackage so keep it in sync. It is
@@ -200,7 +203,141 @@
                 })).longValue();
     }
 
-
-    private SecuritySupport() {
+    /**
+     * Strip off path from an URI
+     *
+     * @param uri an URI with full path
+     * @return the file name only
+     */
+    public static String sanitizePath(String uri) {
+        if (uri == null) {
+            return "";
+        }
+        int i = uri.lastIndexOf("/");
+        if (i > 0) {
+            return uri.substring(i+1, uri.length());
+        }
+        return "";
     }
+
+    /**
+     * Check the protocol used in the systemId against allowed protocols
+     *
+     * @param systemId the Id of the URI
+     * @param allowedProtocols a list of allowed protocols separated by comma
+     * @param accessAny keyword to indicate allowing any protocol
+     * @return the name of the protocol if rejected, null otherwise
+     */
+    public static String checkAccess(String systemId, String allowedProtocols, String accessAny) throws IOException {
+        if (systemId == null || allowedProtocols.equalsIgnoreCase(accessAny)) {
+            return null;
+        }
+
+        String protocol;
+        if (systemId.indexOf(":")==-1) {
+            protocol = "file";
+        } else {
+            URL url = new URL(systemId);
+            protocol = url.getProtocol();
+            if (protocol.equalsIgnoreCase("jar")) {
+                String path = url.getPath();
+                protocol = path.substring(0, path.indexOf(":"));
+            }
+        }
+
+        if (isProtocolAllowed(protocol, allowedProtocols)) {
+            //access allowed
+            return null;
+        } else {
+            return protocol;
+        }
+    }
+
+    /**
+     * Check if the protocol is in the allowed list of protocols. The check
+     * is case-insensitive while ignoring whitespaces.
+     *
+     * @param protocol a protocol
+     * @param allowedProtocols a list of allowed protocols
+     * @return true if the protocol is in the list
+     */
+    private static boolean isProtocolAllowed(String protocol, String allowedProtocols) {
+         String temp[] = allowedProtocols.split(",");
+         for (String t : temp) {
+             t = t.trim();
+             if (t.equalsIgnoreCase(protocol)) {
+                 return true;
+             }
+         }
+         return false;
+     }
+
+    /**
+     * Read from $java.home/lib/jaxp.properties for the specified property
+     *
+     * @param propertyId the Id of the property
+     * @return the value of the property
+     */
+    public static String getDefaultAccessProperty(String sysPropertyId, String defaultVal) {
+        String accessExternal = SecuritySupport.getSystemProperty(sysPropertyId);
+        if (accessExternal == null) {
+            accessExternal = readJAXPProperty(sysPropertyId);
+            if (accessExternal == null) {
+                accessExternal = defaultVal;
+            }
+        }
+        return accessExternal;
+    }
+
+    /**
+     * Read from $java.home/lib/jaxp.properties for the specified property
+     * The program
+     *
+     * @param propertyId the Id of the property
+     * @return the value of the property
+     */
+    static String readJAXPProperty(String propertyId) {
+        String value = null;
+        InputStream is = null;
+        try {
+            if (firstTime) {
+                synchronized (cacheProps) {
+                    if (firstTime) {
+                        String configFile = getSystemProperty("java.home") + File.separator +
+                            "lib" + File.separator + "jaxp.properties";
+                        File f = new File(configFile);
+                        if (getFileExists(f)) {
+                            is = getFileInputStream(f);
+                            cacheProps.load(is);
+                        }
+                        firstTime = false;
+                    }
+                }
+            }
+            value = cacheProps.getProperty(propertyId);
+
+        }
+        catch (Exception ex) {}
+        finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException ex) {}
+            }
+        }
+
+        return value;
+    }
+
+    /**
+     * Cache for properties in java.home/lib/jaxp.properties
+     */
+    static final Properties cacheProps = new Properties();
+
+    /**
+     * Flag indicating if the program has tried reading java.home/lib/jaxp.properties
+     */
+    static volatile boolean firstTime = true;
+
+    private SecuritySupport () {}
 }
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java
index f4f903b..76c4643 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java
@@ -54,6 +54,7 @@
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
 import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
+import java.util.Objects;
 
 /**
  * @author Jacek Ambroziak
@@ -156,8 +157,15 @@
             this.type = type;
             this.distance = distance;
         }
+
+        @Override
+        public int hashCode() {
+            return Objects.hashCode(this.type);
+        }
+
+        @Override
         public boolean equals(Object query){
-            return query.equals(type);
+            return query != null && query.equals(type);
         }
     }
 
@@ -277,6 +285,7 @@
         return(_fname.toString());
     }
 
+    @Override
     public void setParser(Parser parser) {
         super.setParser(parser);
         if (_arguments != null) {
@@ -319,6 +328,7 @@
      * Type check a function call. Since different type conversions apply,
      * type checking is different for standard and external (Java) functions.
      */
+    @Override
     public Type typeCheck(SymbolTable stable)
         throws TypeCheckError
     {
@@ -680,6 +690,7 @@
      * Compile the function call and treat as an expression
      * Update true/false-lists.
      */
+    @Override
     public void translateDesynthesized(ClassGenerator classGen,
                                        MethodGenerator methodGen)
     {
@@ -700,6 +711,7 @@
      * Translate a function call. The compiled code will leave the function's
      * return value on the JVM's stack.
      */
+    @Override
     public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
         final int n = argumentCount();
         final ConstantPoolGen cpg = classGen.getConstantPool();
@@ -857,6 +869,7 @@
         }
     }
 
+    @Override
     public String toString() {
         return "funcall(" + _fname + ", " + _arguments + ')';
     }
@@ -1069,7 +1082,7 @@
     protected static String replaceDash(String name)
     {
         char dash = '-';
-        StringBuffer buff = new StringBuffer("");
+        final StringBuilder buff = new StringBuilder("");
         for (int i = 0; i < name.length(); i++) {
         if (i > 0 && name.charAt(i-1) == dash)
             buff.append(Character.toUpperCase(name.charAt(i)));
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java
index b2d33e9..fdfbe17 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java
@@ -23,18 +23,19 @@
 
 package com.sun.org.apache.xalan.internal.xsltc.compiler;
 
-import java.io.File;
-import java.net.URL;
-import java.net.MalformedURLException;
-import java.util.Enumeration;
-
-import com.sun.org.apache.xml.internal.utils.SystemIDResolver;
+import com.sun.org.apache.xalan.internal.XalanConstants;
+import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
-
+import com.sun.org.apache.xml.internal.utils.SystemIDResolver;
+import java.io.File;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.util.Enumeration;
+import javax.xml.XMLConstants;
 import org.xml.sax.InputSource;
 import org.xml.sax.XMLReader;
 
@@ -84,6 +85,17 @@
             // No SourceLoader or not resolved by SourceLoader
             if (input == null) {
                 docToLoad = SystemIDResolver.getAbsoluteURI(docToLoad, currLoadedDoc);
+                String accessError = SecuritySupport.checkAccess(docToLoad,
+                        xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET),
+                        XalanConstants.ACCESS_EXTERNAL_ALL);
+
+                if (accessError != null) {
+                    final ErrorMsg msg = new ErrorMsg(ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+                                        SecuritySupport.sanitizePath(docToLoad), accessError,
+                                        this);
+                    parser.reportError(Constants.FATAL, msg);
+                    return;
+                }
                 input = new InputSource(docToLoad);
             }
 
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java
index 3d549f4..71c129f 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java
@@ -23,19 +23,20 @@
 
 package com.sun.org.apache.xalan.internal.xsltc.compiler;
 
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Enumeration;
-
-import com.sun.org.apache.xml.internal.utils.SystemIDResolver;
+import com.sun.org.apache.xalan.internal.XalanConstants;
+import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
-
+import com.sun.org.apache.xml.internal.utils.SystemIDResolver;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import javax.xml.XMLConstants;
 import org.xml.sax.InputSource;
 import org.xml.sax.XMLReader;
 
@@ -85,6 +86,17 @@
             // No SourceLoader or not resolved by SourceLoader
             if (input == null) {
                 docToLoad = SystemIDResolver.getAbsoluteURI(docToLoad, currLoadedDoc);
+                String accessError = SecuritySupport.checkAccess(docToLoad,
+                        xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET),
+                        XalanConstants.ACCESS_EXTERNAL_ALL);
+
+                if (accessError != null) {
+                    final ErrorMsg msg = new ErrorMsg(ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+                                        SecuritySupport.sanitizePath(docToLoad), accessError,
+                                        this);
+                    parser.reportError(Constants.FATAL, msg);
+                    return;
+                }
                 input = new InputSource(docToLoad);
             }
 
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java
index 80ce77b..9669bf7 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java
@@ -23,6 +23,16 @@
 
 package com.sun.org.apache.xalan.internal.xsltc.compiler;
 
+import com.sun.java_cup.internal.runtime.Symbol;
+import com.sun.org.apache.xalan.internal.XalanConstants;
+import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
+import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
+import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
+import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
+import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType;
+import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
+import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
+import com.sun.org.apache.xml.internal.serializer.utils.SystemIDResolver;
 import java.io.File;
 import java.io.IOException;
 import java.io.StringReader;
@@ -33,27 +43,18 @@
 import java.util.Stack;
 import java.util.StringTokenizer;
 import java.util.Vector;
-
-import com.sun.java_cup.internal.runtime.Symbol;
 import javax.xml.XMLConstants;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
-
-import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
-import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType;
-import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
-import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
-import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
-import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
 import org.xml.sax.Attributes;
-import org.xml.sax.helpers.AttributesImpl;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.InputSource;
 import org.xml.sax.Locator;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
 import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.AttributesImpl;
 
 /**
  * @author Jacek Ambroziak
@@ -475,6 +476,8 @@
                 factory.setNamespaceAware(true);
             }
             final SAXParser parser = factory.newSAXParser();
+            parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
+                    _xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
             final XMLReader reader = parser.getXMLReader();
             return(parse(reader, input));
         }
@@ -547,6 +550,25 @@
             return(element);
         }
         else {
+            try {
+                String path = _target;
+                if (path.indexOf(":")==-1) {
+                    path = "file:" + path;
+                }
+                path = SystemIDResolver.getAbsoluteURI(path);
+                String accessError = SecuritySupport.checkAccess(path,
+                        _xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET),
+                        XalanConstants.ACCESS_EXTERNAL_ALL);
+                if (accessError != null) {
+                    ErrorMsg msg = new ErrorMsg(ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+                            SecuritySupport.sanitizePath(_target), accessError,
+                            root);
+                    throw new CompilerException(msg.toString());
+                }
+            } catch (IOException ex) {
+                throw new CompilerException(ex);
+            }
+
             return(loadExternalStylesheet(_target));
         }
     }
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/VariableRefBase.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/VariableRefBase.java
index 100c0e7..76cee04 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/VariableRefBase.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/VariableRefBase.java
@@ -25,6 +25,7 @@
 
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
+import java.util.Objects;
 
 /**
  * @author Morten Jorgensen
@@ -97,13 +98,15 @@
      * Two variable references are deemed equal if they refer to the
      * same variable.
      */
+    @Override
     public boolean equals(Object obj) {
-        try {
-            return (_variable == ((VariableRefBase) obj)._variable);
-        }
-        catch (ClassCastException e) {
-            return false;
-        }
+        return obj == this || (obj instanceof VariableRefBase)
+            && (_variable == ((VariableRefBase) obj)._variable);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(this._variable);
     }
 
     /**
@@ -111,10 +114,12 @@
      * format 'variable-ref(<var-name>)'.
      * @return Variable reference description
      */
+    @Override
     public String toString() {
         return "variable-ref("+_variable.getName()+'/'+_variable.getType()+')';
     }
 
+    @Override
     public Type typeCheck(SymbolTable stable)
         throws TypeCheckError
     {
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java
index 4540278..97fff3b 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java
@@ -39,8 +39,10 @@
 import java.util.jar.JarEntry;
 import java.util.jar.JarOutputStream;
 import java.util.jar.Manifest;
+import javax.xml.XMLConstants;
 
 import com.sun.org.apache.bcel.internal.classfile.JavaClass;
+import com.sun.org.apache.xalan.internal.XalanConstants;
 import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;
@@ -136,6 +138,16 @@
     private boolean _useServicesMechanism = true;
 
     /**
+     * protocols allowed for external references set by the stylesheet processing instruction, Import and Include element.
+     */
+    private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+     /**
+     * protocols allowed for external DTD references in source file and/or stylesheet.
+     */
+    private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+
+
+    /**
      * XSLTC compiler constructor
      */
     public XSLTC(boolean useServicesMechanism) {
@@ -170,6 +182,31 @@
     }
 
     /**
+     * Return allowed protocols for accessing external stylesheet.
+     */
+    public String getProperty(String name) {
+        if (name.equals(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)) {
+            return _accessExternalStylesheet;
+        }
+        else if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
+            return _accessExternalDTD;
+        }
+        return null;
+    }
+
+    /**
+     * Set allowed protocols for accessing external stylesheet.
+     */
+    public void setProperty(String name, String value) {
+        if (name.equals(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)) {
+            _accessExternalStylesheet = (String)value;
+        }
+        else if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
+            _accessExternalDTD = (String)value;
+        }
+    }
+
+    /**
      * Only for user by the internal TrAX implementation.
      */
     public Parser getParser() {
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java
index de37839..90655c6 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java
@@ -446,6 +446,12 @@
         "Could not find stylesheet target ''{0}''."},
 
         /*
+         * Note to translators:  access to the stylesheet target is denied
+         */
+        {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+        "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
+        /*
          * Note to translators:  This message represents an internal error in
          * condition in XSLTC.  The substitution text is the class name in XSLTC
          * that is missing some functionality.
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ca.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ca.java
index 1d615bf..fa28ddc 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ca.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ca.java
@@ -444,6 +444,12 @@
         "No s''ha trobat la destinaci\u00f3 ''{0}'' del full d''estils."},
 
         /*
+         * Note to translators:  access to the stylesheet target is denied
+         */
+        {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+        "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
+        /*
          * Note to translators:  This message represents an internal error in
          * condition in XSLTC.  The substitution text is the class name in XSLTC
          * that is missing some functionality.
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_cs.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_cs.java
index 739b670..4220efd 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_cs.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_cs.java
@@ -444,6 +444,12 @@
         "Nelze naj\u00edt c\u00edlovou p\u0159edlohu se stylem ''{0}''."},
 
         /*
+         * Note to translators:  access to the stylesheet target is denied
+         */
+        {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+        "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
+        /*
          * Note to translators:  This message represents an internal error in
          * condition in XSLTC.  The substitution text is the class name in XSLTC
          * that is missing some functionality.
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_de.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_de.java
index e0473d4..1ae98c1 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_de.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_de.java
@@ -444,6 +444,12 @@
         "Stylesheet-Ziel \"{0}\" konnte nicht gefunden werden."},
 
         /*
+         * Note to translators:  access to the stylesheet target is denied
+         */
+        {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+        "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
+        /*
          * Note to translators:  This message represents an internal error in
          * condition in XSLTC.  The substitution text is the class name in XSLTC
          * that is missing some functionality.
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_es.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_es.java
index ffb9bcc..7aa0deb 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_es.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_es.java
@@ -444,6 +444,12 @@
         "No se ha encontrado el destino de hoja de estilo ''{0}''."},
 
         /*
+         * Note to translators:  access to the stylesheet target is denied
+         */
+        {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+        "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
+        /*
          * Note to translators:  This message represents an internal error in
          * condition in XSLTC.  The substitution text is the class name in XSLTC
          * that is missing some functionality.
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_fr.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_fr.java
index 4c7087e..39151c7 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_fr.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_fr.java
@@ -444,6 +444,12 @@
         "Cible de feuille de style ''{0}'' introuvable."},
 
         /*
+         * Note to translators:  access to the stylesheet target is denied
+         */
+        {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+        "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
+        /*
          * Note to translators:  This message represents an internal error in
          * condition in XSLTC.  The substitution text is the class name in XSLTC
          * that is missing some functionality.
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_it.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_it.java
index 4c33c19..b8f68b9 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_it.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_it.java
@@ -444,6 +444,12 @@
         "Impossibile trovare la destinazione ''{0}'' del foglio di stile."},
 
         /*
+         * Note to translators:  access to the stylesheet target is denied
+         */
+        {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+        "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
+        /*
          * Note to translators:  This message represents an internal error in
          * condition in XSLTC.  The substitution text is the class name in XSLTC
          * that is missing some functionality.
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java
index eec29e9..28c15ea 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java
@@ -444,6 +444,12 @@
         "\u30B9\u30BF\u30A4\u30EB\u30B7\u30FC\u30C8\u30FB\u30BF\u30FC\u30B2\u30C3\u30C8''{0}''\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002"},
 
         /*
+         * Note to translators:  access to the stylesheet target is denied
+         */
+        {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+        "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
+        /*
          * Note to translators:  This message represents an internal error in
          * condition in XSLTC.  The substitution text is the class name in XSLTC
          * that is missing some functionality.
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ko.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ko.java
index 9a2c5b4..3385381 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ko.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ko.java
@@ -444,6 +444,12 @@
         "\uC2A4\uD0C0\uC77C\uC2DC\uD2B8 \uB300\uC0C1 ''{0}''\uC744(\uB97C) \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
 
         /*
+         * Note to translators:  access to the stylesheet target is denied
+         */
+        {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+        "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
+        /*
          * Note to translators:  This message represents an internal error in
          * condition in XSLTC.  The substitution text is the class name in XSLTC
          * that is missing some functionality.
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_pt_BR.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_pt_BR.java
index a0c3142..c6b369e 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_pt_BR.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_pt_BR.java
@@ -444,6 +444,12 @@
         "N\u00E3o foi poss\u00EDvel localizar o alvo da folha de estilos ''{0}''."},
 
         /*
+         * Note to translators:  access to the stylesheet target is denied
+         */
+        {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+        "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
+        /*
          * Note to translators:  This message represents an internal error in
          * condition in XSLTC.  The substitution text is the class name in XSLTC
          * that is missing some functionality.
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sk.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sk.java
index cc0ba4b..1a76afc 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sk.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sk.java
@@ -444,6 +444,12 @@
         "Nebolo mo\u017en\u00e9 n\u00e1js\u0165 cie\u013e \u0161t\u00fdlu dokumentu ''{0}''."},
 
         /*
+         * Note to translators:  access to the stylesheet target is denied
+         */
+        {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+        "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
+        /*
          * Note to translators:  This message represents an internal error in
          * condition in XSLTC.  The substitution text is the class name in XSLTC
          * that is missing some functionality.
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sv.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sv.java
index 62d2f7a..07aa76c 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sv.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sv.java
@@ -444,6 +444,12 @@
         "Hittade inte formatmallen ''{0}''."},
 
         /*
+         * Note to translators:  access to the stylesheet target is denied
+         */
+        {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+        "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
+        /*
          * Note to translators:  This message represents an internal error in
          * condition in XSLTC.  The substitution text is the class name in XSLTC
          * that is missing some functionality.
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_CN.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_CN.java
index 683ea33..1b12156 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_CN.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_CN.java
@@ -444,6 +444,12 @@
         "\u627E\u4E0D\u5230\u6837\u5F0F\u8868\u76EE\u6807 ''{0}''\u3002"},
 
         /*
+         * Note to translators:  access to the stylesheet target is denied
+         */
+        {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+        "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
+        /*
          * Note to translators:  This message represents an internal error in
          * condition in XSLTC.  The substitution text is the class name in XSLTC
          * that is missing some functionality.
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_TW.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_TW.java
index 892a2e8..f813e66 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_TW.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_TW.java
@@ -444,6 +444,12 @@
         "\u627E\u4E0D\u5230\u6A23\u5F0F\u8868\u76EE\u6A19 ''{0}''\u3002"},
 
         /*
+         * Note to translators:  access to the stylesheet target is denied
+         */
+        {ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+        "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+
+        /*
          * Note to translators:  This message represents an internal error in
          * condition in XSLTC.  The substitution text is the class name in XSLTC
          * that is missing some functionality.
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java
index faa7e99..102f354 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java
@@ -95,6 +95,7 @@
     public static final String UNSUPPORTED_EXT_ERR = "UNSUPPORTED_EXT_ERR";
     public static final String MISSING_XSLT_URI_ERR = "MISSING_XSLT_URI_ERR";
     public static final String MISSING_XSLT_TARGET_ERR = "MISSING_XSLT_TARGET_ERR";
+    public static final String ACCESSING_XSLT_TARGET_ERR = "ACCESSING_XSLT_TARGET_ERR";
     public static final String NOT_IMPLEMENTED_ERR = "NOT_IMPLEMENTED_ERR";
     public static final String NOT_STYLESHEET_ERR = "NOT_STYLESHEET_ERR";
     public static final String ELEMENT_PARSE_ERR = "ELEMENT_PARSE_ERR";
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/dom/LoadDocument.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/dom/LoadDocument.java
index de87c56..f3e2879 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/dom/LoadDocument.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/dom/LoadDocument.java
@@ -23,6 +23,7 @@
 
 package com.sun.org.apache.xalan.internal.xsltc.dom;
 
+import com.sun.org.apache.xalan.internal.XalanConstants;
 import java.io.FileNotFoundException;
 
 import javax.xml.transform.stream.StreamSource;
@@ -31,8 +32,10 @@
 import com.sun.org.apache.xalan.internal.xsltc.DOMCache;
 import com.sun.org.apache.xalan.internal.xsltc.DOMEnhancedForDTM;
 import com.sun.org.apache.xalan.internal.xsltc.TransletException;
+import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
 import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
 import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
+import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
 import com.sun.org.apache.xml.internal.dtm.DTM;
 import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
 import com.sun.org.apache.xml.internal.dtm.DTMManager;
@@ -199,6 +202,13 @@
                 throw new TransletException(e);
             }
         } else {
+            String accessError = SecuritySupport.checkAccess(uri, translet.getAllowedProtocols(), XalanConstants.ACCESS_EXTERNAL_ALL);
+            if (accessError != null) {
+                ErrorMsg msg = new ErrorMsg(ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
+                        SecuritySupport.sanitizePath(uri), accessError);
+                throw new Exception(msg.toString());
+            }
+
             // Parse the input document and construct DOM object
             // Trust the DTMManager to pick the right parser and
             // set up the DOM correctly.
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java
index 71e1e4a..9eddf5c 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java
@@ -23,6 +23,7 @@
 
 package com.sun.org.apache.xalan.internal.xsltc.runtime;
 
+import com.sun.org.apache.xalan.internal.XalanConstants;
 import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
 import java.io.File;
 import java.io.FileOutputStream;
@@ -110,6 +111,11 @@
 
     private boolean _useServicesMechanism;
 
+    /**
+     * protocols allowed for external references set by the stylesheet processing instruction, Document() function, Import and Include element.
+     */
+    private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+
     /************************************************************************
      * Debugging
      ************************************************************************/
@@ -758,6 +764,20 @@
         _useServicesMechanism = flag;
     }
 
+    /**
+     * Return allowed protocols for accessing external stylesheet.
+     */
+    public String getAllowedProtocols() {
+        return _accessExternalStylesheet;
+    }
+
+    /**
+     * Set allowed protocols for accessing external stylesheet.
+     */
+    public void setAllowedProtocols(String protocols) {
+        _accessExternalStylesheet = protocols;
+    }
+
     /************************************************************************
      * DOMImplementation caching for basis library
      ************************************************************************/
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java
index 2eb161d..879c1cb 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java
@@ -99,6 +99,12 @@
         if (tfactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING))
             xsltc.setSecureProcessing(true);
 
+        xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET,
+                (String)tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET));
+        xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
+                (String)tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_DTD));
+
+
         if ("true".equals(tfactory.getAttribute(TransformerFactoryImpl.ENABLE_INLINING)))
             xsltc.setTemplateInlining(true);
         else
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java
index a3bd7f6..e6d9cc3 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java
@@ -23,6 +23,7 @@
 
 package com.sun.org.apache.xalan.internal.xsltc.trax;
 
+import com.sun.org.apache.xalan.internal.XalanConstants;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
@@ -124,6 +125,11 @@
 
     private boolean _useServicesMechanism;
 
+    /**
+     * protocols allowed for external references set by the stylesheet processing instruction, Import and Include element.
+     */
+    private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+
     static final class TransletClassLoader extends ClassLoader {
         TransletClassLoader(ClassLoader parent) {
             super(parent);
@@ -171,6 +177,7 @@
         _indentNumber = indentNumber;
         _tfactory = tfactory;
         _useServicesMechanism = tfactory.useServicesMechnism();
+        _accessExternalStylesheet = (String) tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET);
     }
     /**
      * Need for de-serialization, see readObject().
@@ -381,6 +388,7 @@
             translet.postInitialization();
             translet.setTemplates(this);
             translet.setServicesMechnism(_useServicesMechanism);
+            translet.setAllowedProtocols(_accessExternalStylesheet);
             if (_auxClasses != null) {
                 translet.setAuxiliaryClasses(_auxClasses);
             }
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java
index 78d96aa..2675268 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java
@@ -225,6 +225,16 @@
     private boolean _useServicesMechanism;
 
     /**
+     * protocols allowed for external references set by the stylesheet processing instruction, Import and Include element.
+     */
+    private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+     /**
+     * protocols allowed for external DTD references in source file and/or stylesheet.
+     */
+    private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+
+
+    /**
      * javax.xml.transform.sax.TransformerFactory implementation.
      */
     public TransformerFactoryImpl() {
@@ -238,10 +248,17 @@
     private TransformerFactoryImpl(boolean useServicesMechanism) {
         this.m_DTMManagerClass = XSLTCDTMManager.getDTMManagerClass(useServicesMechanism);
         this._useServicesMechanism = useServicesMechanism;
+
+        String defaultAccess = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
         if (System.getSecurityManager() != null) {
             _isSecureMode = true;
             _isNotSecureProcessing = false;
+            defaultAccess = XalanConstants.getExternalAccessDefault(true);
         }
+        _accessExternalStylesheet =  SecuritySupport.getDefaultAccessProperty(
+                XalanConstants.SP_ACCESS_EXTERNAL_STYLESHEET, defaultAccess);
+        _accessExternalDTD =  SecuritySupport.getDefaultAccessProperty(
+                XalanConstants.SP_ACCESS_EXTERNAL_DTD, defaultAccess);
     }
 
     /**
@@ -301,6 +318,12 @@
             else
               return Boolean.FALSE;
         }
+        else if (name.equals(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)) {
+            return _accessExternalStylesheet;
+        }
+        else if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
+            return _accessExternalDTD;
+        }
 
         // Throw an exception for all other attributes
         ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_INVALID_ATTR_ERR, name);
@@ -401,6 +424,14 @@
                 return;
             }
         }
+        else if (name.equals(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)) {
+            _accessExternalStylesheet = (String)value;
+            return;
+        }
+        else if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
+            _accessExternalDTD = (String)value;
+            return;
+        }
 
         // Throw an exception for all other attributes
         final ErrorMsg err
@@ -444,7 +475,12 @@
                 throw new TransformerConfigurationException(err.toString());
             }
             _isNotSecureProcessing = !value;
-            // all done processing feature
+
+            // set restriction, allowing no access to external stylesheet
+            if (value) {
+                _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT_FSP;
+                _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT_FSP;
+            }
             return;
         }
         else if (name.equals(XalanConstants.ORACLE_FEATURE_SERVICE_MECHANISM)) {
@@ -799,6 +835,8 @@
                 xsltc.setTemplateInlining(false);
 
         if (!_isNotSecureProcessing) xsltc.setSecureProcessing(true);
+        xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, _accessExternalStylesheet);
+        xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD);
         xsltc.init();
 
         // Set a document loader (for xsl:include/import) if defined
@@ -880,15 +918,20 @@
 
         // Check that the transformation went well before returning
     if (bytecodes == null) {
-
         Vector errs = xsltc.getErrors();
         ErrorMsg err = null;
         if (errs != null) {
-            err = (ErrorMsg)errs.get(errs.size()-1);
+            err = (ErrorMsg)errs.elementAt(errs.size()-1);
         } else {
             err = new ErrorMsg(ErrorMsg.JAXP_COMPILE_ERR);
         }
-        TransformerConfigurationException exc =  new TransformerConfigurationException(err.toString(), err.getCause());
+        Throwable cause = err.getCause();
+        TransformerConfigurationException exc;
+        if (cause != null) {
+            exc =  new TransformerConfigurationException(cause.getMessage(), cause);
+        } else {
+            exc =  new TransformerConfigurationException(err.toString());
+        }
 
         // Pass compiler errors to the error listener
         if (_errorListener != null) {
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
index 16e178e..a32ab82 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
@@ -23,6 +23,7 @@
 
 package com.sun.org.apache.xalan.internal.xsltc.trax;
 
+import com.sun.org.apache.xalan.internal.XalanConstants;
 import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
 import java.io.File;
 import java.io.FileOutputStream;
@@ -61,6 +62,7 @@
 import javax.xml.transform.stax.StAXSource;
 import javax.xml.transform.stream.StreamResult;
 import javax.xml.transform.stream.StreamSource;
+import javax.xml.XMLConstants;
 
 import com.sun.org.apache.xml.internal.utils.SystemIDResolver;
 
@@ -207,6 +209,14 @@
      * Note the default value (false) is the safe option..
      */
     private boolean _useServicesMechanism;
+    /**
+     * protocols allowed for external references set by the stylesheet processing instruction, Import and Include element.
+     */
+    private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+     /**
+     * protocols allowed for external DTD references in source file and/or stylesheet.
+     */
+    private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
 
     /**
      * A hashtable to store parameters for the identity transform. These
@@ -260,7 +270,10 @@
         _indentNumber = indentNumber;
         _tfactory = tfactory;
         _useServicesMechanism = _tfactory.useServicesMechnism();
+        _accessExternalStylesheet = (String)_tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET);
+        _accessExternalDTD = (String)_tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_DTD);
         _readerManager = XMLReaderManager.getInstance(_useServicesMechanism);
+        _readerManager.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD);
         //_isIncremental = tfactory._incremental;
     }
 
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java
index f5e1c85..bef160d 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java
@@ -105,6 +105,8 @@
                     if (reader == null) {
                        try {
                            reader= XMLReaderFactory.createXMLReader();
+                           reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
+                                   xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
                        } catch (Exception e ) {
                            try {
 
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java
index ad11c04..23be56b 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java
@@ -20,18 +20,6 @@
 
 package com.sun.org.apache.xerces.internal.dom;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Vector;
-
-import com.sun.org.apache.xerces.internal.util.PropertyState;
-import com.sun.org.apache.xerces.internal.util.Status;
-import org.w3c.dom.DOMConfiguration;
-import org.w3c.dom.DOMErrorHandler;
-import org.w3c.dom.DOMStringList;
-
 import com.sun.org.apache.xerces.internal.impl.Constants;
 import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
 import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
@@ -42,7 +30,10 @@
 import com.sun.org.apache.xerces.internal.util.DOMErrorHandlerWrapper;
 import com.sun.org.apache.xerces.internal.util.MessageFormatter;
 import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings;
+import com.sun.org.apache.xerces.internal.util.PropertyState;
 import com.sun.org.apache.xerces.internal.util.SymbolTable;
+import com.sun.org.apache.xerces.internal.utils.ObjectFactory;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
 import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler;
 import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler;
 import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
@@ -55,12 +46,19 @@
 import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
 import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
-import com.sun.org.apache.xerces.internal.utils.ObjectFactory;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Vector;
+import javax.xml.XMLConstants;
+import org.w3c.dom.DOMConfiguration;
+import org.w3c.dom.DOMErrorHandler;
 import org.w3c.dom.DOMException;
+import org.w3c.dom.DOMStringList;
 import org.w3c.dom.ls.LSResourceResolver;
 
 
-
 /**
  * Xerces implementation of DOMConfiguration that maintains a table of recognized parameters.
  *
@@ -158,6 +156,14 @@
     protected static final String SCHEMA_DV_FACTORY =
         Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY;
 
+    /** Property identifier: access to external dtd */
+    protected static final String ACCESS_EXTERNAL_DTD =
+        XMLConstants.ACCESS_EXTERNAL_DTD;
+
+    /** Property identifier: access to external schema  */
+    protected static final String ACCESS_EXTERNAL_SCHEMA =
+        XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
     //
     // Data
     //
@@ -276,7 +282,9 @@
             JAXP_SCHEMA_SOURCE,
             JAXP_SCHEMA_LANGUAGE,
             DTD_VALIDATOR_FACTORY_PROPERTY,
-            SCHEMA_DV_FACTORY
+            SCHEMA_DV_FACTORY,
+            ACCESS_EXTERNAL_DTD,
+            ACCESS_EXTERNAL_SCHEMA
         };
         addRecognizedProperties(recognizedProperties);
 
@@ -310,6 +318,14 @@
         fValidationManager = createValidationManager();
         setProperty(VALIDATION_MANAGER, fValidationManager);
 
+        //For DOM, the secure feature is set to true by default
+        String accessExternal =  SecuritySupport.getDefaultAccessProperty(
+                Constants.SP_ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT);
+        setProperty(ACCESS_EXTERNAL_DTD, accessExternal);
+
+        accessExternal =  SecuritySupport.getDefaultAccessProperty(
+                Constants.SP_ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT);
+        setProperty(ACCESS_EXTERNAL_SCHEMA, accessExternal);
 
         // add message formatters
         if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java
index d6f457d..ec8a111 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java
@@ -20,6 +20,7 @@
 
 package com.sun.org.apache.xerces.internal.impl;
 
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
 import java.util.Enumeration;
 import java.util.NoSuchElementException;
 
@@ -138,6 +139,21 @@
 
     public static final String FEATURE_SECURE_PROCESSING = "http://javax.xml.XMLConstants/feature/secure-processing";
 
+    // Oracle Feature:
+    /**
+     * <p>Use Service Mechanism</p>
+     *
+     * <ul>
+     *   <li>
+     * {@code true} instruct an object to use service mechanism to
+     * find a service implementation. This is the default behavior.
+     *   </li>
+     *   <li>
+     * {@code false} instruct an object to skip service mechanism and
+     * use the default implementation for that service.
+     *   </li>
+     * </ul>
+     */
     public static final String ORACLE_FEATURE_SERVICE_MECHANISM = "http://www.oracle.com/feature/use-service-mechanism";
 
     /** Document XML version property ("document-xml-version"). */
@@ -160,6 +176,34 @@
 
     public static final String SYSTEM_PROPERTY_ELEMENT_ATTRIBUTE_LIMIT = "elementAttributeLimit" ;
 
+    /** JAXP Standard property prefix ("http://javax.xml.XMLConstants/property/"). */
+    public static final String JAXPAPI_PROPERTY_PREFIX =
+        "http://javax.xml.XMLConstants/property/";
+
+    /** Oracle JAXP property prefix ("http://www.oracle.com/xml/jaxp/properties/"). */
+    public static final String ORACLE_JAXP_PROPERTY_PREFIX =
+        "http://www.oracle.com/xml/jaxp/properties/";
+
+    //System Properties corresponding to ACCESS_EXTERNAL_* properties
+    public static final String SP_ACCESS_EXTERNAL_DTD = "javax.xml.accessExternalDTD";
+    public static final String SP_ACCESS_EXTERNAL_SCHEMA = "javax.xml.accessExternalSchema";
+    //all access keyword
+    public static final String ACCESS_EXTERNAL_ALL = "all";
+
+    /**
+     * Default value when FEATURE_SECURE_PROCESSING (FSP) is set to true
+     */
+    public static final String EXTERNAL_ACCESS_DEFAULT_FSP = "";
+    /**
+     * JDK version by which the default is to restrict external connection
+     */
+    public static final int RESTRICT_BY_DEFAULT_JDK_VERSION = 8;
+
+    /**
+     * FEATURE_SECURE_PROCESSING (FSP) is true by default
+     */
+    public static final String EXTERNAL_ACCESS_DEFAULT = getExternalAccessDefault(true);
+
     //
     // DOM features
     //
@@ -653,6 +697,59 @@
         ? new ArrayEnumeration(fgXercesProperties) : fgEmptyEnumeration;
     } // getXercesProperties():Enumeration
 
+    /**
+     * Determine the default value of the external access properties
+     *
+     * jaxp 1.5 does not require implementations to restrict by default
+     *
+     * For JDK8:
+     * The default value is 'file' (including jar:file); The keyword "all" grants permission
+     * to all protocols. When {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} is on,
+     * the default value is an empty string indicating no access is allowed.
+     *
+     * For JDK7:
+     * The default value is 'all' granting permission to all protocols. If by default,
+     * {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} is true, it should
+     * not change the default value. However, if {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING}
+     * is set explicitly, the values of the properties shall be set to an empty string
+     * indicating no access is allowed.
+     *
+     * @param isSecureProcessing indicating if Secure Processing is set
+     * @return default value
+     */
+    public static String getExternalAccessDefault(boolean isSecureProcessing) {
+        String defaultValue = "all";
+        if (isJDKandAbove(RESTRICT_BY_DEFAULT_JDK_VERSION)) {
+            defaultValue = "file";
+            if (isSecureProcessing) {
+                defaultValue = EXTERNAL_ACCESS_DEFAULT_FSP;
+            }
+        }
+        return defaultValue;
+    }
+
+    /*
+     * Check the version of the current JDK against that specified in the
+     * parameter
+     *
+     * There is a proposal to change the java version string to:
+     * MAJOR.MINOR.FU.CPU.PSU-BUILDNUMBER_BUGIDNUMBER_OPTIONAL
+     * This method would work with both the current format and that proposed
+     *
+     * @param compareTo a JDK version to be compared to
+     * @return true if the current version is the same or above that represented
+     * by the parameter
+     */
+    public static boolean isJDKandAbove(int compareTo) {
+        String javaVersion = SecuritySupport.getSystemProperty("java.version");
+        String versions[] = javaVersion.split("\\.", 3);
+        if (Integer.parseInt(versions[0]) >= compareTo ||
+            Integer.parseInt(versions[1]) >= compareTo) {
+            return true;
+        }
+        return false;
+    }
+
     //
     // Classes
     //
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java
index ead08fe..b85ea50 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java
@@ -25,13 +25,14 @@
 
 package com.sun.org.apache.xerces.internal.impl;
 
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
+import com.sun.xml.internal.stream.StaxEntityResolverWrapper;
 import java.util.HashMap;
+import javax.xml.XMLConstants;
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLOutputFactory;
 import javax.xml.stream.XMLResolver;
 
-import com.sun.xml.internal.stream.StaxEntityResolverWrapper;
-
 /**
  *  This class manages different properties related to Stax specification and its implementation.
  * This class constructor also takes itself (PropertyManager object) as parameter and initializes the
@@ -51,6 +52,12 @@
     private static final String STRING_INTERNING = "http://xml.org/sax/features/string-interning";
 
 
+    /** Property identifier: access to external dtd */
+    protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+    /** Property identifier: access to external schema  */
+    protected static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
     HashMap supportedProps = new HashMap();
 
     public static final int CONTEXT_READER = 1;
@@ -117,6 +124,15 @@
         supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE, new Boolean(false));
         supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE, new Boolean(false));
         supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE, new Boolean(false));
+
+        //For DOM/SAX, the secure feature is set to true by default
+        String accessExternal =  SecuritySupport.getDefaultAccessProperty(
+                Constants.SP_ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT);
+        supportedProps.put(ACCESS_EXTERNAL_DTD, accessExternal);
+
+        accessExternal =  SecuritySupport.getDefaultAccessProperty(
+                Constants.SP_ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT);
+        supportedProps.put(ACCESS_EXTERNAL_SCHEMA, accessExternal);
     }
 
     private void initWriterProps(){
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java
index abbd696..82c009b 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java
@@ -52,7 +52,10 @@
 import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler;
 import com.sun.org.apache.xerces.internal.util.SecurityManager;
 import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
 import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
+import com.sun.xml.internal.stream.Entity;
+import javax.xml.XMLConstants;
 import javax.xml.stream.XMLStreamConstants;
 import javax.xml.stream.events.XMLEvent;
 
@@ -159,6 +162,18 @@
     protected static final String ENTITY_RESOLVER =
             Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY;
 
+    /** Feature identifier: standard uri conformant */
+    protected static final String STANDARD_URI_CONFORMANT =
+            Constants.XERCES_FEATURE_PREFIX +Constants.STANDARD_URI_CONFORMANT_FEATURE;
+
+    /** property identifier: access external dtd. */
+    protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+    /** access external dtd: file protocol
+     *  For DOM/SAX, the secure feature is set to true by default
+     */
+    final static String EXTERNAL_ACCESS_DEFAULT = Constants.EXTERNAL_ACCESS_DEFAULT;
+
     // recognized features and properties
 
     /** Recognized features. */
@@ -184,6 +199,7 @@
         SYMBOL_TABLE,
                 ERROR_REPORTER,
                 ENTITY_MANAGER,
+                ACCESS_EXTERNAL_DTD
     };
 
     /** Property defaults. */
@@ -191,6 +207,7 @@
                 null,
                 null,
                 null,
+                EXTERNAL_ACCESS_DEFAULT
     };
 
     private static final char [] cdata = {'[','C','D','A','T','A','['};
@@ -297,6 +314,17 @@
     protected String fDeclaredEncoding =  null;
     /** Xerces Feature: Disallow doctype declaration. */
     protected boolean fDisallowDoctype = false;
+    /**
+     * comma-delimited list of protocols that are allowed for the purpose
+     * of accessing external dtd or entity references
+     */
+    protected String fAccessExternalDTD = EXTERNAL_ACCESS_DEFAULT;
+
+    /**
+     * standard uri conformant (strict uri).
+     * http://apache.org/xml/features/standard-uri-conformant
+     */
+    protected boolean fStrictURI;
 
     // drivers
 
@@ -413,17 +441,6 @@
      *
      * @return True if there is more to scan, false otherwise.
      */
-   /* public boolean scanDocument(boolean complete)
-    throws IOException, XNIException {
-
-        // keep dispatching "events"
-        fEntityManager.setEntityHandler(this);
-
-        return true;
-
-    } // scanDocument(boolean):boolean
-    */
-
     public boolean scanDocument(boolean complete)
     throws IOException, XNIException {
 
@@ -579,6 +596,9 @@
         //xxx: external entities are supported in Xerces
         // it would be good to define feature for this case
         fSupportExternalEntities = true;
+        fSupportExternalEntities = true;
+        fSupportExternalEntities = true;
+        fSupportExternalEntities = true;
         fReplaceEntityReferences = true;
         fIsCoalesce = false;
 
@@ -589,6 +609,9 @@
 
         dtdGrammarUtil = null;
 
+        // JAXP 1.5 features and properties
+        fAccessExternalDTD = (String) componentManager.getProperty(ACCESS_EXTERNAL_DTD, EXTERNAL_ACCESS_DEFAULT);
+        fStrictURI = componentManager.getFeature(STANDARD_URI_CONFORMANT, false);
 
         //fEntityManager.test();
     } // reset(XMLComponentManager)
@@ -639,6 +662,9 @@
 
         dtdGrammarUtil = null;
 
+        // Oracle jdk feature
+        fAccessExternalDTD = (String) propertyManager.getProperty(ACCESS_EXTERNAL_DTD);
+
     } // reset(XMLComponentManager)
 
     /**
@@ -735,6 +761,14 @@
             return;
         }
 
+        //JAXP 1.5 properties
+        if (propertyId.startsWith(Constants.JAXPAPI_PROPERTY_PREFIX)) {
+            if (propertyId.equals(ACCESS_EXTERNAL_DTD))
+            {
+                fAccessExternalDTD = (String)value;
+            }
+        }
+
     } // setProperty(String,Object)
 
     /**
@@ -1846,7 +1880,8 @@
         //1. if the entity is external and support to external entities is not required
         // 2. or entities should not be replaced
         //3. or if it is built in entity reference.
-        if((fEntityStore.isExternalEntity(name) && !fSupportExternalEntities) || (!fEntityStore.isExternalEntity(name) && !fReplaceEntityReferences) || foundBuiltInRefs){
+        boolean isEE = fEntityStore.isExternalEntity(name);
+        if((isEE && !fSupportExternalEntities) || (!isEE && !fReplaceEntityReferences) || foundBuiltInRefs){
             fScannerState = SCANNER_STATE_REFERENCE;
             return ;
         }
@@ -1996,6 +2031,12 @@
 
     } // getDriverName():String
 
+    String checkAccess(String systemId, String allowedProtocols) throws IOException {
+        String baseSystemId = fEntityScanner.getBaseSystemId();
+        String expandedSystemId = fEntityManager.expandSystemId(systemId, baseSystemId,fStrictURI);
+        return SecuritySupport.checkAccess(expandedSystemId, allowedProtocols, Constants.ACCESS_EXTERNAL_ALL);
+    }
+
     //
     // Classes
     //
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java
index b6ef755..b043c9d3b 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java
@@ -21,6 +21,22 @@
 package com.sun.org.apache.xerces.internal.impl;
 
 
+import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDDescription;
+import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
+import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
+import com.sun.org.apache.xerces.internal.util.XMLChar;
+import com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl;
+import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
+import com.sun.org.apache.xerces.internal.xni.Augmentations;
+import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
+import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
+import com.sun.org.apache.xerces.internal.xni.XMLString;
+import com.sun.org.apache.xerces.internal.xni.XNIException;
+import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
+import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
+import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDScanner;
+import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
 import com.sun.xml.internal.stream.Entity;
 import com.sun.xml.internal.stream.StaxXMLInputSource;
 import com.sun.xml.internal.stream.dtd.DTDGrammarUtil;
@@ -29,23 +45,6 @@
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.events.XMLEvent;
 
-import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
-import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
-import com.sun.org.apache.xerces.internal.util.XMLChar;
-import com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl;
-import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
-import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
-import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
-import com.sun.org.apache.xerces.internal.xni.XMLString;
-import com.sun.org.apache.xerces.internal.xni.XNIException;
-import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
-import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
-import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
-import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDScanner;
-import com.sun.org.apache.xerces.internal.xni.Augmentations;
-import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDDescription;
-import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentScanner;
-
 
 /**
  * This class is responsible for scanning XML document structure
@@ -148,7 +147,7 @@
 
     /** Property defaults. */
     private static final Object[] PROPERTY_DEFAULTS = {
-        null,
+            null,
                 null
     };
 
@@ -920,7 +919,6 @@
                             reportFatalError("DoctypeNotAllowed", null);
                         }
 
-
                         if (fSeenDoctypeDecl) {
                             reportFatalError("AlreadySeenDoctype", null);
                         }
@@ -952,15 +950,18 @@
                         if (fDoctypeSystemId != null) {
                             if (((fValidation || fLoadExternalDTD)
                                 && (fValidationManager == null || !fValidationManager.isCachedDTD()))) {
-                            if (fSupportDTD)
-                                setScannerState(SCANNER_STATE_DTD_EXTERNAL);
-                            else
-                                setScannerState(SCANNER_STATE_PROLOG);
-                            setDriver(fContentDriver);
-                            if(fDTDDriver == null)
-                                fDTDDriver = new DTDDriver();
-                            return fDTDDriver.next();
+                                if (fSupportDTD) {
+                                    setScannerState(SCANNER_STATE_DTD_EXTERNAL);
+                                } else {
+                                    setScannerState(SCANNER_STATE_PROLOG);
+                                }
 
+                                setDriver(fContentDriver);
+                                if(fDTDDriver == null) {
+                                    fDTDDriver = new DTDDriver();
+                                }
+
+                                return fDTDDriver.next();
                             }
                         }
                         else if (fExternalSubsetSource != null) {
@@ -1149,9 +1150,21 @@
                             resourceIdentifier.setValues(fDoctypePublicId, fDoctypeSystemId, null, null);
                             XMLInputSource xmlInputSource = null ;
                             StaxXMLInputSource staxInputSource =  fEntityManager.resolveEntityAsPerStax(resourceIdentifier);
+
+                            // Check access permission. If the source is resolved by a resolver, the check is skipped.
+                            if (!staxInputSource.hasResolver()) {
+                                String accessError = checkAccess(fDoctypeSystemId, fAccessExternalDTD);
+                                if (accessError != null) {
+                                    reportFatalError("AccessExternalDTD", new Object[]{ SecuritySupport.sanitizePath(fDoctypeSystemId), accessError });
+                                }
+                            }
                             xmlInputSource = staxInputSource.getXMLInputSource();
                             fDTDScanner.setInputSource(xmlInputSource);
-                            setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
+                            if (fEntityScanner.fCurrentEntity != null) {
+                                setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
+                            } else {
+                                setScannerState(SCANNER_STATE_PROLOG);
+                            }
                             again = true;
                             break;
                         }
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java
index b761fc4..547a3a5 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2006, 2013 Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -20,51 +20,37 @@
 
 package com.sun.org.apache.xerces.internal.impl ;
 
+import com.sun.org.apache.xerces.internal.impl.Constants;
+import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader;
+import com.sun.org.apache.xerces.internal.impl.io.UCSReader;
+import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader;
+import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
+import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler;
+import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
+import com.sun.org.apache.xerces.internal.util.*;
+import com.sun.org.apache.xerces.internal.util.SecurityManager;
+import com.sun.org.apache.xerces.internal.util.URI;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
+import com.sun.org.apache.xerces.internal.xni.Augmentations;
+import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
+import com.sun.org.apache.xerces.internal.xni.XNIException;
+import com.sun.org.apache.xerces.internal.xni.parser.*;
+import com.sun.xml.internal.stream.Entity;
 import com.sun.xml.internal.stream.StaxEntityResolverWrapper;
 import com.sun.xml.internal.stream.StaxXMLInputSource;
 import com.sun.xml.internal.stream.XMLEntityStorage;
 import java.io.*;
-import java.io.BufferedReader;
-import java.util.*;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.StringReader;
 import java.lang.reflect.Method;
 import java.net.HttpURLConnection;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLConnection;
-import java.net.URISyntaxException;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Stack;
-
-
-import com.sun.org.apache.xerces.internal.impl.io.*;
-import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
-import com.sun.org.apache.xerces.internal.util.*;
-import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
-import com.sun.org.apache.xerces.internal.xni.XNIException;
-import com.sun.org.apache.xerces.internal.xni.parser.*;
-import com.sun.org.apache.xerces.internal.impl.Constants;
-import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
-import com.sun.xml.internal.stream.Entity;
-import com.sun.org.apache.xerces.internal.xni.Augmentations;
-
-import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader;
-import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader;
-import com.sun.org.apache.xerces.internal.impl.io.UCSReader;
-import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler;
-import com.sun.org.apache.xerces.internal.util.HTTPInputSource;
-import com.sun.org.apache.xerces.internal.xinclude.XIncludeHandler;
-
-import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
-import com.sun.org.apache.xerces.internal.util.SecurityManager;
-import com.sun.org.apache.xerces.internal.util.URI;
+import javax.xml.XMLConstants;
 
 
 /**
@@ -140,6 +126,10 @@
     protected static final String WARN_ON_DUPLICATE_ENTITYDEF =
             Constants.XERCES_FEATURE_PREFIX +Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE;
 
+    /** Feature identifier: load external DTD. */
+    protected static final String LOAD_EXTERNAL_DTD =
+            Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE;
+
     // property identifiers
 
     /** Property identifier: symbol table. */
@@ -173,8 +163,16 @@
     protected static final String SECURITY_MANAGER =
         Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
 
-protected static final String PARSER_SETTINGS =
+    protected static final String PARSER_SETTINGS =
         Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS;
+
+    /** property identifier: access external dtd. */
+    protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+    /** access external dtd: file protocol */
+    static final String EXTERNAL_ACCESS_DEFAULT = Constants.EXTERNAL_ACCESS_DEFAULT;
+
+
     // recognized features and properties
 
     /** Recognized features. */
@@ -205,7 +203,7 @@
                 VALIDATION_MANAGER,
                 BUFFER_SIZE,
                 SECURITY_MANAGER,
-
+                ACCESS_EXTERNAL_DTD
     };
 
     /** Property defaults. */
@@ -215,7 +213,8 @@
                 null,
                 null,
                 new Integer(DEFAULT_BUFFER_SIZE),
-                null
+                null,
+                EXTERNAL_ACCESS_DEFAULT
     };
 
     private static final String XMLEntity = "[xml]".intern();
@@ -274,6 +273,8 @@
      */
     protected boolean fAllowJavaEncodings = true ;
 
+    /** Load external DTD. */
+    protected boolean fLoadExternalDTD = true;
 
     // properties
 
@@ -302,7 +303,8 @@
     /** Property Manager. This is used from Stax */
     protected PropertyManager fPropertyManager ;
 
-
+    /** used to restrict external access */
+    protected String fAccessExternalDTD = EXTERNAL_ACCESS_DEFAULT;
     // settings
 
     /**
@@ -366,6 +368,9 @@
     /** Current entity. */
     protected Entity.ScannedEntity fCurrentEntity = null;
 
+    /** identify if the InputSource is created by a resolver */
+    boolean fISCreatedByResolver = false;
+
     // shared context
 
     protected XMLEntityStorage fEntityStorage ;
@@ -965,18 +970,25 @@
             System.out.println("BEFORE Calling resolveEntity") ;
         }
 
+        fISCreatedByResolver = false;
         //either of Stax or Xerces would be null
         if(fStaxEntityResolver != null){
             staxInputSource = fStaxEntityResolver.resolveEntity(ri);
+            if(staxInputSource != null) {
+                fISCreatedByResolver = true;
+            }
         }
 
         if(fEntityResolver != null){
             xmlInputSource = fEntityResolver.resolveEntity(ri);
+            if(xmlInputSource != null) {
+                fISCreatedByResolver = true;
+            }
         }
 
         if(xmlInputSource != null){
             //wrap this XMLInputSource to StaxInputSource
-            staxInputSource = new StaxXMLInputSource(xmlInputSource);
+            staxInputSource = new StaxXMLInputSource(xmlInputSource, fISCreatedByResolver);
         }
 
         // do default resolution
@@ -1108,7 +1120,13 @@
 
         // should we skip external entities?
         boolean external = entity.isExternal();
+        Entity.ExternalEntity externalEntity = null;
+        String extLitSysId = null, extBaseSysId = null, expandedSystemId = null;
         if (external) {
+            externalEntity = (Entity.ExternalEntity)entity;
+            extLitSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getLiteralSystemId() : null);
+            extBaseSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getBaseSystemId() : null);
+            expandedSystemId = expandSystemId(extLitSysId, extBaseSysId);
             boolean unparsed = entity.isUnparsed();
             boolean parameter = entityName.startsWith("%");
             boolean general = !parameter;
@@ -1118,13 +1136,6 @@
                 if (fEntityHandler != null) {
                     fResourceIdentifier.clear();
                     final String encoding = null;
-                    Entity.ExternalEntity externalEntity = (Entity.ExternalEntity)entity;
-                    //REVISIT:  since we're storing expandedSystemId in the
-                    // externalEntity, how could this have got here if it wasn't already
-                    // expanded??? - neilg
-                    String extLitSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getLiteralSystemId() : null);
-                    String extBaseSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getBaseSystemId() : null);
-                    String expandedSystemId = expandSystemId(extLitSysId, extBaseSysId);
                     fResourceIdentifier.setValues(
                             (externalEntity.entityLocation != null ? externalEntity.entityLocation.getPublicId() : null),
                             extLitSysId, extBaseSysId, expandedSystemId);
@@ -1162,11 +1173,6 @@
                             fResourceIdentifier.clear();
                             final String encoding = null;
                             if (external) {
-                                Entity.ExternalEntity externalEntity = (Entity.ExternalEntity)entity;
-                                // REVISIT:  for the same reason above...
-                                String extLitSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getLiteralSystemId() : null);
-                                String extBaseSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getBaseSystemId() : null);
-                                String expandedSystemId = expandSystemId(extLitSysId, extBaseSysId);
                                 fResourceIdentifier.setValues(
                                         (externalEntity.entityLocation != null ? externalEntity.entityLocation.getPublicId() : null),
                                         extLitSysId, extBaseSysId, expandedSystemId);
@@ -1188,7 +1194,6 @@
         XMLInputSource xmlInputSource = null ;
 
         if (external) {
-            Entity.ExternalEntity externalEntity = (Entity.ExternalEntity)entity;
             staxInputSource = resolveEntityAsPerStax(externalEntity.entityLocation);
             /** xxx:  Waiting from the EG
              * //simply return if there was entity resolver registered and application
@@ -1196,6 +1201,18 @@
              * if(staxInputSource.hasXMLStreamOrXMLEventReader()) return ;
              */
             xmlInputSource = staxInputSource.getXMLInputSource() ;
+            if (!fISCreatedByResolver) {
+                //let the not-LoadExternalDTD or not-SupportDTD process to handle the situation
+                if (fLoadExternalDTD) {
+                    String accessError = SecuritySupport.checkAccess(expandedSystemId, fAccessExternalDTD, Constants.ACCESS_EXTERNAL_ALL);
+                    if (accessError != null) {
+                        fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN,
+                                "AccessExternalEntity",
+                                new Object[] { SecuritySupport.sanitizePath(expandedSystemId), accessError },
+                                XMLErrorReporter.SEVERITY_FATAL_ERROR);
+                    }
+                }
+            }
         }
         // wrap internal entity
         else {
@@ -1400,6 +1417,12 @@
             fStaxEntityResolver = null;
         }
 
+        // Zephyr feature ignore-external-dtd is the opposite of Xerces' load-external-dtd
+        fLoadExternalDTD = !((Boolean)propertyManager.getProperty(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.IGNORE_EXTERNAL_DTD)).booleanValue();
+
+        // JAXP 1.5 feature
+        fAccessExternalDTD = (String) propertyManager.getProperty(ACCESS_EXTERNAL_DTD);
+
         // initialize state
         //fStandalone = false;
         fEntities.clear();
@@ -1409,8 +1432,6 @@
         fExternalGeneralEntities = true;
         fExternalParameterEntities = true;
         fAllowJavaEncodings = true ;
-
-        //test();
     }
 
     /**
@@ -1453,6 +1474,7 @@
         fAllowJavaEncodings = componentManager.getFeature(ALLOW_JAVA_ENCODINGS, false);
         fWarnDuplicateEntityDef = componentManager.getFeature(WARN_ON_DUPLICATE_ENTITYDEF, false);
         fStrictURI = componentManager.getFeature(STANDARD_URI_CONFORMANT, false);
+        fLoadExternalDTD = componentManager.getFeature(LOAD_EXTERNAL_DTD, true);
 
         // xerces properties
         fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE);
@@ -1462,6 +1484,9 @@
         fValidationManager = (ValidationManager)componentManager.getProperty(VALIDATION_MANAGER, null);
         fSecurityManager = (SecurityManager)componentManager.getProperty(SECURITY_MANAGER, null);
 
+        // JAXP 1.5 feature
+        fAccessExternalDTD = (String) componentManager.getProperty(ACCESS_EXTERNAL_DTD, EXTERNAL_ACCESS_DEFAULT);
+
         //reset general state
         reset();
 
@@ -1554,6 +1579,11 @@
                 featureId.endsWith(Constants.ALLOW_JAVA_ENCODINGS_FEATURE)) {
                 fAllowJavaEncodings = state;
             }
+            if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() &&
+                featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) {
+                fLoadExternalDTD = state;
+                return;
+            }
         }
 
     } // setFeature(String,boolean)
@@ -1610,7 +1640,15 @@
             }
         }
 
+        //JAXP 1.5 properties
+        if (propertyId.startsWith(Constants.JAXPAPI_PROPERTY_PREFIX)) {
+            if (propertyId.equals(ACCESS_EXTERNAL_DTD))
+            {
+                fAccessExternalDTD = (String)value;
+            }
+        }
     }
+
     /**
      * Returns a list of property identifiers that are recognized by
      * this component. This method may return null if no properties
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/AbstractDateTimeDV.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/AbstractDateTimeDV.java
index e69c9e5..d9d6587 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/AbstractDateTimeDV.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/AbstractDateTimeDV.java
@@ -51,456 +51,471 @@
  */
 public abstract class AbstractDateTimeDV extends TypeValidator {
 
-        //debugging
-        private static final boolean DEBUG=false;
-
-        //define shared variables for date/time
-
-
-        //define constants to be used in assigning default values for
-        //all date/time excluding duration
-        protected final static int YEAR=2000;
-        protected final static int MONTH=01;
-        protected final static int DAY = 01;
-
+    //debugging
+    private static final boolean DEBUG = false;
+    //define shared variables for date/time
+    //define constants to be used in assigning default values for
+    //all date/time excluding duration
+    protected final static int YEAR = 2000;
+    protected final static int MONTH = 01;
+    protected final static int DAY = 01;
     protected static final DatatypeFactory datatypeFactory = new DatatypeFactoryImpl();
 
-        public short getAllowedFacets(){
-                return ( XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION |XSSimpleTypeDecl.FACET_MAXINCLUSIVE |XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE  | XSSimpleTypeDecl.FACET_MINEXCLUSIVE  );
-        }//getAllowedFacets()
+    @Override
+    public short getAllowedFacets() {
+        return (XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION | XSSimpleTypeDecl.FACET_MAXINCLUSIVE | XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE | XSSimpleTypeDecl.FACET_MINEXCLUSIVE);
+    }//getAllowedFacets()
 
-
-        // distinguishes between identity and equality for date/time values
-        // ie: two values representing the same "moment in time" but with different
-        // remembered timezones are now equal but not identical.
-        public boolean isIdentical (Object value1, Object value2) {
-                if (!(value1 instanceof DateTimeData) || !(value2 instanceof DateTimeData)) {
-                        return false;
-                }
-
-                DateTimeData v1 = (DateTimeData)value1;
-                DateTimeData v2 = (DateTimeData)value2;
-
-                // original timezones must be the same in addition to date/time values
-                // being 'equal'
-                if ((v1.timezoneHr == v2.timezoneHr) && (v1.timezoneMin == v2.timezoneMin)) {
-                        return v1.equals(v2);
-                }
-
-                return false;
-        }//isIdentical()
-
-        // the parameters are in compiled form (from getActualValue)
-        public int compare (Object value1, Object value2) {
-                return compareDates(((DateTimeData)value1),
-                                ((DateTimeData)value2), true);
-        }//compare()
-
-        /**
-         * Compare algorithm described in dateDime (3.2.7).
-         * Duration datatype overwrites this method
-         *
-         * @param date1  normalized date representation of the first value
-         * @param date2  normalized date representation of the second value
-         * @param strict
-         * @return less, greater, less_equal, greater_equal, equal
-         */
-        protected short compareDates(DateTimeData date1, DateTimeData date2, boolean strict) {
-                if (date1.utc == date2.utc) {
-                        return compareOrder(date1, date2);
-                }
-                short c1, c2;
-
-                DateTimeData tempDate = new DateTimeData(null, this);
-
-                if ( date1.utc=='Z' ) {
-
-                        //compare date1<=date1<=(date2 with time zone -14)
-                        //
-                        cloneDate(date2, tempDate); //clones date1 value to global temporary storage: fTempDate
-                        tempDate.timezoneHr=14;
-                        tempDate.timezoneMin = 0;
-                        tempDate.utc='+';
-                        normalize(tempDate);
-                        c1 = compareOrder(date1, tempDate);
-                        if (c1 == LESS_THAN)
-                                return c1;
-
-                        //compare date1>=(date2 with time zone +14)
-                        //
-                        cloneDate(date2, tempDate); //clones date1 value to global temporary storage: tempDate
-                        tempDate.timezoneHr = -14;
-                        tempDate.timezoneMin = 0;
-                        tempDate.utc='-';
-                        normalize(tempDate);
-                        c2 = compareOrder(date1, tempDate);
-                        if (c2 == GREATER_THAN)
-                                return c2;
-
-                        return INDETERMINATE;
-                }
-                else if ( date2.utc=='Z' ) {
-
-                        //compare (date1 with time zone -14)<=date2
-                        //
-                        cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate
-                        tempDate.timezoneHr = -14;
-                        tempDate.timezoneMin = 0;
-                        tempDate.utc='-';
-                        if (DEBUG) {
-                                System.out.println("tempDate=" + dateToString(tempDate));
-                        }
-                        normalize(tempDate);
-                        c1 = compareOrder(tempDate, date2);
-                        if (DEBUG) {
-                                System.out.println("date=" + dateToString(date2));
-                                System.out.println("tempDate=" + dateToString(tempDate));
-                        }
-                        if (c1 == LESS_THAN)
-                                return c1;
-
-                        //compare (date1 with time zone +14)<=date2
-                        //
-                        cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate
-                        tempDate.timezoneHr = 14;
-                        tempDate.timezoneMin = 0;
-                        tempDate.utc='+';
-                        normalize(tempDate);
-                        c2 = compareOrder(tempDate, date2);
-                        if (DEBUG) {
-                                System.out.println("tempDate=" + dateToString(tempDate));
-                        }
-                        if (c2 == GREATER_THAN)
-                                return c2;
-
-                        return INDETERMINATE;
-                }
-                return INDETERMINATE;
-
+    // distinguishes between identity and equality for date/time values
+    // ie: two values representing the same "moment in time" but with different
+    // remembered timezones are now equal but not identical.
+    @Override
+    public boolean isIdentical(Object value1, Object value2) {
+        if (!(value1 instanceof DateTimeData) || !(value2 instanceof DateTimeData)) {
+            return false;
         }
 
-        /**
-         * Given normalized values, determines order-relation
-         * between give date/time objects.
-         *
-         * @param date1  date/time object
-         * @param date2  date/time object
-         * @return 0 if date1 and date2 are equal, a value less than 0 if date1 is less than date2, a value greater than 0 if date1 is greater than date2
-         */
-        protected short compareOrder(DateTimeData date1, DateTimeData date2) {
-                if(date1.position < 1) {
-                        if (date1.year < date2.year)
-                                return -1;
-                        if (date1.year > date2.year)
-                                return 1;
-                }
-                if(date1.position < 2) {
-                        if (date1.month < date2.month)
-                                return -1;
-                        if (date1.month > date2.month)
-                                return 1;
-                }
-                if (date1.day < date2.day)
-                        return -1;
-                if (date1.day > date2.day)
-                        return 1;
-                if (date1.hour < date2.hour)
-                        return -1;
-                if (date1.hour > date2.hour)
-                        return 1;
-                if (date1.minute < date2.minute)
-                        return -1;
-                if (date1.minute > date2.minute)
-                        return 1;
-                if (date1.second < date2.second)
-                        return -1;
-                if (date1.second > date2.second)
-                        return 1;
-                if (date1.utc < date2.utc)
-                        return -1;
-                if (date1.utc > date2.utc)
-                        return 1;
-                return 0;
+        DateTimeData v1 = (DateTimeData) value1;
+        DateTimeData v2 = (DateTimeData) value2;
+
+        // original timezones must be the same in addition to date/time values
+        // being 'equal'
+        if ((v1.timezoneHr == v2.timezoneHr) && (v1.timezoneMin == v2.timezoneMin)) {
+            return v1.equals(v2);
         }
 
-        /**
-         * Parses time hh:mm:ss.sss and time zone if any
-         *
-         * @param start
-         * @param end
-         * @param data
-         * @exception RuntimeException
-         */
-        protected  void getTime (String buffer, int start, int end, DateTimeData data) throws RuntimeException{
+        return false;
+    }//isIdentical()
 
-                int stop = start+2;
-
-                //get hours (hh)
-                data.hour=parseInt(buffer, start,stop);
-
-                //get minutes (mm)
-
-                if (buffer.charAt(stop++)!=':') {
-                        throw new RuntimeException("Error in parsing time zone" );
-                }
-                start = stop;
-                stop = stop+2;
-                data.minute=parseInt(buffer, start,stop);
-
-                //get seconds (ss)
-                if (buffer.charAt(stop++)!=':') {
-                        throw new RuntimeException("Error in parsing time zone" );
-                }
-
-                //find UTC sign if any
-                int sign = findUTCSign(buffer, start, end);
-
-                //get seconds (ms)
-                start = stop;
-                stop = sign < 0 ? end : sign;
-                data.second = parseSecond(buffer, start, stop);
-
-                //parse UTC time zone (hh:mm)
-                if (sign > 0) {
-                        getTimeZone(buffer, data, sign, end);
-                }
-        }
-
-        /**
-         * Parses date CCYY-MM-DD
-         *
-         * @param buffer
-         * @param start start position
-         * @param end end position
-         * @param date
-         * @exception RuntimeException
-         */
-        protected int getDate (String buffer, int start, int end, DateTimeData date) throws RuntimeException{
-
-                start = getYearMonth(buffer, start, end, date);
-
-                if (buffer.charAt(start++) !='-') {
-                        throw new RuntimeException("CCYY-MM must be followed by '-' sign");
-                }
-                int stop = start + 2;
-                date.day=parseInt(buffer, start, stop);
-                return stop;
-        }
-
-        /**
-         * Parses date CCYY-MM
-         *
-         * @param buffer
-         * @param start start position
-         * @param end end position
-         * @param date
-         * @exception RuntimeException
-         */
-        protected int getYearMonth (String buffer, int start, int end, DateTimeData date) throws RuntimeException{
-
-                if ( buffer.charAt(0)=='-' ) {
-                        // REVISIT: date starts with preceding '-' sign
-                        //          do we have to do anything with it?
-                        //
-                        start++;
-                }
-                int i = indexOf(buffer, start, end, '-');
-                if ( i==-1 ) throw new RuntimeException("Year separator is missing or misplaced");
-                int length = i-start;
-                if (length<4) {
-                        throw new RuntimeException("Year must have 'CCYY' format");
-                }
-                else if (length > 4 && buffer.charAt(start)=='0'){
-                        throw new RuntimeException("Leading zeros are required if the year value would otherwise have fewer than four digits; otherwise they are forbidden");
-                }
-                date.year= parseIntYear(buffer, i);
-                if (buffer.charAt(i)!='-') {
-                        throw new RuntimeException("CCYY must be followed by '-' sign");
-                }
-                start = ++i;
-                i = start +2;
-                date.month=parseInt(buffer, start, i);
-                return i; //fStart points right after the MONTH
-        }
-
-        /**
-         * Shared code from Date and YearMonth datatypes.
-         * Finds if time zone sign is present
-         *
-         * @param end
-         * @param date
-         * @exception RuntimeException
-         */
-        protected void parseTimeZone (String buffer, int start, int end, DateTimeData date) throws RuntimeException{
-
-                //fStart points right after the date
-
-                if ( start < end ) {
-                        if (!isNextCharUTCSign(buffer, start, end)) {
-                                throw new RuntimeException ("Error in month parsing");
-                        }
-                        else {
-                                getTimeZone(buffer, date, start, end);
-                        }
-                }
-        }
-
-        /**
-         * Parses time zone: 'Z' or {+,-} followed by  hh:mm
-         *
-         * @param data
-         * @param sign
-         * @exception RuntimeException
-         */
-        protected void getTimeZone (String buffer, DateTimeData data, int sign, int end) throws RuntimeException{
-                data.utc=buffer.charAt(sign);
-
-                if ( buffer.charAt(sign) == 'Z' ) {
-                        if (end>(++sign)) {
-                                throw new RuntimeException("Error in parsing time zone");
-                        }
-                        return;
-                }
-                if ( sign<=(end-6) ) {
-
-                        int negate = buffer.charAt(sign) == '-'?-1:1;
-                        //parse hr
-                        int stop = ++sign+2;
-                        data.timezoneHr = negate*parseInt(buffer, sign, stop);
-                        if (buffer.charAt(stop++)!=':') {
-                                throw new RuntimeException("Error in parsing time zone" );
-                        }
-
-                        //parse min
-                        data.timezoneMin = negate*parseInt(buffer, stop, stop+2);
-
-                        if ( stop+2!=end ) {
-                                throw new RuntimeException("Error in parsing time zone");
-                        }
-            if(data.timezoneHr != 0 || data.timezoneMin != 0)
-                data.normalized = false;
-                }
-                else {
-                        throw new RuntimeException("Error in parsing time zone");
-                }
-                if ( DEBUG ) {
-                        System.out.println("time[hh]="+data.timezoneHr + " time[mm]=" +data.timezoneMin);
-                }
-        }
-
-        /**
-         * Computes index of given char within StringBuffer
-         *
-         * @param start
-         * @param end
-         * @param ch     character to look for in StringBuffer
-         * @return index of ch within StringBuffer
-         */
-        protected  int indexOf (String buffer, int start, int end, char ch) {
-                for ( int i=start;i<end;i++ ) {
-                        if ( buffer.charAt(i) == ch ) {
-                                return i;
-                        }
-                }
-                return -1;
-        }
-
-        /**
-         * Validates given date/time object accoring to W3C PR Schema
-         * [D.1 ISO 8601 Conventions]
-         *
-         * @param data
-         */
-        protected void validateDateTime (DateTimeData data) {
-
-                //REVISIT: should we throw an exception for not valid dates
-                //          or reporting an error message should be sufficient?
-
-                /**
-                 * XML Schema 1.1 - RQ-123: Allow year 0000 in date related types.
-                 */
-                if (!Constants.SCHEMA_1_1_SUPPORT && data.year==0 ) {
-                        throw new RuntimeException("The year \"0000\" is an illegal year value");
-
-                }
-
-                if ( data.month<1 || data.month>12 ) {
-                        throw new RuntimeException("The month must have values 1 to 12");
-
-                }
-
-                //validate days
-                if ( data.day>maxDayInMonthFor(data.year, data.month) || data.day<1 ) {
-                        throw new RuntimeException("The day must have values 1 to 31");
-                }
-
-                //validate hours
-                if ( data.hour>23 || data.hour<0 ) {
-                        if (data.hour == 24 && data.minute == 0 && data.second == 0) {
-                                data.hour = 0;
-                                if (++data.day > maxDayInMonthFor(data.year, data.month)) {
-                                        data.day = 1;
-                                        if (++data.month > 12) {
-                                                data.month = 1;
-                                                if (Constants.SCHEMA_1_1_SUPPORT) {
-                                                        ++data.year;
-                                                }
-                                                else if (++data.year == 0) {
-                                                        data.year = 1;
-                                                }
-                                        }
-                                }
-                        }
-                        else {
-                                throw new RuntimeException("Hour must have values 0-23, unless 24:00:00");
-                        }
-                }
-
-                //validate
-                if ( data.minute>59 || data.minute<0 ) {
-                        throw new RuntimeException("Minute must have values 0-59");
-                }
-
-                //validate
-                if ( data.second>=60 || data.second<0 ) {
-                        throw new RuntimeException("Second must have values 0-59");
-
-                }
-
-                //validate
-                if ( data.timezoneHr>14 || data.timezoneHr<-14 ) {
-                        throw new RuntimeException("Time zone should have range -14:00 to +14:00");
-                }
-                else {
-                        if((data.timezoneHr == 14 || data.timezoneHr == -14) && data.timezoneMin != 0)
-                                throw new RuntimeException("Time zone should have range -14:00 to +14:00");
-                        else if(data.timezoneMin > 59 || data.timezoneMin < -59)
-                                throw new RuntimeException("Minute must have values 0-59");
-                }
-
-        }
-
-        /**
-         * Return index of UTC char: 'Z', '+', '-'
-         *
-         * @param start
-         * @param end
-         * @return index of the UTC character that was found
-         */
-        protected int findUTCSign (String buffer, int start, int end) {
-                int c;
-                for ( int i=start;i<end;i++ ) {
-                        c=buffer.charAt(i);
-                        if ( c == 'Z' || c=='+' || c=='-' ) {
-                                return i;
-                        }
-
-                }
-                return -1;
-        }
+    // the parameters are in compiled form (from getActualValue)
+    @Override
+    public int compare(Object value1, Object value2) {
+        return compareDates(((DateTimeData) value1),
+                ((DateTimeData) value2), true);
+    }//compare()
 
     /**
-     * Returns <code>true</code> if the character at start is 'Z', '+' or '-'.
+     * Compare algorithm described in dateDime (3.2.7). Duration datatype
+     * overwrites this method
+     *
+     * @param date1 normalized date representation of the first value
+     * @param date2 normalized date representation of the second value
+     * @param strict
+     * @return less, greater, less_equal, greater_equal, equal
+     */
+    protected short compareDates(DateTimeData date1, DateTimeData date2, boolean strict) {
+        if (date1.utc == date2.utc) {
+            return compareOrder(date1, date2);
+        }
+        short c1, c2;
+
+        DateTimeData tempDate = new DateTimeData(null, this);
+
+        if (date1.utc == 'Z') {
+
+            //compare date1<=date1<=(date2 with time zone -14)
+            //
+            cloneDate(date2, tempDate); //clones date1 value to global temporary storage: fTempDate
+            tempDate.timezoneHr = 14;
+            tempDate.timezoneMin = 0;
+            tempDate.utc = '+';
+            normalize(tempDate);
+            c1 = compareOrder(date1, tempDate);
+            if (c1 == LESS_THAN) {
+                return c1;
+            }
+
+            //compare date1>=(date2 with time zone +14)
+            //
+            cloneDate(date2, tempDate); //clones date1 value to global temporary storage: tempDate
+            tempDate.timezoneHr = -14;
+            tempDate.timezoneMin = 0;
+            tempDate.utc = '-';
+            normalize(tempDate);
+            c2 = compareOrder(date1, tempDate);
+            if (c2 == GREATER_THAN) {
+                return c2;
+            }
+
+            return INDETERMINATE;
+        } else if (date2.utc == 'Z') {
+
+            //compare (date1 with time zone -14)<=date2
+            //
+            cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate
+            tempDate.timezoneHr = -14;
+            tempDate.timezoneMin = 0;
+            tempDate.utc = '-';
+            if (DEBUG) {
+                System.out.println("tempDate=" + dateToString(tempDate));
+            }
+            normalize(tempDate);
+            c1 = compareOrder(tempDate, date2);
+            if (DEBUG) {
+                System.out.println("date=" + dateToString(date2));
+                System.out.println("tempDate=" + dateToString(tempDate));
+            }
+            if (c1 == LESS_THAN) {
+                return c1;
+            }
+
+            //compare (date1 with time zone +14)<=date2
+            //
+            cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate
+            tempDate.timezoneHr = 14;
+            tempDate.timezoneMin = 0;
+            tempDate.utc = '+';
+            normalize(tempDate);
+            c2 = compareOrder(tempDate, date2);
+            if (DEBUG) {
+                System.out.println("tempDate=" + dateToString(tempDate));
+            }
+            if (c2 == GREATER_THAN) {
+                return c2;
+            }
+
+            return INDETERMINATE;
+        }
+        return INDETERMINATE;
+
+    }
+
+    /**
+     * Given normalized values, determines order-relation between give date/time
+     * objects.
+     *
+     * @param date1 date/time object
+     * @param date2 date/time object
+     * @return 0 if date1 and date2 are equal, a value less than 0 if date1 is
+     * less than date2, a value greater than 0 if date1 is greater than date2
+     */
+    protected short compareOrder(DateTimeData date1, DateTimeData date2) {
+        if (date1.position < 1) {
+            if (date1.year < date2.year) {
+                return -1;
+            }
+            if (date1.year > date2.year) {
+                return 1;
+            }
+        }
+        if (date1.position < 2) {
+            if (date1.month < date2.month) {
+                return -1;
+            }
+            if (date1.month > date2.month) {
+                return 1;
+            }
+        }
+        if (date1.day < date2.day) {
+            return -1;
+        }
+        if (date1.day > date2.day) {
+            return 1;
+        }
+        if (date1.hour < date2.hour) {
+            return -1;
+        }
+        if (date1.hour > date2.hour) {
+            return 1;
+        }
+        if (date1.minute < date2.minute) {
+            return -1;
+        }
+        if (date1.minute > date2.minute) {
+            return 1;
+        }
+        if (date1.second < date2.second) {
+            return -1;
+        }
+        if (date1.second > date2.second) {
+            return 1;
+        }
+        if (date1.utc < date2.utc) {
+            return -1;
+        }
+        if (date1.utc > date2.utc) {
+            return 1;
+        }
+        return 0;
+    }
+
+    /**
+     * Parses time hh:mm:ss.sss and time zone if any
+     *
+     * @param start
+     * @param end
+     * @param data
+     * @exception RuntimeException
+     */
+    protected void getTime(String buffer, int start, int end, DateTimeData data) throws RuntimeException {
+
+        int stop = start + 2;
+
+        //get hours (hh)
+        data.hour = parseInt(buffer, start, stop);
+
+        //get minutes (mm)
+
+        if (buffer.charAt(stop++) != ':') {
+            throw new RuntimeException("Error in parsing time zone");
+        }
+        start = stop;
+        stop = stop + 2;
+        data.minute = parseInt(buffer, start, stop);
+
+        //get seconds (ss)
+        if (buffer.charAt(stop++) != ':') {
+            throw new RuntimeException("Error in parsing time zone");
+        }
+
+        //find UTC sign if any
+        int sign = findUTCSign(buffer, start, end);
+
+        //get seconds (ms)
+        start = stop;
+        stop = sign < 0 ? end : sign;
+        data.second = parseSecond(buffer, start, stop);
+
+        //parse UTC time zone (hh:mm)
+        if (sign > 0) {
+            getTimeZone(buffer, data, sign, end);
+        }
+    }
+
+    /**
+     * Parses date CCYY-MM-DD
+     *
+     * @param buffer
+     * @param start start position
+     * @param end end position
+     * @param date
+     * @exception RuntimeException
+     */
+    protected int getDate(String buffer, int start, int end, DateTimeData date) throws RuntimeException {
+
+        start = getYearMonth(buffer, start, end, date);
+
+        if (buffer.charAt(start++) != '-') {
+            throw new RuntimeException("CCYY-MM must be followed by '-' sign");
+        }
+        int stop = start + 2;
+        date.day = parseInt(buffer, start, stop);
+        return stop;
+    }
+
+    /**
+     * Parses date CCYY-MM
+     *
+     * @param buffer
+     * @param start start position
+     * @param end end position
+     * @param date
+     * @exception RuntimeException
+     */
+    protected int getYearMonth(String buffer, int start, int end, DateTimeData date) throws RuntimeException {
+
+        if (buffer.charAt(0) == '-') {
+            // REVISIT: date starts with preceding '-' sign
+            //          do we have to do anything with it?
+            //
+            start++;
+        }
+        int i = indexOf(buffer, start, end, '-');
+        if (i == -1) {
+            throw new RuntimeException("Year separator is missing or misplaced");
+        }
+        int length = i - start;
+        if (length < 4) {
+            throw new RuntimeException("Year must have 'CCYY' format");
+        } else if (length > 4 && buffer.charAt(start) == '0') {
+            throw new RuntimeException("Leading zeros are required if the year value would otherwise have fewer than four digits; otherwise they are forbidden");
+        }
+        date.year = parseIntYear(buffer, i);
+        if (buffer.charAt(i) != '-') {
+            throw new RuntimeException("CCYY must be followed by '-' sign");
+        }
+        start = ++i;
+        i = start + 2;
+        date.month = parseInt(buffer, start, i);
+        return i; //fStart points right after the MONTH
+    }
+
+    /**
+     * Shared code from Date and YearMonth datatypes. Finds if time zone sign is
+     * present
+     *
+     * @param end
+     * @param date
+     * @exception RuntimeException
+     */
+    protected void parseTimeZone(String buffer, int start, int end, DateTimeData date) throws RuntimeException {
+
+        //fStart points right after the date
+
+        if (start < end) {
+            if (!isNextCharUTCSign(buffer, start, end)) {
+                throw new RuntimeException("Error in month parsing");
+            } else {
+                getTimeZone(buffer, date, start, end);
+            }
+        }
+    }
+
+    /**
+     * Parses time zone: 'Z' or {+,-} followed by hh:mm
+     *
+     * @param data
+     * @param sign
+     * @exception RuntimeException
+     */
+    protected void getTimeZone(String buffer, DateTimeData data, int sign, int end) throws RuntimeException {
+        data.utc = buffer.charAt(sign);
+
+        if (buffer.charAt(sign) == 'Z') {
+            if (end > (++sign)) {
+                throw new RuntimeException("Error in parsing time zone");
+            }
+            return;
+        }
+        if (sign <= (end - 6)) {
+
+            int negate = buffer.charAt(sign) == '-' ? -1 : 1;
+            //parse hr
+            int stop = ++sign + 2;
+            data.timezoneHr = negate * parseInt(buffer, sign, stop);
+            if (buffer.charAt(stop++) != ':') {
+                throw new RuntimeException("Error in parsing time zone");
+            }
+
+            //parse min
+            data.timezoneMin = negate * parseInt(buffer, stop, stop + 2);
+
+            if (stop + 2 != end) {
+                throw new RuntimeException("Error in parsing time zone");
+            }
+            if (data.timezoneHr != 0 || data.timezoneMin != 0) {
+                data.normalized = false;
+            }
+        } else {
+            throw new RuntimeException("Error in parsing time zone");
+        }
+        if (DEBUG) {
+            System.out.println("time[hh]=" + data.timezoneHr + " time[mm]=" + data.timezoneMin);
+        }
+    }
+
+    /**
+     * Computes index of given char within StringBuffer
+     *
+     * @param start
+     * @param end
+     * @param ch character to look for in StringBuffer
+     * @return index of ch within StringBuffer
+     */
+    protected int indexOf(String buffer, int start, int end, char ch) {
+        for (int i = start; i < end; i++) {
+            if (buffer.charAt(i) == ch) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Validates given date/time object accoring to W3C PR Schema [D.1 ISO 8601
+     * Conventions]
+     *
+     * @param data
+     */
+    protected void validateDateTime(DateTimeData data) {
+
+        //REVISIT: should we throw an exception for not valid dates
+        //          or reporting an error message should be sufficient?
+
+        /**
+         * XML Schema 1.1 - RQ-123: Allow year 0000 in date related types.
+         */
+        if (!Constants.SCHEMA_1_1_SUPPORT && data.year == 0) {
+            throw new RuntimeException("The year \"0000\" is an illegal year value");
+
+        }
+
+        if (data.month < 1 || data.month > 12) {
+            throw new RuntimeException("The month must have values 1 to 12");
+
+        }
+
+        //validate days
+        if (data.day > maxDayInMonthFor(data.year, data.month) || data.day < 1) {
+            throw new RuntimeException("The day must have values 1 to 31");
+        }
+
+        //validate hours
+        if (data.hour > 23 || data.hour < 0) {
+            if (data.hour == 24 && data.minute == 0 && data.second == 0) {
+                data.hour = 0;
+                if (++data.day > maxDayInMonthFor(data.year, data.month)) {
+                    data.day = 1;
+                    if (++data.month > 12) {
+                        data.month = 1;
+                        if (Constants.SCHEMA_1_1_SUPPORT) {
+                            ++data.year;
+                        } else if (++data.year == 0) {
+                            data.year = 1;
+                        }
+                    }
+                }
+            } else {
+                throw new RuntimeException("Hour must have values 0-23, unless 24:00:00");
+            }
+        }
+
+        //validate
+        if (data.minute > 59 || data.minute < 0) {
+            throw new RuntimeException("Minute must have values 0-59");
+        }
+
+        //validate
+        if (data.second >= 60 || data.second < 0) {
+            throw new RuntimeException("Second must have values 0-59");
+
+        }
+
+        //validate
+        if (data.timezoneHr > 14 || data.timezoneHr < -14) {
+            throw new RuntimeException("Time zone should have range -14:00 to +14:00");
+        } else {
+            if ((data.timezoneHr == 14 || data.timezoneHr == -14) && data.timezoneMin != 0) {
+                throw new RuntimeException("Time zone should have range -14:00 to +14:00");
+            } else if (data.timezoneMin > 59 || data.timezoneMin < -59) {
+                throw new RuntimeException("Minute must have values 0-59");
+            }
+        }
+
+    }
+
+    /**
+     * Return index of UTC char: 'Z', '+', '-'
+     *
+     * @param start
+     * @param end
+     * @return index of the UTC character that was found
+     */
+    protected int findUTCSign(String buffer, int start, int end) {
+        int c;
+        for (int i = start; i < end; i++) {
+            c = buffer.charAt(i);
+            if (c == 'Z' || c == '+' || c == '-') {
+                return i;
+            }
+
+        }
+        return -1;
+    }
+
+    /**
+     * Returns
+     * <code>true</code> if the character at start is 'Z', '+' or '-'.
      */
     protected final boolean isNextCharUTCSign(String buffer, int start, int end) {
         if (start < end) {
@@ -510,135 +525,145 @@
         return false;
     }
 
-        /**
-         * Given start and end position, parses string value
-         *
-         * @param buffer string to parse
-         * @param start  start position
-         * @param end    end position
-         * @return  return integer representation of characters
-         */
-        protected  int parseInt (String buffer, int start, int end)
-        throws NumberFormatException{
-                //REVISIT: more testing on this parsing needs to be done.
-                int radix=10;
-                int result = 0;
-                int digit=0;
-                int limit = -Integer.MAX_VALUE;
-                int multmin = limit / radix;
-                int i = start;
-                do {
-                        digit = getDigit(buffer.charAt(i));
-                        if ( digit < 0 ) throw new NumberFormatException("'" + buffer + "' has wrong format");
-                        if ( result < multmin ) throw new NumberFormatException("'" + buffer + "' has wrong format");
-                        result *= radix;
-                        if ( result < limit + digit ) throw new NumberFormatException("'" + buffer + "' has wrong format");
-                        result -= digit;
-
-                }while ( ++i < end );
-                return -result;
-        }
-
-        // parse Year differently to support negative value.
-        protected int parseIntYear (String buffer, int end){
-                int radix=10;
-                int result = 0;
-                boolean negative = false;
-                int i=0;
-                int limit;
-                int multmin;
-                int digit=0;
-
-                if (buffer.charAt(0) == '-'){
-                        negative = true;
-                        limit = Integer.MIN_VALUE;
-                        i++;
-
-                }
-                else{
-                        limit = -Integer.MAX_VALUE;
-                }
-                multmin = limit / radix;
-                while (i < end)
-                {
-                        digit = getDigit(buffer.charAt(i++));
-                        if (digit < 0) throw new NumberFormatException("'" + buffer + "' has wrong format");
-                        if (result < multmin) throw new NumberFormatException("'" + buffer + "' has wrong format");
-                        result *= radix;
-                        if (result < limit + digit) throw new NumberFormatException("'" + buffer + "' has wrong format");
-                        result -= digit;
-                }
-
-                if (negative)
-                {
-                        if (i > 1) return result;
-                        else throw new NumberFormatException("'" + buffer + "' has wrong format");
-                }
-                return -result;
-
-        }
-
-        /**
-         * If timezone present - normalize dateTime  [E Adding durations to dateTimes]
-         *
-         * @param date   CCYY-MM-DDThh:mm:ss+03
-         */
-        protected void normalize(DateTimeData date) {
-
-                // REVISIT: we have common code in addDuration() for durations
-                //          should consider reorganizing it.
-                //
-
-                //add minutes (from time zone)
-                int negate = -1;
-
-                if ( DEBUG ) {
-                        System.out.println("==>date.minute"+date.minute);
-                        System.out.println("==>date.timezoneMin" +date.timezoneMin);
-                }
-                int temp = date.minute + negate * date.timezoneMin;
-                int carry = fQuotient (temp, 60);
-                date.minute= mod(temp, 60, carry);
-
-                if ( DEBUG ) {
-                        System.out.println("==>carry: " + carry);
-                }
-                //add hours
-                temp = date.hour + negate * date.timezoneHr + carry;
-                carry = fQuotient(temp, 24);
-                date.hour=mod(temp, 24, carry);
-                if ( DEBUG ) {
-                        System.out.println("==>date.hour"+date.hour);
-                        System.out.println("==>carry: " + carry);
-                }
-
-                date.day=date.day+carry;
-
-                while ( true ) {
-                        temp=maxDayInMonthFor(date.year, date.month);
-                        if (date.day<1) {
-                                date.day = date.day + maxDayInMonthFor(date.year, date.month-1);
-                                carry=-1;
-                        }
-                        else if ( date.day>temp ) {
-                                date.day=date.day-temp;
-                                carry=1;
-                        }
-                        else {
-                                break;
-                        }
-                        temp=date.month+carry;
-                        date.month=modulo(temp, 1, 13);
-                        date.year=date.year+fQuotient(temp, 1, 13);
-            if(date.year == 0 && !Constants.SCHEMA_1_1_SUPPORT) {
-                date.year = (date.timezoneHr < 0 || date.timezoneMin < 0)?1:-1;
+    /**
+     * Given start and end position, parses string value
+     *
+     * @param buffer string to parse
+     * @param start start position
+     * @param end end position
+     * @return return integer representation of characters
+     */
+    protected int parseInt(String buffer, int start, int end)
+            throws NumberFormatException {
+        //REVISIT: more testing on this parsing needs to be done.
+        int radix = 10;
+        int result = 0;
+        int digit = 0;
+        int limit = -Integer.MAX_VALUE;
+        int multmin = limit / radix;
+        int i = start;
+        do {
+            digit = getDigit(buffer.charAt(i));
+            if (digit < 0) {
+                throw new NumberFormatException("'" + buffer + "' has wrong format");
             }
-                }
-                date.utc='Z';
+            if (result < multmin) {
+                throw new NumberFormatException("'" + buffer + "' has wrong format");
+            }
+            result *= radix;
+            if (result < limit + digit) {
+                throw new NumberFormatException("'" + buffer + "' has wrong format");
+            }
+            result -= digit;
+
+        } while (++i < end);
+        return -result;
+    }
+
+    // parse Year differently to support negative value.
+    protected int parseIntYear(String buffer, int end) {
+        int radix = 10;
+        int result = 0;
+        boolean negative = false;
+        int i = 0;
+        int limit;
+        int multmin;
+        int digit = 0;
+
+        if (buffer.charAt(0) == '-') {
+            negative = true;
+            limit = Integer.MIN_VALUE;
+            i++;
+
+        } else {
+            limit = -Integer.MAX_VALUE;
+        }
+        multmin = limit / radix;
+        while (i < end) {
+            digit = getDigit(buffer.charAt(i++));
+            if (digit < 0) {
+                throw new NumberFormatException("'" + buffer + "' has wrong format");
+            }
+            if (result < multmin) {
+                throw new NumberFormatException("'" + buffer + "' has wrong format");
+            }
+            result *= radix;
+            if (result < limit + digit) {
+                throw new NumberFormatException("'" + buffer + "' has wrong format");
+            }
+            result -= digit;
         }
 
+        if (negative) {
+            if (i > 1) {
+                return result;
+            } else {
+                throw new NumberFormatException("'" + buffer + "' has wrong format");
+            }
+        }
+        return -result;
 
-        /**
+    }
+
+    /**
+     * If timezone present - normalize dateTime [E Adding durations to
+     * dateTimes]
+     *
+     * @param date CCYY-MM-DDThh:mm:ss+03
+     */
+    protected void normalize(DateTimeData date) {
+
+        // REVISIT: we have common code in addDuration() for durations
+        //          should consider reorganizing it.
+        //
+
+        //add minutes (from time zone)
+        int negate = -1;
+
+        if (DEBUG) {
+            System.out.println("==>date.minute" + date.minute);
+            System.out.println("==>date.timezoneMin" + date.timezoneMin);
+        }
+        int temp = date.minute + negate * date.timezoneMin;
+        int carry = fQuotient(temp, 60);
+        date.minute = mod(temp, 60, carry);
+
+        if (DEBUG) {
+            System.out.println("==>carry: " + carry);
+        }
+        //add hours
+        temp = date.hour + negate * date.timezoneHr + carry;
+        carry = fQuotient(temp, 24);
+        date.hour = mod(temp, 24, carry);
+        if (DEBUG) {
+            System.out.println("==>date.hour" + date.hour);
+            System.out.println("==>carry: " + carry);
+        }
+
+        date.day = date.day + carry;
+
+        while (true) {
+            temp = maxDayInMonthFor(date.year, date.month);
+            if (date.day < 1) {
+                date.day = date.day + maxDayInMonthFor(date.year, date.month - 1);
+                carry = -1;
+            } else if (date.day > temp) {
+                date.day = date.day - temp;
+                carry = 1;
+            } else {
+                break;
+            }
+            temp = date.month + carry;
+            date.month = modulo(temp, 1, 13);
+            date.year = date.year + fQuotient(temp, 1, 13);
+            if (date.year == 0 && !Constants.SCHEMA_1_1_SUPPORT) {
+                date.year = (date.timezoneHr < 0 || date.timezoneMin < 0) ? 1 : -1;
+            }
+        }
+        date.utc = 'Z';
+    }
+
+    /**
      * @param date
      */
     protected void saveUnnormalized(DateTimeData date) {
@@ -651,154 +676,149 @@
     }
 
     /**
-         * Resets object representation of date/time
-         *
-         * @param data   date/time object
-         */
-        protected void resetDateObj(DateTimeData data) {
-                data.year = 0;
-                data.month = 0;
-                data.day = 0;
-                data.hour = 0;
-                data.minute = 0;
-                data.second = 0;
-                data.utc = 0;
-                data.timezoneHr = 0;
-                data.timezoneMin = 0;
+     * Resets object representation of date/time
+     *
+     * @param data date/time object
+     */
+    protected void resetDateObj(DateTimeData data) {
+        data.year = 0;
+        data.month = 0;
+        data.day = 0;
+        data.hour = 0;
+        data.minute = 0;
+        data.second = 0;
+        data.utc = 0;
+        data.timezoneHr = 0;
+        data.timezoneMin = 0;
+    }
+
+    /**
+     * Given {year,month} computes maximum number of days for given month
+     *
+     * @param year
+     * @param month
+     * @return integer containg the number of days in a given month
+     */
+    protected int maxDayInMonthFor(int year, int month) {
+        //validate days
+        if (month == 4 || month == 6 || month == 9 || month == 11) {
+            return 30;
+        } else if (month == 2) {
+            if (isLeapYear(year)) {
+                return 29;
+            } else {
+                return 28;
+            }
+        } else {
+            return 31;
         }
+    }
 
-        /**
-         * Given {year,month} computes maximum
-         * number of days for given month
-         *
-         * @param year
-         * @param month
-         * @return integer containg the number of days in a given month
-         */
-        protected int maxDayInMonthFor(int year, int month) {
-                //validate days
-                if ( month==4 || month==6 || month==9 || month==11 ) {
-                        return 30;
-                }
-                else if ( month==2 ) {
-                        if ( isLeapYear(year) ) {
-                                return 29;
-                        }
-                        else {
-                                return 28;
-                        }
-                }
-                else {
-                        return 31;
-                }
-        }
+    private boolean isLeapYear(int year) {
 
-        private boolean isLeapYear(int year) {
+        //REVISIT: should we take care about Julian calendar?
+        return ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)));
+    }
 
-                //REVISIT: should we take care about Julian calendar?
-                return((year%4 == 0) && ((year%100 != 0) || (year%400 == 0)));
-        }
+    //
+    // help function described in W3C PR Schema [E Adding durations to dateTimes]
+    //
+    protected int mod(int a, int b, int quotient) {
+        //modulo(a, b) = a - fQuotient(a,b)*b
+        return (a - quotient * b);
+    }
 
-        //
-        // help function described in W3C PR Schema [E Adding durations to dateTimes]
-        //
-        protected int mod (int a, int b, int quotient) {
-                //modulo(a, b) = a - fQuotient(a,b)*b
-                return (a - quotient*b) ;
-        }
+    //
+    // help function described in W3C PR Schema [E Adding durations to dateTimes]
+    //
+    protected int fQuotient(int a, int b) {
 
-        //
-        // help function described in W3C PR Schema [E Adding durations to dateTimes]
-        //
-        protected int fQuotient (int a, int b) {
+        //fQuotient(a, b) = the greatest integer less than or equal to a/b
+        return (int) Math.floor((float) a / b);
+    }
 
-                //fQuotient(a, b) = the greatest integer less than or equal to a/b
-                return (int)Math.floor((float)a/b);
-        }
+    //
+    // help function described in W3C PR Schema [E Adding durations to dateTimes]
+    //
+    protected int modulo(int temp, int low, int high) {
+        //modulo(a - low, high - low) + low
+        int a = temp - low;
+        int b = high - low;
+        return (mod(a, b, fQuotient(a, b)) + low);
+    }
 
-        //
-        // help function described in W3C PR Schema [E Adding durations to dateTimes]
-        //
-        protected int modulo (int temp, int low, int high) {
-                //modulo(a - low, high - low) + low
-                int a = temp - low;
-                int b = high - low;
-                return (mod (a, b, fQuotient(a, b)) + low) ;
-        }
+    //
+    // help function described in W3C PR Schema [E Adding durations to dateTimes]
+    //
+    protected int fQuotient(int temp, int low, int high) {
+        //fQuotient(a - low, high - low)
 
-        //
-        // help function described in W3C PR Schema [E Adding durations to dateTimes]
-        //
-        protected int fQuotient (int temp, int low, int high) {
-                //fQuotient(a - low, high - low)
+        return fQuotient(temp - low, high - low);
+    }
 
-                return fQuotient(temp - low, high - low);
-        }
+    protected String dateToString(DateTimeData date) {
+        StringBuffer message = new StringBuffer(25);
+        append(message, date.year, 4);
+        message.append('-');
+        append(message, date.month, 2);
+        message.append('-');
+        append(message, date.day, 2);
+        message.append('T');
+        append(message, date.hour, 2);
+        message.append(':');
+        append(message, date.minute, 2);
+        message.append(':');
+        append(message, date.second);
+        append(message, (char) date.utc, 0);
+        return message.toString();
+    }
 
-
-        protected String dateToString(DateTimeData date) {
-                StringBuffer message = new StringBuffer(25);
-                append(message, date.year, 4);
-                message.append('-');
-                append(message, date.month, 2);
-                message.append('-');
-                append(message, date.day, 2);
-                message.append('T');
-                append(message, date.hour, 2);
-                message.append(':');
-                append(message, date.minute, 2);
-                message.append(':');
-                append(message, date.second);
-                append(message, (char)date.utc, 0);
-                return message.toString();
-        }
-
-        protected final void append(StringBuffer message, int value, int nch) {
+    protected final void append(StringBuffer message, int value, int nch) {
         if (value == Integer.MIN_VALUE) {
             message.append(value);
             return;
         }
-                if (value < 0) {
-                        message.append('-');
-                        value = -value;
-                }
-                if (nch == 4) {
-                        if (value < 10)
-                                message.append("000");
-                        else if (value < 100)
-                                message.append("00");
-                        else if (value < 1000)
-                                message.append('0');
-                        message.append(value);
-                }
-                else if (nch == 2) {
-                        if (value < 10)
-                                message.append('0');
-                        message.append(value);
-                }
-                else {
-                        if (value != 0)
-                                message.append((char)value);
-                }
+        if (value < 0) {
+            message.append('-');
+            value = -value;
         }
-
-        protected final void append(StringBuffer message, double value) {
-            if (value < 0) {
-                message.append('-');
-                value = -value;
+        if (nch == 4) {
+            if (value < 10) {
+                message.append("000");
+            } else if (value < 100) {
+                message.append("00");
+            } else if (value < 1000) {
+                message.append('0');
             }
+            message.append(value);
+        } else if (nch == 2) {
             if (value < 10) {
                 message.append('0');
             }
-            append2(message, value);
+            message.append(value);
+        } else {
+            if (value != 0) {
+                message.append((char) value);
+            }
         }
+    }
+
+    protected final void append(StringBuffer message, double value) {
+        if (value < 0) {
+            message.append('-');
+            value = -value;
+        }
+        if (value < 10) {
+            message.append('0');
+        }
+        append2(message, value);
+    }
 
     protected final void append2(StringBuffer message, double value) {
         final int intValue = (int) value;
         if (value == intValue) {
             message.append(intValue);
-        }
-        else {
+        } else {
             append3(message, value);
         }
     }
@@ -815,9 +835,8 @@
             // Need to convert from scientific notation of the form
             // n.nnn...E-N (N >= 4) to a normal decimal value.
             try {
-                exp = parseInt(d, eIndex+2, d.length());
-            }
-            // This should never happen.
+                exp = parseInt(d, eIndex + 2, d.length());
+            } // This should never happen.
             // It's only possible if String.valueOf(double) is broken.
             catch (Exception e) {
                 message.append(d);
@@ -843,14 +862,12 @@
                     message.append(c);
                 }
             }
-        }
-        else {
+        } else {
             // Need to convert from scientific notation of the form
             // n.nnn...EN (N >= 7) to a normal decimal value.
             try {
-                exp = parseInt(d, eIndex+1, d.length());
-            }
-            // This should never happen.
+                exp = parseInt(d, eIndex + 1, d.length());
+            } // This should never happen.
             // It's only possible if String.valueOf(double) is broken.
             catch (Exception e) {
                 message.append(d);
@@ -873,174 +890,220 @@
         }
     }
 
-        protected double parseSecond(String buffer, int start, int end)
-        throws NumberFormatException {
-                int dot = -1;
-                for (int i = start; i < end; i++) {
-                        char ch = buffer.charAt(i);
-                        if (ch == '.')
-                                dot = i;
-                        else if (ch > '9' || ch < '0')
-                                throw new NumberFormatException("'" + buffer + "' has wrong format");
-                }
-                if (dot == -1) {
-                        if (start+2 != end)
-                                throw new NumberFormatException("'" + buffer + "' has wrong format");
-                }
-                else if (start+2 != dot || dot+1 == end) {
-                        throw new NumberFormatException("'" + buffer + "' has wrong format");
-                }
-                return Double.parseDouble(buffer.substring(start, end));
+    protected double parseSecond(String buffer, int start, int end)
+            throws NumberFormatException {
+        int dot = -1;
+        for (int i = start; i < end; i++) {
+            char ch = buffer.charAt(i);
+            if (ch == '.') {
+                dot = i;
+            } else if (ch > '9' || ch < '0') {
+                throw new NumberFormatException("'" + buffer + "' has wrong format");
+            }
         }
-
-        //
-        //Private help functions
-        //
-
-        private void cloneDate (DateTimeData finalValue, DateTimeData tempDate) {
-                tempDate.year = finalValue.year;
-                tempDate.month = finalValue.month;
-                tempDate.day = finalValue.day;
-                tempDate.hour = finalValue.hour;
-                tempDate.minute = finalValue.minute;
-                tempDate.second = finalValue.second;
-                tempDate.utc = finalValue.utc;
-                tempDate.timezoneHr = finalValue.timezoneHr;
-                tempDate.timezoneMin = finalValue.timezoneMin;
+        if (dot == -1) {
+            if (start + 2 != end) {
+                throw new NumberFormatException("'" + buffer + "' has wrong format");
+            }
+        } else if (start + 2 != dot || dot + 1 == end) {
+            throw new NumberFormatException("'" + buffer + "' has wrong format");
         }
+        return Double.parseDouble(buffer.substring(start, end));
+    }
 
-        /**
-         * Represents date time data
-         */
-        static final class DateTimeData implements XSDateTime {
-                int year, month, day, hour, minute, utc;
-                double second;
-                int timezoneHr, timezoneMin;
+    //
+    //Private help functions
+    //
+    private void cloneDate(DateTimeData finalValue, DateTimeData tempDate) {
+        tempDate.year = finalValue.year;
+        tempDate.month = finalValue.month;
+        tempDate.day = finalValue.day;
+        tempDate.hour = finalValue.hour;
+        tempDate.minute = finalValue.minute;
+        tempDate.second = finalValue.second;
+        tempDate.utc = finalValue.utc;
+        tempDate.timezoneHr = finalValue.timezoneHr;
+        tempDate.timezoneMin = finalValue.timezoneMin;
+    }
+
+    /**
+     * Represents date time data
+     */
+    static final class DateTimeData implements XSDateTime {
+
+        int year, month, day, hour, minute, utc;
+        double second;
+        int timezoneHr, timezoneMin;
         private String originalValue;
         boolean normalized = true;
-
         int unNormYear;
         int unNormMonth;
         int unNormDay;
         int unNormHour;
         int unNormMinute;
         double unNormSecond;
+        // used for comparisons - to decide the 'interesting' portions of
+        // a date/time based data type.
+        int position;
+        // a pointer to the type that was used go generate this data
+        // note that this is not the actual simple type, but one of the
+        // statically created XXXDV objects, so this won't cause any GC problem.
+        final AbstractDateTimeDV type;
+        private volatile String canonical;
 
-                // used for comparisons - to decide the 'interesting' portions of
-                // a date/time based data type.
-                int position;
-                // a pointer to the type that was used go generate this data
-                // note that this is not the actual simple type, but one of the
-                // statically created XXXDV objects, so this won't cause any GC problem.
-                final AbstractDateTimeDV type;
-                private String canonical;
-                public DateTimeData(String originalValue, AbstractDateTimeDV type) {
+        public DateTimeData(String originalValue, AbstractDateTimeDV type) {
             this.originalValue = originalValue;
-                        this.type = type;
-                }
-                public DateTimeData(int year, int month, int day, int hour, int minute,
-                                double second, int utc, String originalValue, boolean normalized, AbstractDateTimeDV type) {
-                        this.year = year;
-                        this.month = month;
-                        this.day = day;
-                        this.hour = hour;
-                        this.minute = minute;
-                        this.second = second;
-                        this.utc = utc;
-                        this.type = type;
+            this.type = type;
+        }
+
+        public DateTimeData(int year, int month, int day, int hour, int minute,
+                double second, int utc, String originalValue, boolean normalized, AbstractDateTimeDV type) {
+            this.year = year;
+            this.month = month;
+            this.day = day;
+            this.hour = hour;
+            this.minute = minute;
+            this.second = second;
+            this.utc = utc;
+            this.type = type;
             this.originalValue = originalValue;
-                }
-                public boolean equals(Object obj) {
-                        if (!(obj instanceof DateTimeData))
-                                return false;
-                        return type.compareDates(this, (DateTimeData)obj, true)==0;
-                }
-                public synchronized String toString() {
-                        if (canonical == null) {
-                                canonical = type.dateToString(this);
-                        }
-                        return canonical;
-                }
-                /* (non-Javadoc)
-                 * @see org.apache.xerces.xs.datatypes.XSDateTime#getYear()
-                 */
-                public int getYears() {
-            if(type instanceof DurationDV)
-                return 0;
-                        return normalized?year:unNormYear;
-                }
-                /* (non-Javadoc)
-                 * @see org.apache.xerces.xs.datatypes.XSDateTime#getMonth()
-                 */
-                public int getMonths() {
-            if(type instanceof DurationDV) {
-                return year*12 + month;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (!(obj instanceof DateTimeData)) {
+                return false;
             }
-                        return normalized?month:unNormMonth;
-                }
-                /* (non-Javadoc)
-                 * @see org.apache.xerces.xs.datatypes.XSDateTime#getDay()
-                 */
-                public int getDays() {
-            if(type instanceof DurationDV)
-                return 0;
-                        return normalized?day:unNormDay;
-                }
-                /* (non-Javadoc)
-                 * @see org.apache.xerces.xs.datatypes.XSDateTime#getHour()
-                 */
-                public int getHours() {
-            if(type instanceof DurationDV)
-                return 0;
-                        return normalized?hour:unNormHour;
-                }
-                /* (non-Javadoc)
-                 * @see org.apache.xerces.xs.datatypes.XSDateTime#getMinutes()
-                 */
-                public int getMinutes() {
-            if(type instanceof DurationDV)
-                return 0;
-                        return normalized?minute:unNormMinute;
-                }
-                /* (non-Javadoc)
-                 * @see org.apache.xerces.xs.datatypes.XSDateTime#getSeconds()
-                 */
-                public double getSeconds() {
-            if(type instanceof DurationDV) {
-                return day*24*60*60 + hour*60*60 + minute*60 + second;
+            return type.compareDates(this, (DateTimeData) obj, true) == 0;
+        }
+
+        // If two DateTimeData are equals - then they should have the same
+        // hashcode. This means we need to convert the date to UTC before
+        // we return its hashcode.
+        // The DateTimeData is unfortunately mutable - so we cannot
+        // cache the result of the conversion...
+        //
+        @Override
+        public int hashCode() {
+            final DateTimeData tempDate = new DateTimeData(null, type);
+            type.cloneDate(this, tempDate);
+            type.normalize(tempDate);
+            return type.dateToString(tempDate).hashCode();
+        }
+
+        @Override
+        public String toString() {
+            if (canonical == null) {
+                canonical = type.dateToString(this);
             }
-                        return normalized?second:unNormSecond;
-                }
-                /* (non-Javadoc)
-                 * @see org.apache.xerces.xs.datatypes.XSDateTime#hasTimeZone()
-                 */
-                public boolean hasTimeZone() {
-                        return utc != 0;
-                }
-                /* (non-Javadoc)
-                 * @see org.apache.xerces.xs.datatypes.XSDateTime#getTimeZoneHours()
-                 */
-                public int getTimeZoneHours() {
-                        return timezoneHr;
-                }
-                /* (non-Javadoc)
-                 * @see org.apache.xerces.xs.datatypes.XSDateTime#getTimeZoneMinutes()
-                 */
-                public int getTimeZoneMinutes() {
-                        return timezoneMin;
-                }
+            return canonical;
+        }
+        /* (non-Javadoc)
+         * @see org.apache.xerces.xs.datatypes.XSDateTime#getYear()
+         */
+
+        @Override
+        public int getYears() {
+            if (type instanceof DurationDV) {
+                return 0;
+            }
+            return normalized ? year : unNormYear;
+        }
+        /* (non-Javadoc)
+         * @see org.apache.xerces.xs.datatypes.XSDateTime#getMonth()
+         */
+
+        @Override
+        public int getMonths() {
+            if (type instanceof DurationDV) {
+                return year * 12 + month;
+            }
+            return normalized ? month : unNormMonth;
+        }
+        /* (non-Javadoc)
+         * @see org.apache.xerces.xs.datatypes.XSDateTime#getDay()
+         */
+
+        @Override
+        public int getDays() {
+            if (type instanceof DurationDV) {
+                return 0;
+            }
+            return normalized ? day : unNormDay;
+        }
+        /* (non-Javadoc)
+         * @see org.apache.xerces.xs.datatypes.XSDateTime#getHour()
+         */
+
+        @Override
+        public int getHours() {
+            if (type instanceof DurationDV) {
+                return 0;
+            }
+            return normalized ? hour : unNormHour;
+        }
+        /* (non-Javadoc)
+         * @see org.apache.xerces.xs.datatypes.XSDateTime#getMinutes()
+         */
+
+        @Override
+        public int getMinutes() {
+            if (type instanceof DurationDV) {
+                return 0;
+            }
+            return normalized ? minute : unNormMinute;
+        }
+        /* (non-Javadoc)
+         * @see org.apache.xerces.xs.datatypes.XSDateTime#getSeconds()
+         */
+
+        @Override
+        public double getSeconds() {
+            if (type instanceof DurationDV) {
+                return day * 24 * 60 * 60 + hour * 60 * 60 + minute * 60 + second;
+            }
+            return normalized ? second : unNormSecond;
+        }
+        /* (non-Javadoc)
+         * @see org.apache.xerces.xs.datatypes.XSDateTime#hasTimeZone()
+         */
+
+        @Override
+        public boolean hasTimeZone() {
+            return utc != 0;
+        }
+        /* (non-Javadoc)
+         * @see org.apache.xerces.xs.datatypes.XSDateTime#getTimeZoneHours()
+         */
+
+        @Override
+        public int getTimeZoneHours() {
+            return timezoneHr;
+        }
+        /* (non-Javadoc)
+         * @see org.apache.xerces.xs.datatypes.XSDateTime#getTimeZoneMinutes()
+         */
+
+        @Override
+        public int getTimeZoneMinutes() {
+            return timezoneMin;
+        }
         /* (non-Javadoc)
          * @see org.apache.xerces.xs.datatypes.XSDateTime#getLexicalValue()
          */
+
+        @Override
         public String getLexicalValue() {
             return originalValue;
         }
         /* (non-Javadoc)
          * @see org.apache.xerces.xs.datatypes.XSDateTime#normalize()
          */
+
+        @Override
         public XSDateTime normalize() {
-            if(!normalized) {
-                DateTimeData dt = (DateTimeData)this.clone();
+            if (!normalized) {
+                DateTimeData dt = (DateTimeData) this.clone();
                 dt.normalized = true;
                 return dt;
             }
@@ -1049,13 +1112,16 @@
         /* (non-Javadoc)
          * @see org.apache.xerces.xs.datatypes.XSDateTime#isNormalized()
          */
+
+        @Override
         public boolean isNormalized() {
             return normalized;
         }
 
+        @Override
         public Object clone() {
             DateTimeData dt = new DateTimeData(this.year, this.month, this.day, this.hour,
-                        this.minute, this.second, this.utc, this.originalValue, this.normalized, this.type);
+                    this.minute, this.second, this.utc, this.originalValue, this.normalized, this.type);
             dt.canonical = this.canonical;
             dt.position = position;
             dt.timezoneHr = this.timezoneHr;
@@ -1072,16 +1138,19 @@
         /* (non-Javadoc)
          * @see org.apache.xerces.xs.datatypes.XSDateTime#getXMLGregorianCalendar()
          */
+        @Override
         public XMLGregorianCalendar getXMLGregorianCalendar() {
             return type.getXMLGregorianCalendar(this);
         }
         /* (non-Javadoc)
          * @see org.apache.xerces.xs.datatypes.XSDateTime#getDuration()
          */
+
+        @Override
         public Duration getDuration() {
             return type.getDuration(this);
         }
-        }
+    }
 
     protected XMLGregorianCalendar getXMLGregorianCalendar(DateTimeData data) {
         return null;
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/DecimalDV.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/DecimalDV.java
index ce61611..622042b 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/DecimalDV.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/DecimalDV.java
@@ -26,6 +26,7 @@
 import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException;
 import com.sun.org.apache.xerces.internal.impl.dv.ValidationContext;
 import com.sun.org.apache.xerces.internal.xs.datatypes.XSDecimal;
+import java.util.Objects;
 
 /**
  * Represent the schema type "decimal"
@@ -38,10 +39,12 @@
  */
 public class DecimalDV extends TypeValidator {
 
+    @Override
     public final short getAllowedFacets(){
         return ( XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION |XSSimpleTypeDecl.FACET_MAXINCLUSIVE |XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE  | XSSimpleTypeDecl.FACET_MINEXCLUSIVE | XSSimpleTypeDecl.FACET_TOTALDIGITS | XSSimpleTypeDecl.FACET_FRACTIONDIGITS);
     }
 
+    @Override
     public Object getActualValue(String content, ValidationContext context) throws InvalidDatatypeValueException {
         try {
             return new XDecimal(content);
@@ -50,20 +53,23 @@
         }
     }
 
+    @Override
     public final int compare(Object value1, Object value2){
         return ((XDecimal)value1).compareTo((XDecimal)value2);
     }
 
+    @Override
     public final int getTotalDigits(Object value){
         return ((XDecimal)value).totalDigits;
     }
 
+    @Override
     public final int getFractionDigits(Object value){
         return ((XDecimal)value).fracDigits;
     }
 
     // Avoid using the heavy-weight java.math.BigDecimal
-    static class XDecimal implements XSDecimal {
+    static final class XDecimal implements XSDecimal {
         // sign: 0 for vlaue 0; 1 for positive values; -1 for negative values
         int sign = 1;
         // total digits. >= 1
@@ -216,6 +222,8 @@
 
             integer = true;
         }
+
+        @Override
         public boolean equals(Object val) {
             if (val == this)
                 return true;
@@ -232,6 +240,19 @@
             return intDigits == oval.intDigits && fracDigits == oval.fracDigits &&
                    ivalue.equals(oval.ivalue) && fvalue.equals(oval.fvalue);
         }
+
+        @Override
+        public int hashCode() {
+            int hash = 7;
+            hash = 17 * hash + this.sign;
+            if (this.sign == 0) return hash;
+            hash = 17 * hash + this.intDigits;
+            hash = 17 * hash + this.fracDigits;
+            hash = 17 * hash + Objects.hashCode(this.ivalue);
+            hash = 17 * hash + Objects.hashCode(this.fvalue);
+            return hash;
+        }
+
         public int compareTo(XDecimal val) {
             if (sign != val.sign)
                 return sign > val.sign ? 1 : -1;
@@ -248,7 +269,9 @@
             ret = fvalue.compareTo(val.fvalue);
             return ret == 0 ? 0 : (ret > 0 ? 1 : -1);
         }
+
         private String canonical;
+        @Override
         public synchronized String toString() {
             if (canonical == null) {
                 makeCanonical();
@@ -269,7 +292,7 @@
                 return;
             }
             // for -0.1, total digits is 1, so we need 3 extra spots
-            StringBuffer buffer = new StringBuffer(totalDigits+3);
+            final StringBuilder buffer = new StringBuilder(totalDigits+3);
             if (sign == -1)
                 buffer.append('-');
             if (intDigits != 0)
@@ -288,6 +311,7 @@
             canonical = buffer.toString();
         }
 
+        @Override
         public BigDecimal getBigDecimal() {
             if (sign == 0) {
                 return new BigDecimal(BigInteger.ZERO);
@@ -295,6 +319,7 @@
             return new BigDecimal(toString());
         }
 
+        @Override
         public BigInteger getBigInteger() throws NumberFormatException {
             if (fracDigits != 0) {
                 throw new NumberFormatException();
@@ -308,6 +333,7 @@
             return new BigInteger("-" + ivalue);
         }
 
+        @Override
         public long getLong() throws NumberFormatException {
             if (fracDigits != 0) {
                 throw new NumberFormatException();
@@ -321,6 +347,7 @@
             return Long.parseLong("-" + ivalue);
         }
 
+        @Override
         public int getInt() throws NumberFormatException {
             if (fracDigits != 0) {
                 throw new NumberFormatException();
@@ -334,6 +361,7 @@
             return Integer.parseInt("-" + ivalue);
         }
 
+        @Override
         public short getShort() throws NumberFormatException {
             if (fracDigits != 0) {
                 throw new NumberFormatException();
@@ -347,6 +375,7 @@
             return Short.parseShort("-" + ivalue);
         }
 
+        @Override
         public byte getByte() throws NumberFormatException {
             if (fracDigits != 0) {
                 throw new NumberFormatException();
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/PrecisionDecimalDV.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/PrecisionDecimalDV.java
index af8d8d4..a75f03a 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/PrecisionDecimalDV.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/PrecisionDecimalDV.java
@@ -32,7 +32,7 @@
  */
 class PrecisionDecimalDV extends TypeValidator {
 
-    static class XPrecisionDecimal {
+    static final class XPrecisionDecimal {
 
         // sign: 0 for absent; 1 for positive values; -1 for negative values (except in case of INF, -INF)
         int sign = 1;
@@ -144,7 +144,71 @@
             totalDigits = intDigits + fracDigits;
         }
 
+        // Construct a canonical String representation of this number
+        // for the purpose of deriving a hashCode value compliant with
+        // equals.
+        // The toString representation will be:
+        // NaN for NaN, INF for +infinity, -INF for -infinity, 0 for zero,
+        // and [1-9].[0-9]*[1-9]?(E[1-9][0-9]*)? for other numbers.
+        private static String canonicalToStringForHashCode(String ivalue, String fvalue, int sign, int pvalue) {
+            if ("NaN".equals(ivalue)) {
+                return "NaN";
+            }
+            if ("INF".equals(ivalue)) {
+                return sign < 0 ? "-INF" : "INF";
+            }
+            final StringBuilder builder = new StringBuilder();
+            final int ilen = ivalue.length();
+            final int flen0 = fvalue.length();
+            int lastNonZero;
+            for (lastNonZero = flen0; lastNonZero > 0 ; lastNonZero--) {
+                if (fvalue.charAt(lastNonZero -1 ) != '0') break;
+            }
+            final int flen = lastNonZero;
+            int iStart;
+            int exponent = pvalue;
+            for (iStart = 0; iStart < ilen; iStart++) {
+                if (ivalue.charAt(iStart) != '0') break;
+            }
+            int fStart = 0;
+            if (iStart < ivalue.length()) {
+                builder.append(sign == -1 ? "-" : "");
+                builder.append(ivalue.charAt(iStart));
+                iStart++;
+            } else {
+                if (flen > 0) {
+                    for (fStart = 0; fStart < flen; fStart++) {
+                        if (fvalue.charAt(fStart) != '0') break;
+                    }
+                    if (fStart < flen) {
+                        builder.append(sign == -1 ? "-" : "");
+                        builder.append(fvalue.charAt(fStart));
+                        exponent -= ++fStart;
+                    } else {
+                        return "0";
+                    }
+                } else {
+                    return "0";
+                }
+            }
 
+            if (iStart < ilen || fStart < flen) {
+                builder.append('.');
+            }
+            while (iStart < ilen) {
+                builder.append(ivalue.charAt(iStart++));
+                exponent++;
+            }
+            while (fStart < flen) {
+                builder.append(fvalue.charAt(fStart++));
+            }
+            if (exponent != 0) {
+                builder.append("E").append(exponent);
+            }
+            return builder.toString();
+        }
+
+        @Override
         public boolean equals(Object val) {
             if (val == this)
                 return true;
@@ -156,6 +220,20 @@
             return this.compareTo(oval) == EQUAL;
         }
 
+        @Override
+        public int hashCode() {
+            // There's nothing else we can use easily, because equals could
+            // return true for widely different representation of the
+            // same number - and we don't have any canonical representation.
+            // The problem here is that we must ensure that if two numbers
+            // are equals then their hash code must also be equals.
+            // hashCode for 1.01E1 should be the same as hashCode for 0.101E2
+            // So we call cannonicalToStringForHashCode - which implements an
+            // algorithm that invents a normalized string representation
+            // for this number, and we return a hash for that.
+            return canonicalToStringForHashCode(ivalue, fvalue, sign, pvalue).hashCode();
+        }
+
         /**
          * @return
          */
@@ -295,6 +373,7 @@
 
         private String canonical;
 
+        @Override
         public synchronized String toString() {
             if (canonical == null) {
                 makeCanonical();
@@ -325,6 +404,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.impl.dv.xs.TypeValidator#getAllowedFacets()
      */
+    @Override
     public short getAllowedFacets() {
         return ( XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION |XSSimpleTypeDecl.FACET_MAXINCLUSIVE |XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE  | XSSimpleTypeDecl.FACET_MINEXCLUSIVE | XSSimpleTypeDecl.FACET_TOTALDIGITS | XSSimpleTypeDecl.FACET_FRACTIONDIGITS);
     }
@@ -332,6 +412,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.impl.dv.xs.TypeValidator#getActualValue(java.lang.String, com.sun.org.apache.xerces.internal.impl.dv.ValidationContext)
      */
+    @Override
     public Object getActualValue(String content, ValidationContext context)
     throws InvalidDatatypeValueException {
         try {
@@ -341,18 +422,22 @@
         }
     }
 
+    @Override
     public int compare(Object value1, Object value2) {
         return ((XPrecisionDecimal)value1).compareTo((XPrecisionDecimal)value2);
     }
 
+    @Override
     public int getFractionDigits(Object value) {
         return ((XPrecisionDecimal)value).fracDigits;
     }
 
+    @Override
     public int getTotalDigits(Object value) {
         return ((XPrecisionDecimal)value).totalDigits;
     }
 
+    @Override
     public boolean isIdentical(Object value1, Object value2) {
         if(!(value2 instanceof XPrecisionDecimal) || !(value1 instanceof XPrecisionDecimal))
             return false;
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages.properties
index 5a06fa0..ea35c9e 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages.properties
@@ -11,7 +11,7 @@
 HrefMissing = The 'href' attribute of an 'include' element is missing.
 RecursiveInclude = Recursive include detected.  Document ''{0}'' was already processed.
 InvalidParseValue = Invalid value for ''parse'' attribute on ''include'' element: ''{0}''.
-XMLParseError = Error attempting to parse XML file (href=''{0}'').
+XMLParseError = Error attempting to parse XML file (href=''{0}''). Reason: {1}
 XMLResourceError = Include operation failed, reverting to fallback. Resource error reading file as XML (href=''{0}''). Reason: {1}
 TextResourceError = Include operation failed, reverting to fallback. Resource error reading file as text (href=''{0}''). Reason: {1}
 NO_XPointerSchema = Schema for \"{0}\" is not supported by default. Define your own schema for {0}.See http://apache.org/xml/properties/xpointer-schema
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_de.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_de.properties
index 5a05972..58c045b 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_de.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_de.properties
@@ -39,7 +39,7 @@
 HrefMissing = "href"-Attribut eines "include"-Elements fehlt.
 RecursiveInclude = Rekursives "include" ermittelt. Dokument "{0}" wurde bereits verarbeitet.
 InvalidParseValue = Ung\u00FCltiger Wert f\u00FCr "parse"-Attribut bei "include"-Element: "{0}".
-XMLParseError = Fehler beim Versuch, XML-Datei zu parsen (href="{0}").
+XMLParseError = Fehler beim Versuch, XML-Datei zu parsen (href="{0}").  Grund: {1}
 XMLResourceError = Include-Vorgang nicht erfolgreich. Zur\u00FCck zu Fallback. Ressourcenfehler beim Lesen der Datei als XML (href="{0}"). Grund: {1}
 TextResourceError = Include-Vorgang nicht erfolgreich. Zur\u00FCck zu Fallback. Ressourcenfehler beim Lesen der Datei als Text (href="{0}"). Grund: {1}
 NO_XPointerSchema = Schema f\u00FCr \"{0}\" wird standardm\u00E4\u00DFig nicht unterst\u00FCtzt. Definieren Sie Ihr eigenes Schema f\u00FCr {0}. Siehe http://apache.org/xml/properties/xpointer-schema
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_es.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_es.properties
index 59b669f..2bf1f2b 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_es.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_es.properties
@@ -39,7 +39,7 @@
 HrefMissing = Falta el atributo 'href' de un elemento 'include'.
 RecursiveInclude = Se ha detectado un elemento include recursivo. El documento ''{0}'' ya se ha procesado.
 InvalidParseValue = Valor no v\u00E1lido para el atributo ''parse'' en el elemento ''include'': ''{0}''.
-XMLParseError = Error al intentar analizar el archivo XML (href=''{0}'').
+XMLParseError = Error al intentar analizar el archivo XML (href=''{0}'').  Motivo: {1}
 XMLResourceError = Fallo de la operaci\u00F3n include, conversi\u00F3n a fallback. Error del recurso al leer el archivo como XML (href=''{0}''). Motivo: {1}
 TextResourceError = Fallo de la operaci\u00F3n include, conversi\u00F3n a fallback. Error del recurso al leer el archivo como texto (href=''{0}''). Motivo: {1}
 NO_XPointerSchema = El esquema para \"{0}\" no est\u00E1 soportado por defecto. Defina su propio esquema para {0}. Consulte http://apache.org/xml/properties/xpointer-schema
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_fr.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_fr.properties
index c5f3666..9a22cb4 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_fr.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_fr.properties
@@ -39,7 +39,7 @@
 HrefMissing = L'attribut 'href' d'un \u00E9l\u00E9ment 'include' est manquant.
 RecursiveInclude = El\u00E9ment "include" r\u00E9cursif d\u00E9tect\u00E9. Le document ''{0}'' a d\u00E9j\u00E0 \u00E9t\u00E9 trait\u00E9.
 InvalidParseValue = Valeur non valide pour l''attribut ''parse'' sur l''\u00E9l\u00E9ment ''include'' : ''{0}''.
-XMLParseError = Erreur lors de la tentative d''analyse du fichier XML (href=''{0}'').
+XMLParseError = Erreur lors de la tentative d''analyse du fichier XML (href=''{0}''). Raison : {1}
 XMLResourceError = Echec de l''op\u00E9ration Include, r\u00E9tablissement de l''\u00E9l\u00E9ment fallback. Erreur de ressource lors de la lecture du fichier en tant que XML (href=''{0}''). Raison : {1}
 TextResourceError = Echec de l''op\u00E9ration Include, r\u00E9tablissement de l''\u00E9l\u00E9ment fallback. Erreur de ressource lors de la lecture du fichier en tant que texte (href=''{0}''). Raison : {1}
 NO_XPointerSchema = Par d\u00E9faut, le sch\u00E9ma pour \"{0}\" n''est pas pris en charge. D\u00E9finissez votre propre sch\u00E9ma pour {0}. Reportez-vous \u00E0 l''adresse http://apache.org/xml/properties/xpointer-schema
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_it.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_it.properties
index d0ca4e0..1cdc544 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_it.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_it.properties
@@ -39,7 +39,7 @@
 HrefMissing = Manca l'attributo 'href' di un elemento 'include'.
 RecursiveInclude = Inclusione ricorsiva rilevata. Il documento ''{0}'' \u00E8 gi\u00E0 stato elaborato.
 InvalidParseValue = Valore non valido per l''attributo ''parse'' nell''elemento ''include'': ''{0}''.
-XMLParseError = Errore nel tentativo di analizzare il file XML (href=''{0}'').
+XMLParseError = Errore nel tentativo di analizzare il file XML (href=''{0}''). Motivo: {1}
 XMLResourceError = Operazione di inclusione non riuscita. Verr\u00E0 ripristinato il fallback. Errore di risorsa durante la lettura del file come XML (href=''{0}''). Motivo: {1}
 TextResourceError = Operazione di inclusione non riuscita. Verr\u00E0 ripristinato il fallback. Errore di risorsa durante la lettura del file come testo (href=''{0}''). Motivo: {1}
 NO_XPointerSchema = Lo schema per \"{0}\" non \u00E8 supportato per impostazione predefinita. Definire il proprio schema per {0}. Vedere http://apache.org/xml/properties/xpointer-schema.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_ja.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_ja.properties
index d17b8db..6b88fe8 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_ja.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_ja.properties
@@ -39,7 +39,7 @@
 HrefMissing = 'include'\u8981\u7D20\u306E'href'\u5C5E\u6027\u304C\u3042\u308A\u307E\u305B\u3093\u3002
 RecursiveInclude = \u518D\u5E30\u7684\u306Ainclude\u304C\u691C\u51FA\u3055\u308C\u307E\u3057\u305F\u3002\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8''{0}''\u306F\u3059\u3067\u306B\u51E6\u7406\u3055\u308C\u3066\u3044\u307E\u3059\u3002
 InvalidParseValue = ''include''\u8981\u7D20\u306E''parse''\u5C5E\u6027\u306E\u5024\u304C\u7121\u52B9\u3067\u3059: ''{0}''\u3002
-XMLParseError = XML\u30D5\u30A1\u30A4\u30EB\u306E\u89E3\u6790\u8A66\u884C\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F(href=''{0}'')\u3002
+XMLParseError = XML\u30D5\u30A1\u30A4\u30EB\u306E\u89E3\u6790\u8A66\u884C\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F(href=''{0}'')\u3002\u7406\u7531: {1}
 XMLResourceError = \u30A4\u30F3\u30AF\u30EB\u30FC\u30C9\u64CD\u4F5C\u304C\u5931\u6557\u3057\u3001\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF\u306B\u623B\u308A\u307E\u3059\u3002\u30D5\u30A1\u30A4\u30EB\u3092XML\u3068\u3057\u3066\u8AAD\u53D6\u308A\u4E2D\u306B\u30EA\u30BD\u30FC\u30B9\u30FB\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F(href=''{0}'')\u3002\u7406\u7531: {1}
 TextResourceError = \u30A4\u30F3\u30AF\u30EB\u30FC\u30C9\u64CD\u4F5C\u304C\u5931\u6557\u3057\u3001\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF\u306B\u623B\u308A\u307E\u3059\u3002\u30D5\u30A1\u30A4\u30EB\u3092\u30C6\u30AD\u30B9\u30C8\u3068\u3057\u3066\u8AAD\u53D6\u308A\u4E2D\u306B\u30EA\u30BD\u30FC\u30B9\u30FB\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F(href=''{0}'')\u3002\u7406\u7531: {1}
 NO_XPointerSchema = \u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001\"{0}\"\u306E\u30B9\u30AD\u30FC\u30DE\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002{0}\u306B\u5BFE\u3057\u3066\u72EC\u81EA\u306E\u30B9\u30AD\u30FC\u30DE\u3092\u5B9A\u7FA9\u3057\u3066\u304F\u3060\u3055\u3044\u3002http://apache.org/xml/properties/xpointer-schema\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_ko.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_ko.properties
index 430d660..570b7a7 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_ko.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_ko.properties
@@ -39,7 +39,7 @@
 HrefMissing = 'include' \uC694\uC18C\uC758 'href' \uC18D\uC131\uC774 \uB204\uB77D\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
 RecursiveInclude = \uC21C\uD658 include\uAC00 \uAC10\uC9C0\uB418\uC5C8\uC2B5\uB2C8\uB2E4. ''{0}'' \uBB38\uC11C\uAC00 \uC774\uBBF8 \uCC98\uB9AC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
 InvalidParseValue = ''include'' \uC694\uC18C\uC5D0 ''parse'' \uC18D\uC131\uC5D0 \uB300\uD574 \uBD80\uC801\uD569\uD55C \uAC12\uC774 \uC788\uC74C: ''{0}''.
-XMLParseError = XML \uD30C\uC77C(href=''{0}'')\uC758 \uAD6C\uBB38\uC744 \uBD84\uC11D\uD558\uB824\uACE0 \uC2DC\uB3C4\uD558\uB294 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.
+XMLParseError = XML \uD30C\uC77C(href=''{0}'')\uC758 \uAD6C\uBB38\uC744 \uBD84\uC11D\uD558\uB824\uACE0 \uC2DC\uB3C4\uD558\uB294 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.\uC6D0\uC778: {1}
 XMLResourceError = Include \uC791\uC5C5\uC744 \uC2E4\uD328\uD558\uC5EC fallback\uC73C\uB85C \uBCF5\uC6D0\uD558\uB294 \uC911\uC785\uB2C8\uB2E4. \uD30C\uC77C\uC744 XML(href=''{0}'')\uB85C \uC77D\uB294 \uC911 \uB9AC\uC18C\uC2A4 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. \uC6D0\uC778: {1}
 TextResourceError = Include \uC791\uC5C5\uC744 \uC2E4\uD328\uD558\uC5EC fallback\uC73C\uB85C \uBCF5\uC6D0\uD558\uB294 \uC911\uC785\uB2C8\uB2E4. \uD30C\uC77C\uC744 \uD14D\uC2A4\uD2B8(href=''{0}'')\uB85C \uC77D\uB294 \uC911 \uB9AC\uC18C\uC2A4 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. \uC6D0\uC778: {1}
 NO_XPointerSchema = \uAE30\uBCF8\uC801\uC73C\uB85C \"{0}\"\uC5D0 \uB300\uD55C \uC2A4\uD0A4\uB9C8\uB294 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. {0}\uC5D0 \uB300\uD574 \uACE0\uC720\uD55C \uC2A4\uD0A4\uB9C8\uB97C \uC815\uC758\uD558\uC2ED\uC2DC\uC624. http://apache.org/xml/properties/xpointer-schema\uB97C \uCC38\uC870\uD558\uC2ED\uC2DC\uC624.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_pt_BR.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_pt_BR.properties
index 8d5b021..5abd826 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_pt_BR.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_pt_BR.properties
@@ -39,7 +39,7 @@
 HrefMissing = O atributo 'href' de um elemento 'include' n\u00E3o foi encontrado.
 RecursiveInclude = Inclus\u00E3o recursiva detectada. O documento ''{0}'' j\u00E1 foi processado.
 InvalidParseValue = Valor inv\u00E1lido para o atributo ''parse'' no elemento ''include'': ''{0}''.
-XMLParseError = Erro ao tentar fazer parse do arquivo XML (href=''{0}'').
+XMLParseError = Erro ao tentar fazer parse do arquivo XML (href=''{0}'').  Motivo: {1}
 XMLResourceError = Falha na opera\u00E7\u00E3o de inclus\u00E3o; revertendo para fallback. Erro do recurso ao ler o arquivo como XML (href=''{0}''). Motivo: {1}
 TextResourceError = Falha na opera\u00E7\u00E3o de inclus\u00E3o; revertendo para fallback. Erro do recurso ao ler o arquivo como texto (href=''{0}''). Motivo: {1}
 NO_XPointerSchema = Por default, o esquema para \"{0}\" n\u00E3o \u00E9 suportado. Defina seu pr\u00F3prio esquema para {0}. Consulte http://apache.org/xml/properties/xpointer-schema
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_sv.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_sv.properties
index 6f0d1f3..426a5fa 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_sv.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_sv.properties
@@ -39,7 +39,7 @@
 HrefMissing = Ett 'href'-attribut i ett 'include'-element saknas.
 RecursiveInclude = Rekursiv inkludering uppt\u00E4cktes. Dokumentet ''{0}'' har redan bearbetats.
 InvalidParseValue = Ogiltigt v\u00E4rde f\u00F6r ''parse''-attribut i ''include''-element: ''{0}''.
-XMLParseError = Fel vid f\u00F6rs\u00F6k att tolka XML-fil (href=''{0}'').
+XMLParseError = Fel vid f\u00F6rs\u00F6k att tolka XML-fil (href=''{0}''). Orsak: {1}
 XMLResourceError = Inkluderings\u00E5tg\u00E4rden utf\u00F6rdes inte, \u00E5terst\u00E4ller genom att \u00E5terskapa. Resursfel vid l\u00E4sning av fil som XML (href=''{0}''). Orsak: {1}
 TextResourceError = Inkluderings\u00E5tg\u00E4rden utf\u00F6rdes inte, \u00E5terst\u00E4ller genom att \u00E5terskapa. Resursfel vid l\u00E4sning av fil som text (href=''{0}''). Orsak: {1}
 NO_XPointerSchema = Schema f\u00F6r \"{0}\" st\u00F6ds inte som standard. Definiera ett eget schema f\u00F6r {0}.Se http://apache.org/xml/properties/xpointer-schema
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_zh_CN.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_zh_CN.properties
index 3a36b4b..bcbb3aa 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_zh_CN.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_zh_CN.properties
@@ -39,7 +39,7 @@
 HrefMissing = \u7F3A\u5C11 'include' \u5143\u7D20\u7684 'href' \u5C5E\u6027\u3002
 RecursiveInclude = \u68C0\u6D4B\u5230\u9012\u5F52 include\u3002\u5DF2\u5904\u7406\u6587\u6863 ''{0}''\u3002
 InvalidParseValue = ''include'' \u5143\u7D20\u7684 ''parse'' \u5C5E\u6027\u7684\u503C\u65E0\u6548: ''{0}''\u3002
-XMLParseError = \u5C1D\u8BD5\u5BF9 XML \u6587\u4EF6 (href=''{0}'') \u8FDB\u884C\u8BED\u6CD5\u5206\u6790\u65F6\u51FA\u9519\u3002
+XMLParseError = \u5C1D\u8BD5\u5BF9 XML \u6587\u4EF6 (href=''{0}'') \u8FDB\u884C\u8BED\u6CD5\u5206\u6790\u65F6\u51FA\u9519\u3002\u539F\u56E0: {1}
 XMLResourceError = Include \u64CD\u4F5C\u5931\u8D25, \u5E76\u8FD8\u539F\u4E3A fallback\u3002\u4EE5 XML (href=''{0}'') \u683C\u5F0F\u8BFB\u53D6\u6587\u4EF6\u65F6\u51FA\u73B0\u8D44\u6E90\u9519\u8BEF\u3002\u539F\u56E0: {1}
 TextResourceError = Include \u64CD\u4F5C\u5931\u8D25, \u5E76\u8FD8\u539F\u4E3A fallback\u3002\u4EE5\u6587\u672C (href=''{0}'') \u683C\u5F0F\u8BFB\u53D6\u6587\u4EF6\u65F6\u51FA\u73B0\u8D44\u6E90\u9519\u8BEF\u3002\u539F\u56E0: {1}
 NO_XPointerSchema = \u9ED8\u8BA4\u60C5\u51B5\u4E0B, \u4E0D\u652F\u6301 \"{0}\" \u7684\u65B9\u6848\u3002\u8BF7\u4E3A{0}\u5B9A\u4E49\u60A8\u81EA\u5DF1\u7684\u65B9\u6848\u3002\u8BF7\u8BBF\u95EE http://apache.org/xml/properties/xpointer-schema
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_zh_TW.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_zh_TW.properties
index 33948e3..11cff31 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_zh_TW.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_zh_TW.properties
@@ -39,7 +39,7 @@
 HrefMissing = \u907A\u6F0F 'include' \u5143\u7D20\u7684 'href' \u5C6C\u6027\u3002
 RecursiveInclude = \u5075\u6E2C\u5230\u905E\u8FF4\u5305\u542B\u3002\u5DF2\u7D93\u8655\u7406\u6587\u4EF6 ''{0}''\u3002
 InvalidParseValue = ''include'' \u5143\u7D20\u4E0A ''parse'' \u5C6C\u6027\u7684\u7121\u6548\u503C: ''{0}''\u3002
-XMLParseError = \u5617\u8A66\u5256\u6790 XML \u6A94\u6848\u6642\u767C\u751F\u932F\u8AA4 (href=''{0}'')\u3002
+XMLParseError = \u5617\u8A66\u5256\u6790 XML \u6A94\u6848\u6642\u767C\u751F\u932F\u8AA4 (href=''{0}'')\u3002\u539F\u56E0: {1}
 XMLResourceError = \u5305\u542B\u4F5C\u696D\u5931\u6557\uFF0C\u56DE\u5FA9\u81F3\u5F8C\u63F4\u3002\u4EE5 XML (href=''{0}'') \u65B9\u5F0F\u8B80\u53D6\u6A94\u6848\u6642\u767C\u751F\u8CC7\u6E90\u932F\u8AA4\u3002\u539F\u56E0: {1}
 TextResourceError = \u5305\u542B\u4F5C\u696D\u5931\u6557\uFF0C\u56DE\u5FA9\u81F3\u5F8C\u63F4\u3002\u4EE5\u6587\u5B57 (href=''{0}'') \u65B9\u5F0F\u8B80\u53D6\u6A94\u6848\u6642\u767C\u751F\u8CC7\u6E90\u932F\u8AA4\u3002\u539F\u56E0: {1}
 NO_XPointerSchema = \u9810\u8A2D\u4E0D\u652F\u63F4 \"{0}\" \u7684\u7DB1\u8981\u3002\u8ACB\u70BA {0} \u5B9A\u7FA9\u60A8\u81EA\u5DF1\u7684\u7DB1\u8981\u3002\u8ACB\u53C3\u95B1 http://apache.org/xml/properties/xpointer-schema
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties
index 133f428..3bf9ebd 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties
@@ -261,6 +261,9 @@
 # Entity related messages
 # 3.1 Start-Tags, End-Tags, and Empty-Element Tags
         ReferenceToExternalEntity = The external entity reference \"&{0};\" is not permitted in an attribute value.
+        AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+        AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
 # 4.1 Character and Entity References
         EntityNotDeclared = The entity \"{0}\" was referenced, but not declared.
         ReferenceToUnparsedEntity = The unparsed entity reference \"&{0};\" is not permitted.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties
index 29bbccfb..3cf21e5 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties
@@ -289,6 +289,9 @@
 # Entity related messages
 # 3.1 Start-Tags, End-Tags, and Empty-Element Tags
         ReferenceToExternalEntity = Externe Entit\u00E4tsreferenz \"&{0};\" ist in einem Attributwert nicht zul\u00E4ssig.
+        AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+        AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
 # 4.1 Character and Entity References
         EntityNotDeclared = Entit\u00E4t \"{0}\" wurde referenziert aber nicht deklariert.
         ReferenceToUnparsedEntity = Nicht geparste Entit\u00E4tsreferenz \"&{0};\" ist nicht zul\u00E4ssig.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties
index f8227e2..5ebfaf0 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties
@@ -289,6 +289,9 @@
 # Entity related messages
 # 3.1 Start-Tags, End-Tags, and Empty-Element Tags
         ReferenceToExternalEntity = La referencia de entidad externa \"&{0};\" no est\u00E1 permitida en un valor de atributo.
+        AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+        AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
 # 4.1 Character and Entity References
         EntityNotDeclared = Se hizo referencia a la entidad \"{0}\", pero no se declar\u00F3.
         ReferenceToUnparsedEntity = La referencia de entidad no analizada \"&{0};\" no est\u00E1 permitida.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties
index cc0c6bf..f60b073 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties
@@ -289,6 +289,9 @@
 # Entity related messages
 # 3.1 Start-Tags, End-Tags, and Empty-Element Tags
         ReferenceToExternalEntity = La r\u00E9f\u00E9rence d''entit\u00E9 externe \"&{0};\" n''est pas autoris\u00E9e dans une valeur d''attribut.
+        AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+        AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
 # 4.1 Character and Entity References
         EntityNotDeclared = L''entit\u00E9 \"{0}\" \u00E9tait r\u00E9f\u00E9renc\u00E9e, mais pas d\u00E9clar\u00E9e.
         ReferenceToUnparsedEntity = La r\u00E9f\u00E9rence d''entit\u00E9 non analys\u00E9e \"&{0};\" n''est pas autoris\u00E9e.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties
index 03f8ce2..e525777 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties
@@ -289,6 +289,9 @@
 # Entity related messages
 # 3.1 Start-Tags, End-Tags, and Empty-Element Tags
         ReferenceToExternalEntity = Il riferimento di entit\u00E0 esterna \"&{0};\" non \u00E8 consentito in un valore di attributo.
+        AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+        AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
 # 4.1 Character and Entity References
         EntityNotDeclared = L''entit\u00E0 \"{0}\" \u00E8 indicata da un riferimento, ma non \u00E8 dichiarata.
         ReferenceToUnparsedEntity = Il riferimento di entit\u00E0 non analizzata \"&{0};\" non \u00E8 consentito.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ja.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ja.properties
index e837075..ed54869 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ja.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ja.properties
@@ -289,6 +289,9 @@
 # Entity related messages
 # 3.1 Start-Tags, End-Tags, and Empty-Element Tags
         ReferenceToExternalEntity = \u5916\u90E8\u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\u53C2\u7167\"&{0};\"\u306F\u3001\u5C5E\u6027\u5024\u3067\u306F\u8A31\u53EF\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002
+        AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+        AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
 # 4.1 Character and Entity References
         EntityNotDeclared = \u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\"{0}\"\u304C\u53C2\u7167\u3055\u308C\u3066\u3044\u307E\u3059\u304C\u3001\u5BA3\u8A00\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002
         ReferenceToUnparsedEntity = \u672A\u89E3\u6790\u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\u53C2\u7167\"&{0};\"\u306F\u8A31\u53EF\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ko.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ko.properties
index 8262f88..882f808 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ko.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ko.properties
@@ -289,6 +289,9 @@
 # Entity related messages
 # 3.1 Start-Tags, End-Tags, and Empty-Element Tags
         ReferenceToExternalEntity = \uC18D\uC131\uAC12\uC5D0\uC11C\uB294 \uC678\uBD80 \uC5D4\uD2F0\uD2F0 \uCC38\uC870 \"&{0};\"\uC774 \uD5C8\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
+        AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+        AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
 # 4.1 Character and Entity References
         EntityNotDeclared = \"{0}\" \uC5D4\uD2F0\uD2F0\uAC00 \uCC38\uC870\uB418\uC5C8\uC9C0\uB9CC \uC120\uC5B8\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.
         ReferenceToUnparsedEntity = \uAD6C\uBB38\uC774 \uBD84\uC11D\uB418\uC9C0 \uC54A\uC740 \uC5D4\uD2F0\uD2F0 \uCC38\uC870 \"&{0};\"\uC740(\uB294) \uD5C8\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_pt_BR.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_pt_BR.properties
index 94eebc6..57770dc 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_pt_BR.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_pt_BR.properties
@@ -289,6 +289,9 @@
 # Entity related messages
 # 3.1 Start-Tags, End-Tags, and Empty-Element Tags
         ReferenceToExternalEntity = A refer\u00EAncia da entidade externa \"&{0};\" n\u00E3o \u00E9 permitida em um valor do atributo.
+        AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+        AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
 # 4.1 Character and Entity References
         EntityNotDeclared = A entidade \"{0}\" foi referenciada, mas n\u00E3o declarada.
         ReferenceToUnparsedEntity = A refer\u00EAncia da entidade n\u00E3o submetida a parse \"&{0};\" n\u00E3o \u00E9 permitida.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_sv.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_sv.properties
index 6777adb..8c0bb0f 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_sv.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_sv.properties
@@ -289,6 +289,9 @@
 # Entity related messages
 # 3.1 Start-Tags, End-Tags, and Empty-Element Tags
         ReferenceToExternalEntity = Den externa enhetsreferensen \"&{0};\" till\u00E5ts inte i ett attributv\u00E4rde.
+        AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+        AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
 # 4.1 Character and Entity References
         EntityNotDeclared = Enheten \"{0}\" har refererats, men \u00E4r inte deklarerad.
         ReferenceToUnparsedEntity = Den otolkade enhetsreferensen \"&{0};\" \u00E4r inte till\u00E5ten.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_CN.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_CN.properties
index 959f147..74a7a06 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_CN.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_CN.properties
@@ -289,6 +289,9 @@
 # Entity related messages
 # 3.1 Start-Tags, End-Tags, and Empty-Element Tags
         ReferenceToExternalEntity = \u5C5E\u6027\u503C\u4E2D\u4E0D\u5141\u8BB8\u91C7\u7528\u5916\u90E8\u5B9E\u4F53\u5F15\u7528 \"&{0};\"\u3002
+        AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+        AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
 # 4.1 Character and Entity References
         EntityNotDeclared = \u5F15\u7528\u4E86\u5B9E\u4F53 \"{0}\", \u4F46\u672A\u58F0\u660E\u5B83\u3002
         ReferenceToUnparsedEntity = \u4E0D\u5141\u8BB8\u4F7F\u7528\u672A\u8FDB\u884C\u8BED\u6CD5\u5206\u6790\u7684\u5B9E\u4F53\u5F15\u7528 \"&{0};\"\u3002
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_TW.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_TW.properties
index 7495d31..1a95381 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_TW.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_TW.properties
@@ -289,6 +289,9 @@
 # Entity related messages
 # 3.1 Start-Tags, End-Tags, and Empty-Element Tags
         ReferenceToExternalEntity = \u5C6C\u6027\u503C\u4E0D\u5141\u8A31\u53C3\u7167\u5916\u90E8\u500B\u9AD4 \"&{0};\"\u3002
+        AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
+        AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+
 # 4.1 Character and Entity References
         EntityNotDeclared = \u53C3\u7167\u4E86\u500B\u9AD4 \"{0}\"\uFF0C\u4F46\u662F\u672A\u5BA3\u544A\u3002
         ReferenceToUnparsedEntity = \u4E0D\u5141\u8A31\u672A\u5256\u6790\u7684\u500B\u9AD4\u53C3\u7167 \"&{0};\"\u3002
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties
index d2e8471..23234a4 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties
@@ -86,6 +86,7 @@
 
 #schema valid (3.X.3)
 
+        schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
         schema_reference.4 = schema_reference.4: Failed to read schema document ''{0}'', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.
         src-annotation = src-annotation: <annotation> elements can only contain <appinfo> and <documentation> elements, but ''{0}'' was found.
         src-attribute.1 = src-attribute.1: The properties ''default'' and ''fixed'' cannot both be present in attribute declaration ''{0}''. Use only one of them.
@@ -289,6 +290,3 @@
         TargetNamespace.2 = TargetNamespace.2: Expecting no namespace, but the schema document has a target namespace of ''{1}''.
         UndeclaredEntity = UndeclaredEntity: Entity ''{0}'' is not declared.
         UndeclaredPrefix = UndeclaredPrefix: Cannot resolve ''{0}'' as a QName: the prefix ''{1}'' is not declared.
-null
-null
-null
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_de.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_de.properties
index 755985e..eed78fb 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_de.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_de.properties
@@ -114,6 +114,7 @@
 
 #schema valid (3.X.3)
 
+        schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
         schema_reference.4 = schema_reference.4: Schemadokument "{0}" konnte nicht gelesen werden, da 1) das Dokument nicht gefunden werden konnte; 2) das Dokument nicht gelesen werden konnte; 3) das Root-Element des Dokuments nicht <xsd:schema> ist.
         src-annotation = src-annotation: <annotation>-Elemente k\u00F6nnen nur <appinfo>- und <documentation>-Elemente enthalten, aber es wurde "{0}" gefunden.
         src-attribute.1 = src-attribute.1: Die Eigenschaften "default" und "fixed" k\u00F6nnen nicht beide in der Attributdeklaration "{0}" vorhanden sein. Verwenden Sie nur eine dieser Eigenschaften.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_es.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_es.properties
index 3a4e15c..b5e6560 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_es.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_es.properties
@@ -114,6 +114,7 @@
 
 #schema valid (3.X.3)
 
+        schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
         schema_reference.4 = schema_reference.4: Fallo al leer el documento de esquema ''{0}'', porque 1) no se ha encontrado el documento; 2) no se ha podido leer el documento; 3) el elemento ra\u00EDz del documento no es <xsd:schema>.
         src-annotation = src-annotation: Los elementos de <annotation> s\u00F3lo pueden contener elementos de <appinfo> y <documentation>, pero se ha encontrado ''{0}''.
         src-attribute.1 = src-attribute.1: Las propiedades ''default'' y ''fixed'' no pueden estar presentes de forma simult\u00E1nea en la declaraci\u00F3n de atributo ''{0}''. Utilice s\u00F3lo una de ellas.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_fr.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_fr.properties
index 24e910c..f3c3156 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_fr.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_fr.properties
@@ -114,6 +114,7 @@
 
 #schema valid (3.X.3)
 
+        schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
         schema_reference.4 = schema_reference.4 : Echec de la lecture du document de sch\u00E9ma ''{0}'' pour les raisons suivantes : 1) Le document est introuvable ; 2) Le document n''a pas pu \u00EAtre lu ; 3) L''\u00E9l\u00E9ment racine du document n''est pas <xsd:schema>.
         src-annotation = src-annotation : Les \u00E9l\u00E9ments <annotation> ne peuvent contenir que des \u00E9l\u00E9ments <appinfo> et <documentation>, mais ''{0}'' a \u00E9t\u00E9 trouv\u00E9.
         src-attribute.1 = src-attribute.1 : Les propri\u00E9t\u00E9s ''default'' et ''fixed'' ne peuvent pas figurer simultan\u00E9ment dans la d\u00E9claration d''attribut ''{0}''. Utilisez uniquement l''une d''entre elles.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_it.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_it.properties
index 638d400..4153c6d 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_it.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_it.properties
@@ -114,6 +114,7 @@
 
 #schema valid (3.X.3)
 
+        schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
         schema_reference.4 = schema_reference.4: lettura del documento di schema "{0}" non riuscita perch\u00E9 1) non \u00E8 stato possibile trovare il documento; 2) non \u00E8 stato possibile leggere il documento; 3) l''elemento radice del documento non \u00E8 <xsd:schema>.
         src-annotation = src-annotation: possono essere contenuti soltanto elementi <appinfo> e <documentation>, ma \u00E8 stato trovato ''{0}''.
         src-attribute.1 = src-attribute.1: le propriet\u00E0 ''default'' e ''fixed'' non possono essere entrambi presenti nella dichiarazione di attributo ''{0}''. Utilizzarne solo una.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_ja.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_ja.properties
index 536f78c..9fe30e2 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_ja.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_ja.properties
@@ -114,6 +114,7 @@
 
 #schema valid (3.X.3)
 
+        schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
         schema_reference.4 = schema_reference.4: 1)\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u304C\u898B\u3064\u304B\u3089\u306A\u304B\u3063\u305F\u30012)\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u8AAD\u307F\u53D6\u308C\u306A\u304B\u3063\u305F\u30013)\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u30EB\u30FC\u30C8\u8981\u7D20\u304C<xsd:schema>\u3067\u306F\u306A\u304B\u3063\u305F\u305F\u3081\u3001\u30B9\u30AD\u30FC\u30DE\u30FB\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8''{0}''\u306E\u8AAD\u53D6\u308A\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002
         src-annotation = src-annotation: <annotation>\u8981\u7D20\u306B\u542B\u3081\u308B\u3053\u3068\u304C\u3067\u304D\u308B\u306E\u306F<appinfo>\u8981\u7D20\u304A\u3088\u3073<documentation>\u8981\u7D20\u306E\u307F\u3067\u3059\u304C\u3001''{0}''\u304C\u898B\u3064\u304B\u308A\u307E\u3057\u305F\u3002
         src-attribute.1 = src-attribute.1: ''default''\u3068''fixed''\u306E\u4E21\u65B9\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u5C5E\u6027\u5BA3\u8A00''{0}''\u306B\u542B\u3081\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\u3002\u3044\u305A\u308C\u304B\u4E00\u65B9\u306E\u307F\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_ko.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_ko.properties
index 102466b..a6a77f32 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_ko.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_ko.properties
@@ -114,6 +114,7 @@
 
 #schema valid (3.X.3)
 
+        schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
         schema_reference.4 = schema_reference.4: \uC2A4\uD0A4\uB9C8 \uBB38\uC11C ''{0}'' \uC77D\uAE30\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uC6D0\uC778: 1) \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. 2) \uBB38\uC11C\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. 3) \uBB38\uC11C\uC758 \uB8E8\uD2B8 \uC694\uC18C\uAC00 <xsd:schema>\uAC00 \uC544\uB2D9\uB2C8\uB2E4.
         src-annotation = src-annotation: <annotation> \uC694\uC18C\uC5D0\uB294 <appinfo> \uBC0F <documentation> \uC694\uC18C\uB9CC \uD3EC\uD568\uB420 \uC218 \uC788\uC9C0\uB9CC ''{0}''\uC774(\uAC00) \uBC1C\uACAC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
         src-attribute.1 = src-attribute.1: ''default'' \uBC0F ''fixed'' \uC18D\uC131\uC740 \uC18D\uC131 \uC120\uC5B8 ''{0}''\uC5D0 \uD568\uAED8 \uC874\uC7AC\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uD558\uB098\uB9CC \uC0AC\uC6A9\uD558\uC2ED\uC2DC\uC624.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_pt_BR.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_pt_BR.properties
index e3bee29..163fc6d 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_pt_BR.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_pt_BR.properties
@@ -114,6 +114,7 @@
 
 #schema valid (3.X.3)
 
+        schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
         schema_reference.4 = schema_reference.4: Falha ao ler o documento do esquema ''{0}'' porque 1) n\u00E3o foi poss\u00EDvel encontrar o documento; 2) n\u00E3o foi poss\u00EDvel ler o documento; 3) o elemento-raiz do documento n\u00E3o \u00E9 <xsd:schema>.
         src-annotation = src-annotation: os elementos de <annotation> podem conter somente os elementos <appinfo> e <documentation>, mas foi encontrado ''{0}''.
         src-attribute.1 = src-attribute.1: As propriedades ''default'' e ''fixed'' n\u00E3o podem estar presentes na declara\u00E7\u00E3o do atributo ''{0}''. Use somente uma delas.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_sv.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_sv.properties
index 0332f51..4cc42ca 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_sv.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_sv.properties
@@ -114,6 +114,7 @@
 
 #schema valid (3.X.3)
 
+        schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
         schema_reference.4 = schema_reference.4: L\u00E4sning av schemadokument ''{0}'' utf\u00F6rdes inte p\u00E5 grund av 1) det g\u00E5r inte att hitta dokumentet; 2) det g\u00E5r inte att l\u00E4sa dokumentet; 3) dokumentets rotelement \u00E4r inte <xsd:schema>.
         src-annotation = src-annotation: element f\u00F6r <anteckningar> f\u00E5r endast inneh\u00E5lla element f\u00F6r <appinfo> och <dokumentation>, men ''{0}'' hittades.
         src-attribute.1 = src-attribute.1: B\u00E5da egenskaperna ''default'' och ''fixed'' kan inte samtidigt ing\u00E5 i attributdeklarationen ''{0}''. Anv\u00E4nd en av dem.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_zh_CN.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_zh_CN.properties
index ef0338a..f517a72 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_zh_CN.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_zh_CN.properties
@@ -114,6 +114,7 @@
 
 #schema valid (3.X.3)
 
+        schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
         schema_reference.4 = schema_reference.4: \u65E0\u6CD5\u8BFB\u53D6\u65B9\u6848\u6587\u6863 ''{0}'', \u539F\u56E0\u4E3A 1) \u65E0\u6CD5\u627E\u5230\u6587\u6863; 2) \u65E0\u6CD5\u8BFB\u53D6\u6587\u6863; 3) \u6587\u6863\u7684\u6839\u5143\u7D20\u4E0D\u662F <xsd:schema>\u3002
         src-annotation = src-annotation: <annotation> \u5143\u7D20\u53EA\u80FD\u5305\u542B <appinfo> \u548C <documentation> \u5143\u7D20, \u4F46\u53D1\u73B0\u4E86 ''{0}''\u3002
         src-attribute.1 = src-attribute.1: \u5C5E\u6027\u58F0\u660E ''{0}'' \u4E2D\u4E0D\u80FD\u540C\u65F6\u5B58\u5728\u7279\u6027 ''default'' \u548C ''fixed''\u3002\u5E94\u53EA\u4F7F\u7528\u5176\u4E2D\u4E00\u4E2A\u3002
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_zh_TW.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_zh_TW.properties
index a61dc7c..8661de4 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_zh_TW.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_zh_TW.properties
@@ -114,6 +114,7 @@
 
 #schema valid (3.X.3)
 
+        schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
         schema_reference.4 = schema_reference.4: \u7121\u6CD5\u8B80\u53D6\u7DB1\u8981\u6587\u4EF6 ''{0}''\uFF0C\u56E0\u70BA 1) \u627E\u4E0D\u5230\u6587\u4EF6; 2) \u7121\u6CD5\u8B80\u53D6\u6587\u4EF6; 3) \u6587\u4EF6\u7684\u6839\u5143\u7D20\u4E0D\u662F <xsd:schema>\u3002
         src-annotation = src-annotation: <annotation> \u5143\u7D20\u50C5\u80FD\u5305\u542B <appinfo> \u8207 <documentation> \u5143\u7D20\uFF0C\u4F46\u627E\u5230 ''{0}''\u3002
         src-attribute.1 = src-attribute.1: \u5C6C\u6027 ''default'' \u8207 ''fixed'' \u4E0D\u53EF\u540C\u6642\u51FA\u73FE\u5728\u5C6C\u6027\u5BA3\u544A ''{0}'' \u4E2D\u3002\u8ACB\u53EA\u4F7F\u7528\u5176\u4E2D\u4E00\u500B\u3002
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java
index 4b7ba13..3fbe234 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java
@@ -53,6 +53,7 @@
 import com.sun.org.apache.xerces.internal.util.Status;
 import com.sun.org.apache.xerces.internal.util.SymbolTable;
 import com.sun.org.apache.xerces.internal.util.XMLSymbols;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
 import com.sun.org.apache.xerces.internal.xni.XNIException;
 import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
@@ -71,6 +72,7 @@
 import com.sun.org.apache.xerces.internal.xs.XSModel;
 import java.util.HashMap;
 import java.util.Map;
+import javax.xml.XMLConstants;
 import org.w3c.dom.DOMConfiguration;
 import org.w3c.dom.DOMError;
 import org.w3c.dom.DOMErrorHandler;
@@ -216,6 +218,12 @@
     protected static final String ENTITY_MANAGER =
         Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
 
+    /** Property identifier: access to external dtd */
+    public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+    /** Property identifier: access to external schema */
+    public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
     // recognized properties
     private static final String [] RECOGNIZED_PROPERTIES = {
         ENTITY_MANAGER,
@@ -229,7 +237,9 @@
         JAXP_SCHEMA_SOURCE,
         SECURITY_MANAGER,
         LOCALE,
-        SCHEMA_DV_FACTORY
+        SCHEMA_DV_FACTORY,
+        ACCESS_EXTERNAL_DTD,
+        ACCESS_EXTERNAL_SCHEMA
     };
 
     // Data
@@ -260,6 +270,8 @@
     private final CMNodeFactory fNodeFactory = new CMNodeFactory(); //component mgr will be set later
     private CMBuilder fCMBuilder;
     private XSDDescription fXSDDescription = new XSDDescription();
+    private String faccessExternalDTD = Constants.EXTERNAL_ACCESS_DEFAULT;
+    private String faccessExternalSchema = Constants.EXTERNAL_ACCESS_DEFAULT;
 
     private Map fJAXPCache;
     private Locale fLocale = Locale.getDefault();
@@ -454,6 +466,12 @@
                 fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, new XSMessageFormatter());
             }
         }
+        else if (propertyId.equals(ACCESS_EXTERNAL_DTD)) {
+            faccessExternalDTD = (String) state;
+        }
+        else if (propertyId.equals(ACCESS_EXTERNAL_SCHEMA)) {
+            faccessExternalSchema = (String) state;
+        }
     } // setProperty(String, Object)
 
     /**
@@ -585,6 +603,15 @@
         if(!fJAXPProcessed) {
             processJAXPSchemaSource(locationPairs);
         }
+
+        if (desc.isExternal()) {
+            String accessError = SecuritySupport.checkAccess(desc.getExpandedSystemId(), faccessExternalSchema, Constants.ACCESS_EXTERNAL_ALL);
+            if (accessError != null) {
+                throw new XNIException(fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
+                        "schema_reference.access",
+                        new Object[] { SecuritySupport.sanitizePath(desc.getExpandedSystemId()), accessError }, XMLErrorReporter.SEVERITY_ERROR));
+            }
+        }
         SchemaGrammar grammar = fSchemaHandler.parseSchema(source, desc, locationPairs);
 
         return grammar;
@@ -1038,6 +1065,9 @@
         // get generate-synthetic-annotations feature
         fSchemaHandler.setGenerateSyntheticAnnotations(componentManager.getFeature(GENERATE_SYNTHETIC_ANNOTATIONS, false));
         fSchemaHandler.reset(componentManager);
+
+        faccessExternalDTD = (String) componentManager.getProperty(ACCESS_EXTERNAL_DTD);
+        faccessExternalSchema = (String) componentManager.getProperty(ACCESS_EXTERNAL_SCHEMA);
     }
 
     private void initGrammarBucket(){
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java
index c14673e..170601c 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java
@@ -29,7 +29,7 @@
 import java.util.Stack;
 import java.util.Vector;
 import java.util.ArrayList;
-
+import javax.xml.XMLConstants;
 import com.sun.org.apache.xerces.internal.impl.Constants;
 import com.sun.org.apache.xerces.internal.impl.RevalidationHandler;
 import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
@@ -233,6 +233,12 @@
     protected static final String SCHEMA_DV_FACTORY =
         Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY;
 
+    /** property identifier: access external dtd. */
+    private static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+    /** Property identifier: access to external schema */
+    private static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
     protected static final String USE_SERVICE_MECHANISM = Constants.ORACLE_FEATURE_SERVICE_MECHANISM;
 
     // recognized features and properties
@@ -291,11 +297,13 @@
             JAXP_SCHEMA_SOURCE,
             JAXP_SCHEMA_LANGUAGE,
             SCHEMA_DV_FACTORY,
+            ACCESS_EXTERNAL_DTD,
+            ACCESS_EXTERNAL_SCHEMA
             };
 
     /** Property defaults. */
     private static final Object[] PROPERTY_DEFAULTS =
-        { null, null, null, null, null, null, null, null, null, null, null};
+        { null, null, null, null, null, null, null, null, null, null, null, null, null};
 
     // this is the number of valuestores of each kind
     // we expect an element to have.  It's almost
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XSDDescription.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XSDDescription.java
index 8e09b9f..c35baa8 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XSDDescription.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XSDDescription.java
@@ -34,6 +34,7 @@
  * @author Neil Graham, IBM
  * @author Neeraj Bajaj, SUN Microsystems.
  *
+ * @version $Id: XSDDescription.java,v 1.6 2010-11-01 04:39:55 joehw Exp $
  */
 public class XSDDescription extends XMLResourceIdentifierImpl
                 implements XMLSchemaDescription {
@@ -181,6 +182,17 @@
     }
 
     /**
+     * @return true is the schema is external
+     */
+    public boolean isExternal() {
+        return fContextType == CONTEXT_INCLUDE ||
+               fContextType == CONTEXT_REDEFINE ||
+               fContextType == CONTEXT_IMPORT ||
+               fContextType == CONTEXT_ELEMENT ||
+               fContextType == CONTEXT_ATTRIBUTE ||
+               fContextType == CONTEXT_XSITYPE;
+    }
+    /**
      * Compares this grammar with the given grammar. Currently, we compare
      * the target namespaces.
      *
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java
index 7c9974e..eba1ac0 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java
@@ -77,6 +77,7 @@
 import com.sun.org.apache.xerces.internal.util.SymbolTable;
 import com.sun.org.apache.xerces.internal.util.XMLSymbols;
 import com.sun.org.apache.xerces.internal.util.URI.MalformedURIException;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
 import com.sun.org.apache.xerces.internal.xni.QName;
 import com.sun.org.apache.xerces.internal.xni.XNIException;
 import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
@@ -105,6 +106,7 @@
 import com.sun.org.apache.xerces.internal.xs.XSTerm;
 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
 import com.sun.org.apache.xerces.internal.xs.datatypes.ObjectList;
+import javax.xml.XMLConstants;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -221,6 +223,12 @@
     protected static final String LOCALE =
         Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY;
 
+    /** property identifier: access external dtd. */
+    public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+    /** Property identifier: access to external schema */
+    public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
     protected static final boolean DEBUG_NODE_POOL = false;
 
     // Data
@@ -251,6 +259,8 @@
      */
     protected SecurityManager fSecureProcessing = null;
 
+    private String fAccessExternalSchema;
+
     // These tables correspond to the symbol spaces defined in the
     // spec.
     // They are keyed with a QName (that is, String("URI,localpart) and
@@ -2150,6 +2160,15 @@
                         fLastSchemaWasDuplicate = true;
                         return schemaElement;
                     }
+                    if (referType == XSDDescription.CONTEXT_IMPORT || referType == XSDDescription.CONTEXT_INCLUDE
+                            || referType == XSDDescription.CONTEXT_REDEFINE) {
+                        String accessError = SecuritySupport.checkAccess(schemaId, fAccessExternalSchema, Constants.ACCESS_EXTERNAL_ALL);
+                        if (accessError != null) {
+                            reportSchemaFatalError("schema_reference.access",
+                                    new Object[] { SecuritySupport.sanitizePath(schemaId), accessError },
+                                    referElement);
+                        }
+                    }
                 }
 
                 fSchemaParser.parse(schemaSource);
@@ -3561,6 +3580,11 @@
         } catch (XMLConfigurationException e) {
         }
 
+        //For Schema validation, the secure feature is set to true by default
+        fSchemaParser.setProperty(ACCESS_EXTERNAL_DTD,
+                componentManager.getProperty(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT));
+        fAccessExternalSchema = (String) componentManager.getProperty(
+                ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT);
     } // reset(XMLComponentManager)
 
 
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderFactoryImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderFactoryImpl.java
index af14049..aea63c2 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderFactoryImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderFactoryImpl.java
@@ -37,7 +37,7 @@
 /**
  * @author Rajiv Mordani
  * @author Edwin Goei
- * @version $Id: DocumentBuilderFactoryImpl.java,v 1.6 2009/07/28 23:48:32 joehw Exp $
+ * @version $Id: DocumentBuilderFactoryImpl.java,v 1.8 2010-11-01 04:40:06 joehw Exp $
  */
 public class DocumentBuilderFactoryImpl extends DocumentBuilderFactory {
     /** These are DocumentBuilderFactory attributes not DOM attributes */
@@ -191,6 +191,9 @@
 
     public void setFeature(String name, boolean value)
         throws ParserConfigurationException {
+        if (features == null) {
+            features = new Hashtable();
+        }
         // If this is the secure processing feature, save it then return.
         if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
             if (System.getSecurityManager() != null && (!value)) {
@@ -199,11 +202,10 @@
                         "jaxp-secureprocessing-feature", null));
             }
             fSecureProcess = value;
+            features.put(name, value ? Boolean.TRUE : Boolean.FALSE);
             return;
         }
-        if (features == null) {
-            features = new Hashtable();
-        }
+
         features.put(name, value ? Boolean.TRUE : Boolean.FALSE);
         // Test the feature by possibly throwing SAX exceptions
         try {
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java
index 84bab42..39112a6 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java
@@ -27,6 +27,7 @@
 
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.validation.Schema;
+import javax.xml.XMLConstants;
 
 import com.sun.org.apache.xerces.internal.dom.DOMImplementationImpl;
 import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter;
@@ -42,6 +43,7 @@
 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
 import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
+import javax.xml.XMLConstants;
 import org.w3c.dom.DOMImplementation;
 import org.w3c.dom.Document;
 import org.xml.sax.EntityResolver;
@@ -95,6 +97,12 @@
     private static final String SECURITY_MANAGER =
         Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
 
+    /** property identifier: access external dtd. */
+    public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+    /** Property identifier: access to external schema */
+    public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
     private final DOMParser domParser;
     private final Schema grammar;
 
@@ -155,6 +163,23 @@
         // If the secure processing feature is on set a security manager.
         if (secureProcessing) {
             domParser.setProperty(SECURITY_MANAGER, new SecurityManager());
+
+            /**
+             * By default, secure processing is set, no external access is allowed.
+             * However, we need to check if it is actively set on the factory since we
+             * allow the use of the System Property or jaxp.properties to override
+             * the default value
+             */
+            if (features != null) {
+                Object temp = features.get(XMLConstants.FEATURE_SECURE_PROCESSING);
+                if (temp != null) {
+                    boolean value = ((Boolean) temp).booleanValue();
+                    if (value) {
+                        domParser.setProperty(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
+                        domParser.setProperty(ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
+                    }
+                }
+            }
         }
 
         this.grammar = dbf.getSchema();
@@ -211,6 +236,10 @@
                 String feature = (String) entry.getKey();
                 boolean value = ((Boolean) entry.getValue()).booleanValue();
                 domParser.setFeature(feature, value);
+                if (feature.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
+                    domParser.setProperty(ACCESS_EXTERNAL_DTD, "");
+                    domParser.setProperty(ACCESS_EXTERNAL_SCHEMA, "");
+                }
             }
         }
     }
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserFactoryImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserFactoryImpl.java
index eecdc10..ae9d995 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserFactoryImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserFactoryImpl.java
@@ -43,7 +43,7 @@
  * @author Rajiv Mordani
  * @author Edwin Goei
  *
- * @version $Id: SAXParserFactoryImpl.java,v 1.7 2009/07/28 23:48:32 joehw Exp $
+ * @version $Id: SAXParserFactoryImpl.java,v 1.9 2010-11-01 04:40:06 joehw Exp $
  */
 public class SAXParserFactoryImpl extends SAXParserFactory {
 
@@ -124,6 +124,7 @@
                         "jaxp-secureprocessing-feature", null));
             }
             fSecureProcess = value;
+            putInFeatures(name, value);
             return;
         }
 
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java
index 58d7d16..bbb609e 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java
@@ -92,6 +92,12 @@
     private static final String SECURITY_MANAGER =
         Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
 
+    /** property identifier: access external dtd. */
+    public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+    /** Property identifier: access to external schema */
+    public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
     private final JAXPSAXParser xmlReader;
     private String schemaLanguage = null;     // null means DTD
     private final Schema grammar;
@@ -146,6 +152,22 @@
         // If the secure processing feature is on set a security manager.
         if (secureProcessing) {
             xmlReader.setProperty0(SECURITY_MANAGER, new SecurityManager());
+            /**
+             * By default, secure processing is set, no external access is allowed.
+             * However, we need to check if it is actively set on the factory since we
+             * allow the use of the System Property or jaxp.properties to override
+             * the default value
+             */
+            if (features != null) {
+                Object temp = features.get(XMLConstants.FEATURE_SECURE_PROCESSING);
+                if (temp != null) {
+                    boolean value = ((Boolean) temp).booleanValue();
+                    if (value) {
+                        xmlReader.setProperty0(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
+                        xmlReader.setProperty0(ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
+                    }
+                }
+            }
         }
 
         // Set application's features, followed by validation features.
@@ -220,6 +242,10 @@
                 String feature = (String) entry.getKey();
                 boolean value = ((Boolean) entry.getValue()).booleanValue();
                 xmlReader.setFeature0(feature, value);
+                if (feature.equals(XMLConstants.FEATURE_SECURE_PROCESSING) && value) {
+                    xmlReader.setProperty0(ACCESS_EXTERNAL_DTD, "");
+                    xmlReader.setProperty0(ACCESS_EXTERNAL_SCHEMA, "");
+                }
             }
         }
     }
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/AbstractXMLSchema.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/AbstractXMLSchema.java
index 696dd9e..25e13a7 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/AbstractXMLSchema.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/AbstractXMLSchema.java
@@ -41,8 +41,15 @@
      */
     private final HashMap fFeatures;
 
+    /**
+     * Map containing the initial values of properties for
+     * validators created using this grammar pool container.
+     */
+    private final HashMap fProperties;
+
     public AbstractXMLSchema() {
         fFeatures = new HashMap();
+        fProperties = new HashMap();
     }
 
     /*
@@ -77,11 +84,26 @@
     }
 
     /*
-     * Other methods
+     * Set a feature on the schema
      */
-
-    final void setFeature(String featureId, boolean state) {
+    public final void setFeature(String featureId, boolean state) {
         fFeatures.put(featureId, state ? Boolean.TRUE : Boolean.FALSE);
     }
 
+    /**
+     * Returns the initial value of a property for validators created
+     * using this grammar pool container or null if the validators
+     * should use the default value.
+     */
+    public final Object getProperty(String propertyId) {
+        return fProperties.get(propertyId);
+    }
+
+    /*
+     * Set a property on the schema
+     */
+    public final void setProperty(String propertyId, Object state) {
+        fProperties.put(propertyId, state);
+    }
+
 } // AbstractXMLSchema
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java
index 3919c0c..1b4f687 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java
@@ -32,6 +32,7 @@
 import javax.xml.transform.TransformerConfigurationException;
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.XMLConstants;
 
 import com.sun.org.apache.xerces.internal.impl.Constants;
 import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
@@ -176,6 +177,8 @@
         }
         config.setProperty(SYMBOL_TABLE, fComponentManager.getProperty(SYMBOL_TABLE));
         config.setProperty(VALIDATION_MANAGER, fComponentManager.getProperty(VALIDATION_MANAGER));
+        config.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
+                fComponentManager.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
         config.setDocumentHandler(fSchemaValidator);
         config.setDTDHandler(null);
         config.setDTDContentModelHandler(null);
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java
index 2d9f280..e53118b 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java
@@ -675,6 +675,8 @@
                     spf.setNamespaceAware(true);
                     try {
                         reader = spf.newSAXParser().getXMLReader();
+                           reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
+                                   fComponentManager.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
                         // If this is a Xerces SAX parser, set the security manager if there is one
                         if (reader instanceof com.sun.org.apache.xerces.internal.parsers.SAXParser) {
                            SecurityManager securityManager = (SecurityManager) fComponentManager.getProperty(SECURITY_MANAGER);
@@ -685,6 +687,8 @@
                                // Ignore the exception if the security manager cannot be set.
                                catch (SAXException exc) {}
                            }
+                           reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
+                                   fComponentManager.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
                         }
                     } catch( Exception e ) {
                         // this is impossible, but better safe than sorry
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java
index fece15d..4cac487 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java
@@ -45,6 +45,7 @@
 import com.sun.org.apache.xerces.internal.util.StAXInputSource;
 import com.sun.org.apache.xerces.internal.util.Status;
 import com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImpl;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
 import com.sun.org.apache.xerces.internal.xni.XNIException;
 import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
@@ -82,6 +83,12 @@
     private static final String SECURITY_MANAGER =
         Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
 
+    /** property identifier: access external dtd. */
+    public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+    /** Property identifier: access to external schema  */
+    public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
     //
     // Data
     //
@@ -132,6 +139,14 @@
         // Enable secure processing feature by default
         fSecurityManager = new SecurityManager();
         fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager);
+
+        //by default, the secure feature is set to true, otherwise the default would have been 'file'
+        String accessExternal = SecuritySupport.getDefaultAccessProperty(
+                Constants.SP_ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT);
+        fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_DTD, accessExternal);
+        accessExternal = SecuritySupport.getDefaultAccessProperty(
+                Constants.SP_ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT);
+        fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_SCHEMA, accessExternal);
     }
 
     /**
@@ -274,6 +289,7 @@
         // Use a Schema that uses the system id as the equality source.
         AbstractXMLSchema schema = new WeakReferenceXMLSchema();
         propagateFeatures(schema);
+        propagateProperties(schema);
         return schema;
     }
 
@@ -350,6 +366,8 @@
             }
             fSecurityManager = value ? new SecurityManager() : null;
             fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager);
+            fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
+            fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
             return;
         } else if (name.equals(Constants.ORACLE_FEATURE_SERVICE_MECHANISM)) {
             //in secure mode, let _useServicesMechanism be determined by the constructor
@@ -418,6 +436,15 @@
         }
     }
 
+    private void propagateProperties(AbstractXMLSchema schema) {
+        String[] properties = fXMLSchemaLoader.getRecognizedProperties();
+        for (int i = 0; i < properties.length; ++i) {
+            Object state = fXMLSchemaLoader.getProperty(properties[i]);
+            schema.setProperty(properties[i], state);
+        }
+    }
+
+
     /**
      * Extension of XMLGrammarPoolImpl which exposes the number of
      * grammars stored in the grammar pool.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java
index bc4bdef..241d02c 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java
@@ -123,6 +123,12 @@
     private static final String LOCALE =
         Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY;
 
+    /** property identifier: access external dtd. */
+    private static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+    /** Property identifier: access to external schema  */
+    private static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
     //
     // Data
     //
@@ -243,6 +249,9 @@
         }
         fComponents.put(SECURITY_MANAGER, fInitSecurityManager);
 
+        //pass on properties set on SchemaFactory
+        setProperty(ACCESS_EXTERNAL_DTD, grammarContainer.getProperty(ACCESS_EXTERNAL_DTD));
+        setProperty(ACCESS_EXTERNAL_SCHEMA, grammarContainer.getProperty(ACCESS_EXTERNAL_SCHEMA));
     }
 
     /**
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XSGrammarPoolContainer.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XSGrammarPoolContainer.java
index 0246f37..79ef559 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XSGrammarPoolContainer.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XSGrammarPoolContainer.java
@@ -55,4 +55,21 @@
      */
     public Boolean getFeature(String featureId);
 
+    /*
+     * Set a feature on the schema
+     */
+    public void setFeature(String featureId, boolean state);
+
+    /**
+     * Returns the initial value of a property for validators created
+     * using this grammar pool container or null if the validators
+     * should use the default value.
+     */
+    public Object getProperty(String propertyId);
+
+    /*
+     * Set a property on the schema
+     */
+    public void setProperty(String propertyId, Object state);
+
 }
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java
index 72acd0a..32ac6a8 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java
@@ -20,10 +20,13 @@
 
 package com.sun.org.apache.xerces.internal.parsers;
 
+import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Locale;
+import java.util.Properties;
+import javax.xml.XMLConstants;
 
 import com.sun.org.apache.xerces.internal.impl.Constants;
 import com.sun.org.apache.xerces.internal.impl.XML11DTDScannerImpl;
@@ -52,6 +55,7 @@
 import com.sun.org.apache.xerces.internal.util.PropertyState;
 import com.sun.org.apache.xerces.internal.util.Status;
 import com.sun.org.apache.xerces.internal.util.SymbolTable;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
 import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler;
 import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler;
 import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
@@ -274,6 +278,12 @@
     protected static final String SCHEMA_DV_FACTORY =
         Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY;
 
+    /** Property identifier: access to external dtd */
+    protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+    /** Property identifier: access to external schema */
+    protected static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
+
     // debugging
 
     /** Set to true and recompile to print exception stack trace. */
@@ -475,7 +485,8 @@
                 XMLSCHEMA_VALIDATION, XMLSCHEMA_FULL_CHECKING,
                                 EXTERNAL_GENERAL_ENTITIES,
                                 EXTERNAL_PARAMETER_ENTITIES,
-                                PARSER_SETTINGS
+                                PARSER_SETTINGS,
+                                XMLConstants.FEATURE_SECURE_PROCESSING
                         };
         addRecognizedFeatures(recognizedFeatures);
                 // set state for default features
@@ -488,30 +499,31 @@
                 fFeatures.put(SCHEMA_ELEMENT_DEFAULT, Boolean.TRUE);
                 fFeatures.put(NORMALIZE_DATA, Boolean.TRUE);
                 fFeatures.put(SCHEMA_AUGMENT_PSVI, Boolean.TRUE);
-        fFeatures.put(GENERATE_SYNTHETIC_ANNOTATIONS, Boolean.FALSE);
-        fFeatures.put(VALIDATE_ANNOTATIONS, Boolean.FALSE);
-        fFeatures.put(HONOUR_ALL_SCHEMALOCATIONS, Boolean.FALSE);
-        fFeatures.put(NAMESPACE_GROWTH, Boolean.FALSE);
-        fFeatures.put(TOLERATE_DUPLICATES, Boolean.FALSE);
-        fFeatures.put(USE_GRAMMAR_POOL_ONLY, Boolean.FALSE);
+                fFeatures.put(GENERATE_SYNTHETIC_ANNOTATIONS, Boolean.FALSE);
+                fFeatures.put(VALIDATE_ANNOTATIONS, Boolean.FALSE);
+                fFeatures.put(HONOUR_ALL_SCHEMALOCATIONS, Boolean.FALSE);
+                fFeatures.put(NAMESPACE_GROWTH, Boolean.FALSE);
+                fFeatures.put(TOLERATE_DUPLICATES, Boolean.FALSE);
+                fFeatures.put(USE_GRAMMAR_POOL_ONLY, Boolean.FALSE);
                 fFeatures.put(PARSER_SETTINGS, Boolean.TRUE);
+                fFeatures.put(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
 
         // add default recognized properties
         final String[] recognizedProperties =
             {
-                                SYMBOL_TABLE,
-                                ERROR_HANDLER,
-                                ENTITY_RESOLVER,
+                SYMBOL_TABLE,
+                ERROR_HANDLER,
+                ENTITY_RESOLVER,
                 ERROR_REPORTER,
                 ENTITY_MANAGER,
                 DOCUMENT_SCANNER,
                 DTD_SCANNER,
                 DTD_PROCESSOR,
                 DTD_VALIDATOR,
-                                DATATYPE_VALIDATOR_FACTORY,
-                                VALIDATION_MANAGER,
-                                SCHEMA_VALIDATOR,
-                                XML_STRING,
+                DATATYPE_VALIDATOR_FACTORY,
+                VALIDATION_MANAGER,
+                SCHEMA_VALIDATOR,
+                XML_STRING,
                 XMLGRAMMAR_POOL,
                 JAXP_SCHEMA_SOURCE,
                 JAXP_SCHEMA_LANGUAGE,
@@ -523,18 +535,20 @@
                 SCHEMA_NONS_LOCATION,
                 LOCALE,
                 SCHEMA_DV_FACTORY,
+                ACCESS_EXTERNAL_DTD,
+                ACCESS_EXTERNAL_SCHEMA
         };
         addRecognizedProperties(recognizedProperties);
 
-                if (symbolTable == null) {
-                        symbolTable = new SymbolTable();
-                }
-                fSymbolTable = symbolTable;
-                fProperties.put(SYMBOL_TABLE, fSymbolTable);
+        if (symbolTable == null) {
+                symbolTable = new SymbolTable();
+        }
+        fSymbolTable = symbolTable;
+        fProperties.put(SYMBOL_TABLE, fSymbolTable);
 
         fGrammarPool = grammarPool;
         if (fGrammarPool != null) {
-                        fProperties.put(XMLGRAMMAR_POOL, fGrammarPool);
+            fProperties.put(XMLGRAMMAR_POOL, fGrammarPool);
         }
 
         fEntityManager = new XMLEntityManager();
@@ -570,6 +584,15 @@
 
         fVersionDetector = new XMLVersionDetector();
 
+        //FEATURE_SECURE_PROCESSING is true, see the feature above
+        String accessExternal =  SecuritySupport.getDefaultAccessProperty(
+                Constants.SP_ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT);
+        fProperties.put(ACCESS_EXTERNAL_DTD, accessExternal);
+
+        accessExternal =  SecuritySupport.getDefaultAccessProperty(
+                Constants.SP_ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT);
+        fProperties.put(ACCESS_EXTERNAL_SCHEMA, accessExternal);
+
         // add message formatters
         if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
             XMLMessageFormatter xmft = new XMLMessageFormatter();
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/util/URI.java b/jaxp/src/com/sun/org/apache/xerces/internal/util/URI.java
index 0f35b8e..e420f26 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/util/URI.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/util/URI.java
@@ -22,6 +22,7 @@
 
 import java.io.IOException;
 import java.io.Serializable;
+import java.util.Objects;
 
 /**********************************************************************
 * A class to represent a Uniform Resource Identifier (URI). This class
@@ -1212,7 +1213,7 @@
   * @return the scheme-specific part for this URI
   */
   public String getSchemeSpecificPart() {
-    StringBuffer schemespec = new StringBuffer();
+    final StringBuilder schemespec = new StringBuilder();
 
     if (m_host != null || m_regAuthority != null) {
       schemespec.append("//");
@@ -1297,7 +1298,7 @@
    * @return the authority
    */
   public String getAuthority() {
-      StringBuffer authority = new StringBuffer();
+      final StringBuilder authority = new StringBuilder();
       if (m_host != null || m_regAuthority != null) {
           authority.append("//");
 
@@ -1340,7 +1341,7 @@
   */
   public String getPath(boolean p_includeQueryString,
                         boolean p_includeFragment) {
-    StringBuffer pathString = new StringBuffer(m_path);
+    final StringBuilder pathString = new StringBuilder(m_path);
 
     if (p_includeQueryString && m_queryString != null) {
       pathString.append('?');
@@ -1683,6 +1684,7 @@
   * @return true if p_test is a URI with all values equal to this
   *         URI, false otherwise
   */
+  @Override
   public boolean equals(Object p_test) {
     if (p_test instanceof URI) {
       URI testURI = (URI) p_test;
@@ -1711,13 +1713,27 @@
     return false;
   }
 
+    @Override
+    public int hashCode() {
+        int hash = 5;
+        hash = 47 * hash + Objects.hashCode(this.m_scheme);
+        hash = 47 * hash + Objects.hashCode(this.m_userinfo);
+        hash = 47 * hash + Objects.hashCode(this.m_host);
+        hash = 47 * hash + this.m_port;
+        hash = 47 * hash + Objects.hashCode(this.m_path);
+        hash = 47 * hash + Objects.hashCode(this.m_queryString);
+        hash = 47 * hash + Objects.hashCode(this.m_fragment);
+        return hash;
+    }
+
  /**
   * Get the URI as a string specification. See RFC 2396 Section 5.2.
   *
   * @return the URI string specification
   */
+  @Override
   public String toString() {
-    StringBuffer uriSpecString = new StringBuffer();
+    final StringBuilder uriSpecString = new StringBuilder();
 
     if (m_scheme != null) {
       uriSpecString.append(m_scheme);
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/utils/SecuritySupport.java b/jaxp/src/com/sun/org/apache/xerces/internal/utils/SecuritySupport.java
index b1d9d87..7b6d1d5 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/utils/SecuritySupport.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/SecuritySupport.java
@@ -23,14 +23,16 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.io.InputStream;
-
+import java.net.URL;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
 import java.util.Locale;
 import java.util.MissingResourceException;
+import java.util.Properties;
 import java.util.PropertyResourceBundle;
 import java.util.ResourceBundle;
 
@@ -195,5 +197,141 @@
                 })).longValue();
     }
 
+    /**
+     * Strip off path from an URI
+     *
+     * @param uri an URI with full path
+     * @return the file name only
+     */
+    public static String sanitizePath(String uri) {
+        if (uri == null) {
+            return "";
+        }
+        int i = uri.lastIndexOf("/");
+        if (i > 0) {
+            return uri.substring(i+1, uri.length());
+        }
+        return "";
+    }
+
+    /**
+     * Check the protocol used in the systemId against allowed protocols
+     *
+     * @param systemId the Id of the URI
+     * @param allowedProtocols a list of allowed protocols separated by comma
+     * @param accessAny keyword to indicate allowing any protocol
+     * @return the name of the protocol if rejected, null otherwise
+     */
+    public static String checkAccess(String systemId, String allowedProtocols, String accessAny) throws IOException {
+        if (systemId == null || allowedProtocols.equalsIgnoreCase(accessAny)) {
+            return null;
+        }
+
+        String protocol;
+        if (systemId.indexOf(":")==-1) {
+            protocol = "file";
+        } else {
+            URL url = new URL(systemId);
+            protocol = url.getProtocol();
+            if (protocol.equalsIgnoreCase("jar")) {
+                String path = url.getPath();
+                protocol = path.substring(0, path.indexOf(":"));
+            }
+        }
+
+        if (isProtocolAllowed(protocol, allowedProtocols)) {
+            //access allowed
+            return null;
+        } else {
+            return protocol;
+        }
+    }
+
+    /**
+     * Check if the protocol is in the allowed list of protocols. The check
+     * is case-insensitive while ignoring whitespaces.
+     *
+     * @param protocol a protocol
+     * @param allowedProtocols a list of allowed protocols
+     * @return true if the protocol is in the list
+     */
+    private static boolean isProtocolAllowed(String protocol, String allowedProtocols) {
+         String temp[] = allowedProtocols.split(",");
+         for (String t : temp) {
+             t = t.trim();
+             if (t.equalsIgnoreCase(protocol)) {
+                 return true;
+             }
+         }
+         return false;
+     }
+
+    /**
+     * Read from $java.home/lib/jaxp.properties for the specified property
+     *
+     * @param propertyId the Id of the property
+     * @return the value of the property
+     */
+    public static String getDefaultAccessProperty(String sysPropertyId, String defaultVal) {
+        String accessExternal = SecuritySupport.getSystemProperty(sysPropertyId);
+        if (accessExternal == null) {
+            accessExternal = readJAXPProperty(sysPropertyId);
+            if (accessExternal == null) {
+                accessExternal = defaultVal;
+            }
+        }
+        return accessExternal;
+    }
+
+     /**
+     * Read from $java.home/lib/jaxp.properties for the specified property
+     * The program
+     *
+     * @param propertyId the Id of the property
+     * @return the value of the property
+     */
+    static String readJAXPProperty(String propertyId) {
+        String value = null;
+        InputStream is = null;
+        try {
+            if (firstTime) {
+                synchronized (cacheProps) {
+                    if (firstTime) {
+                        String configFile = getSystemProperty("java.home") + File.separator +
+                            "lib" + File.separator + "jaxp.properties";
+                        File f = new File(configFile);
+                        if (getFileExists(f)) {
+                            is = getFileInputStream(f);
+                            cacheProps.load(is);
+                        }
+                        firstTime = false;
+                    }
+                }
+            }
+            value = cacheProps.getProperty(propertyId);
+
+        }
+        catch (Exception ex) {}
+        finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException ex) {}
+            }
+        }
+
+        return value;
+    }
+
+   /**
+     * Cache for properties in java.home/lib/jaxp.properties
+     */
+    static final Properties cacheProps = new Properties();
+
+    /**
+     * Flag indicating if the program has tried reading java.home/lib/jaxp.properties
+     */
+    static volatile boolean firstTime = true;
+
     private SecuritySupport () {}
 }
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java b/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java
index 347ae24..ba72846 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java
@@ -26,6 +26,7 @@
 import java.util.Locale;
 import java.util.Stack;
 import java.util.StringTokenizer;
+import javax.xml.XMLConstants;
 
 import com.sun.org.apache.xerces.internal.impl.Constants;
 import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
@@ -67,6 +68,7 @@
 import com.sun.org.apache.xerces.internal.xpointer.XPointerHandler;
 import com.sun.org.apache.xerces.internal.xpointer.XPointerProcessor;
 import com.sun.org.apache.xerces.internal.utils.ObjectFactory;
+import java.util.Objects;
 
 /**
  * <p>
@@ -229,6 +231,14 @@
     protected static final String PARSER_SETTINGS =
         Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS;
 
+    /** property identifier: access external dtd. */
+    protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+    /** access external dtd: file protocol
+     *  For DOM/SAX, the secure feature is set to true by default
+     */
+    final static String EXTERNAL_ACCESS_DEFAULT = Constants.EXTERNAL_ACCESS_DEFAULT;
+
     /** Recognized features. */
     private static final String[] RECOGNIZED_FEATURES =
         { ALLOW_UE_AND_NOTATION_EVENTS, XINCLUDE_FIXUP_BASE_URIS, XINCLUDE_FIXUP_LANGUAGE };
@@ -283,6 +293,12 @@
     protected XMLErrorReporter fErrorReporter;
     protected XMLEntityResolver fEntityResolver;
     protected SecurityManager fSecurityManager;
+    /**
+     * comma-delimited list of protocols that are allowed for the purpose
+     * of accessing external dtd or entity references
+     */
+    protected String fAccessExternalDTD = EXTERNAL_ACCESS_DEFAULT;
+
 
     // these are needed for text include processing
     protected XIncludeTextReader fXInclude10TextReader;
@@ -375,6 +391,7 @@
 
     // XMLComponent methods
 
+    @Override
     public void reset(XMLComponentManager componentManager)
         throws XNIException {
         fNamespaceContext = null;
@@ -523,6 +540,8 @@
             fSecurityManager = null;
         }
 
+        fAccessExternalDTD = (String)componentManager.getProperty(ACCESS_EXTERNAL_DTD);
+
         // Get buffer size.
         try {
             Integer value =
@@ -580,6 +599,7 @@
      * this component. This method may return null if no features
      * are recognized by this component.
      */
+    @Override
     public String[] getRecognizedFeatures() {
         return (String[])(RECOGNIZED_FEATURES.clone());
     } // getRecognizedFeatures():String[]
@@ -599,6 +619,7 @@
      * @throws SAXNotSupportedException The component should not throw
      *                                  this exception.
      */
+    @Override
     public void setFeature(String featureId, boolean state)
         throws XMLConfigurationException {
         if (featureId.equals(ALLOW_UE_AND_NOTATION_EVENTS)) {
@@ -615,6 +636,7 @@
      * this component. This method may return null if no properties
      * are recognized by this component.
      */
+    @Override
     public String[] getRecognizedProperties() {
         return (String[])(RECOGNIZED_PROPERTIES.clone());
     } // getRecognizedProperties():String[]
@@ -634,6 +656,7 @@
      * @throws SAXNotSupportedException The component should not throw
      *                                  this exception.
      */
+    @Override
     public void setProperty(String propertyId, Object value)
         throws XMLConfigurationException {
         if (propertyId.equals(SYMBOL_TABLE)) {
@@ -664,6 +687,14 @@
             }
             return;
         }
+        if (propertyId.equals(ACCESS_EXTERNAL_DTD)) {
+            fAccessExternalDTD = (String)value;
+            if (fChildConfig != null) {
+                fChildConfig.setProperty(propertyId, value);
+            }
+            return;
+        }
+
         if (propertyId.equals(BUFFER_SIZE)) {
             Integer bufferSize = (Integer) value;
             if (fChildConfig != null) {
@@ -694,6 +725,7 @@
      *
      * @since Xerces 2.2.0
      */
+    @Override
     public Boolean getFeatureDefault(String featureId) {
         for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) {
             if (RECOGNIZED_FEATURES[i].equals(featureId)) {
@@ -712,6 +744,7 @@
      *
      * @since Xerces 2.2.0
      */
+    @Override
     public Object getPropertyDefault(String propertyId) {
         for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) {
             if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) {
@@ -721,10 +754,12 @@
         return null;
     } // getPropertyDefault(String):Object
 
+    @Override
     public void setDocumentHandler(XMLDocumentHandler handler) {
         fDocumentHandler = handler;
     }
 
+    @Override
     public XMLDocumentHandler getDocumentHandler() {
         return fDocumentHandler;
     }
@@ -739,6 +774,7 @@
      *
      * This event is only passed on to the document handler if this is the root document.
      */
+    @Override
     public void startDocument(
         XMLLocator locator,
         String encoding,
@@ -786,6 +822,7 @@
         }
     }
 
+    @Override
     public void xmlDecl(
         String version,
         String encoding,
@@ -798,6 +835,7 @@
         }
     }
 
+    @Override
     public void doctypeDecl(
         String rootElement,
         String publicId,
@@ -809,6 +847,7 @@
         }
     }
 
+    @Override
     public void comment(XMLString text, Augmentations augs)
         throws XNIException {
         if (!fInDTD) {
@@ -825,6 +864,7 @@
         }
     }
 
+    @Override
     public void processingInstruction(
         String target,
         XMLString data,
@@ -845,6 +885,7 @@
         }
     }
 
+    @Override
     public void startElement(
         QName element,
         XMLAttributes attributes,
@@ -915,6 +956,7 @@
         }
     }
 
+    @Override
     public void emptyElement(
         QName element,
         XMLAttributes attributes,
@@ -996,6 +1038,7 @@
         fDepth--;
     }
 
+    @Override
     public void endElement(QName element, Augmentations augs)
         throws XNIException {
 
@@ -1041,6 +1084,7 @@
         fDepth--;
     }
 
+    @Override
     public void startGeneralEntity(
         String name,
         XMLResourceIdentifier resId,
@@ -1059,6 +1103,7 @@
         }
     }
 
+    @Override
     public void textDecl(String version, String encoding, Augmentations augs)
         throws XNIException {
         if (fDocumentHandler != null
@@ -1067,6 +1112,7 @@
         }
     }
 
+    @Override
     public void endGeneralEntity(String name, Augmentations augs)
         throws XNIException {
         if (fDocumentHandler != null
@@ -1076,6 +1122,7 @@
         }
     }
 
+    @Override
     public void characters(XMLString text, Augmentations augs)
         throws XNIException {
         if (getState() == STATE_NORMAL_PROCESSING) {
@@ -1092,6 +1139,7 @@
         }
     }
 
+    @Override
     public void ignorableWhitespace(XMLString text, Augmentations augs)
         throws XNIException {
         if (fDocumentHandler != null
@@ -1101,6 +1149,7 @@
         }
     }
 
+    @Override
     public void startCDATA(Augmentations augs) throws XNIException {
         if (fDocumentHandler != null
             && getState() == STATE_NORMAL_PROCESSING
@@ -1109,6 +1158,7 @@
         }
     }
 
+    @Override
     public void endCDATA(Augmentations augs) throws XNIException {
         if (fDocumentHandler != null
             && getState() == STATE_NORMAL_PROCESSING
@@ -1117,6 +1167,7 @@
         }
     }
 
+    @Override
     public void endDocument(Augmentations augs) throws XNIException {
         if (isRootDocument()) {
             if (!fSeenRootElement) {
@@ -1128,10 +1179,12 @@
         }
     }
 
+    @Override
     public void setDocumentSource(XMLDocumentSource source) {
         fDocumentSource = source;
     }
 
+    @Override
     public XMLDocumentSource getDocumentSource() {
         return fDocumentSource;
     }
@@ -1143,6 +1196,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#attributeDecl(java.lang.String, java.lang.String, java.lang.String, java.lang.String[], java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.Augmentations)
      */
+    @Override
     public void attributeDecl(
         String elementName,
         String attributeName,
@@ -1169,6 +1223,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#elementDecl(java.lang.String, java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
      */
+    @Override
     public void elementDecl(
         String name,
         String contentModel,
@@ -1182,6 +1237,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endAttlist(com.sun.org.apache.xerces.internal.xni.Augmentations)
      */
+    @Override
     public void endAttlist(Augmentations augmentations) throws XNIException {
         if (fDTDHandler != null) {
             fDTDHandler.endAttlist(augmentations);
@@ -1191,6 +1247,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endConditional(com.sun.org.apache.xerces.internal.xni.Augmentations)
      */
+    @Override
     public void endConditional(Augmentations augmentations)
         throws XNIException {
         if (fDTDHandler != null) {
@@ -1201,6 +1258,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endDTD(com.sun.org.apache.xerces.internal.xni.Augmentations)
      */
+    @Override
     public void endDTD(Augmentations augmentations) throws XNIException {
         if (fDTDHandler != null) {
             fDTDHandler.endDTD(augmentations);
@@ -1211,6 +1269,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endExternalSubset(com.sun.org.apache.xerces.internal.xni.Augmentations)
      */
+    @Override
     public void endExternalSubset(Augmentations augmentations)
         throws XNIException {
         if (fDTDHandler != null) {
@@ -1221,6 +1280,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endParameterEntity(java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
      */
+    @Override
     public void endParameterEntity(String name, Augmentations augmentations)
         throws XNIException {
         if (fDTDHandler != null) {
@@ -1231,6 +1291,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#externalEntityDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, com.sun.org.apache.xerces.internal.xni.Augmentations)
      */
+    @Override
     public void externalEntityDecl(
         String name,
         XMLResourceIdentifier identifier,
@@ -1244,6 +1305,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#getDTDSource()
      */
+    @Override
     public XMLDTDSource getDTDSource() {
         return fDTDSource;
     }
@@ -1251,6 +1313,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#ignoredCharacters(com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.Augmentations)
      */
+    @Override
     public void ignoredCharacters(XMLString text, Augmentations augmentations)
         throws XNIException {
         if (fDTDHandler != null) {
@@ -1261,6 +1324,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#internalEntityDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.Augmentations)
      */
+    @Override
     public void internalEntityDecl(
         String name,
         XMLString text,
@@ -1279,6 +1343,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#notationDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, com.sun.org.apache.xerces.internal.xni.Augmentations)
      */
+    @Override
     public void notationDecl(
         String name,
         XMLResourceIdentifier identifier,
@@ -1293,6 +1358,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#setDTDSource(com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource)
      */
+    @Override
     public void setDTDSource(XMLDTDSource source) {
         fDTDSource = source;
     }
@@ -1300,6 +1366,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startAttlist(java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
      */
+    @Override
     public void startAttlist(String elementName, Augmentations augmentations)
         throws XNIException {
         if (fDTDHandler != null) {
@@ -1310,6 +1377,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startConditional(short, com.sun.org.apache.xerces.internal.xni.Augmentations)
      */
+    @Override
     public void startConditional(short type, Augmentations augmentations)
         throws XNIException {
         if (fDTDHandler != null) {
@@ -1320,6 +1388,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startDTD(com.sun.org.apache.xerces.internal.xni.XMLLocator, com.sun.org.apache.xerces.internal.xni.Augmentations)
      */
+    @Override
     public void startDTD(XMLLocator locator, Augmentations augmentations)
         throws XNIException {
         fInDTD = true;
@@ -1331,6 +1400,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startExternalSubset(com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, com.sun.org.apache.xerces.internal.xni.Augmentations)
      */
+    @Override
     public void startExternalSubset(
         XMLResourceIdentifier identifier,
         Augmentations augmentations)
@@ -1343,6 +1413,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startParameterEntity(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
      */
+    @Override
     public void startParameterEntity(
         String name,
         XMLResourceIdentifier identifier,
@@ -1361,6 +1432,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#unparsedEntityDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
      */
+    @Override
     public void unparsedEntityDecl(
         String name,
         XMLResourceIdentifier identifier,
@@ -1380,6 +1452,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource#getDTDHandler()
      */
+    @Override
     public XMLDTDHandler getDTDHandler() {
         return fDTDHandler;
     }
@@ -1387,6 +1460,7 @@
     /* (non-Javadoc)
      * @see com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource#setDTDHandler(com.sun.org.apache.xerces.internal.xni.XMLDTDHandler)
      */
+    @Override
     public void setDTDHandler(XMLDTDHandler handler) {
         fDTDHandler = handler;
     }
@@ -1578,6 +1652,7 @@
                 if (fErrorReporter != null) fChildConfig.setProperty(ERROR_REPORTER, fErrorReporter);
                 if (fEntityResolver != null) fChildConfig.setProperty(ENTITY_RESOLVER, fEntityResolver);
                 fChildConfig.setProperty(SECURITY_MANAGER, fSecurityManager);
+                fChildConfig.setProperty(ACCESS_EXTERNAL_DTD, fAccessExternalDTD);
                 fChildConfig.setProperty(BUFFER_SIZE, new Integer(fBufferSize));
 
                 // features must be copied to child configuration
@@ -1615,11 +1690,10 @@
                         fNamespaceContext);
 
                     ((XPointerHandler)fXPtrProcessor).setProperty(XINCLUDE_FIXUP_BASE_URIS,
-                            new Boolean(fFixupBaseURIs));
+                            fFixupBaseURIs);
 
                     ((XPointerHandler)fXPtrProcessor).setProperty(
-                            XINCLUDE_FIXUP_LANGUAGE,
-                            new Boolean (fFixupLanguage));
+                            XINCLUDE_FIXUP_LANGUAGE, fFixupLanguage);
 
                     if (fErrorReporter != null)
                         ((XPointerHandler)fXPtrProcessor).setProperty(ERROR_REPORTER, fErrorReporter);
@@ -1691,7 +1765,7 @@
                 if (fErrorReporter != null) {
                     fErrorReporter.setDocumentLocator(fDocLocation);
                 }
-                reportFatalError("XMLParseError", new Object[] { href });
+                reportFatalError("XMLParseError", new Object[] { href, e.getMessage() });
             }
             catch (IOException e) {
                 // necessary to make sure proper location is reported in errors
@@ -2093,14 +2167,14 @@
                 /** Check whether the scheme components are equal. */
                 final String baseScheme = base.getScheme();
                 final String literalScheme = uri.getScheme();
-                if (!isEqual(baseScheme, literalScheme)) {
+                if (!Objects.equals(baseScheme, literalScheme)) {
                     return relativeURI;
                 }
 
                 /** Check whether the authority components are equal. */
                 final String baseAuthority = base.getAuthority();
                 final String literalAuthority = uri.getAuthority();
-                if (!isEqual(baseAuthority, literalAuthority)) {
+                if (!Objects.equals(baseAuthority, literalAuthority)) {
                     return uri.getSchemeSpecificPart();
                 }
 
@@ -2113,7 +2187,7 @@
                 final String literalQuery = uri.getQueryString();
                 final String literalFragment = uri.getFragment();
                 if (literalQuery != null || literalFragment != null) {
-                    StringBuffer buffer = new StringBuffer();
+                    final StringBuilder buffer = new StringBuilder();
                     if (literalPath != null) {
                         buffer.append(literalPath);
                     }
@@ -2624,15 +2698,15 @@
 
         // equals() returns true if two Notations have the same name.
         // Useful for searching Vectors for notations with the same name
+        @Override
         public boolean equals(Object obj) {
-            if (obj == null) {
-                return false;
-            }
-            if (obj instanceof Notation) {
-                Notation other = (Notation)obj;
-                return name.equals(other.name);
-            }
-            return false;
+            return obj == this || obj instanceof Notation
+                    && Objects.equals(name, ((Notation)obj).name);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hashCode(name);
         }
 
         // from 4.5.2
@@ -2645,16 +2719,12 @@
         public boolean isDuplicate(Object obj) {
             if (obj != null && obj instanceof Notation) {
                 Notation other = (Notation)obj;
-                return name.equals(other.name)
-                && isEqual(publicId, other.publicId)
-                && isEqual(expandedSystemId, other.expandedSystemId);
+                return Objects.equals(name, other.name)
+                && Objects.equals(publicId, other.publicId)
+                && Objects.equals(expandedSystemId, other.expandedSystemId);
             }
             return false;
         }
-
-        private boolean isEqual(String one, String two) {
-            return (one == two || (one != null && one.equals(two)));
-        }
     }
 
     // This is a storage class to hold information about the unparsed entities.
@@ -2670,15 +2740,15 @@
 
         // equals() returns true if two UnparsedEntities have the same name.
         // Useful for searching Vectors for entities with the same name
+        @Override
         public boolean equals(Object obj) {
-            if (obj == null) {
-                return false;
-            }
-            if (obj instanceof UnparsedEntity) {
-                UnparsedEntity other = (UnparsedEntity)obj;
-                return name.equals(other.name);
-            }
-            return false;
+            return obj == this || obj instanceof UnparsedEntity
+                    && Objects.equals(name, ((UnparsedEntity)obj).name);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hashCode(name);
         }
 
         // from 4.5.1:
@@ -2691,17 +2761,13 @@
         public boolean isDuplicate(Object obj) {
             if (obj != null && obj instanceof UnparsedEntity) {
                 UnparsedEntity other = (UnparsedEntity)obj;
-                return name.equals(other.name)
-                && isEqual(publicId, other.publicId)
-                && isEqual(expandedSystemId, other.expandedSystemId)
-                && isEqual(notation, other.notation);
+                return Objects.equals(name, other.name)
+                && Objects.equals(publicId, other.publicId)
+                && Objects.equals(expandedSystemId, other.expandedSystemId)
+                && Objects.equals(notation, other.notation);
             }
             return false;
         }
-
-        private boolean isEqual(String one, String two) {
-            return (one == two || (one != null && one.equals(two)));
-        }
     }
 
     // The following methods are used for XML Base processing
@@ -2891,17 +2957,13 @@
         return httpSource;
     }
 
-    private boolean isEqual(String one, String two) {
-        return (one == two || (one != null && one.equals(two)));
-    }
-
     // which ASCII characters need to be escaped
-    private static boolean gNeedEscaping[] = new boolean[128];
+    private static final boolean gNeedEscaping[] = new boolean[128];
     // the first hex character if a character needs to be escaped
-    private static char gAfterEscaping1[] = new char[128];
+    private static final char gAfterEscaping1[] = new char[128];
     // the second hex character if a character needs to be escaped
-    private static char gAfterEscaping2[] = new char[128];
-    private static char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7',
+    private static final char gAfterEscaping2[] = new char[128];
+    private static final char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7',
                                      '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
     // initialize the above 3 arrays
     static {
@@ -2931,7 +2993,7 @@
     private String escapeHref(String href) {
         int len = href.length();
         int ch;
-        StringBuffer buffer = new StringBuffer(len*3);
+        final StringBuilder buffer = new StringBuilder(len*3);
 
         // for each character in the href
         int i = 0;
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/dtm/ref/DTMNodeProxy.java b/jaxp/src/com/sun/org/apache/xml/internal/dtm/ref/DTMNodeProxy.java
index fa86b06..d9ca5b0 100644
--- a/jaxp/src/com/sun/org/apache/xml/internal/dtm/ref/DTMNodeProxy.java
+++ b/jaxp/src/com/sun/org/apache/xml/internal/dtm/ref/DTMNodeProxy.java
@@ -27,6 +27,7 @@
 import com.sun.org.apache.xml.internal.dtm.DTM;
 import com.sun.org.apache.xml.internal.dtm.DTMDOMException;
 import com.sun.org.apache.xpath.internal.NodeSet;
+import java.util.Objects;
 
 import org.w3c.dom.Attr;
 import org.w3c.dom.CDATASection;
@@ -141,21 +142,21 @@
    *
    * @return true if the given node has the same handle as this node.
    */
+  @Override
   public final boolean equals(Object node)
   {
-
-    try
-    {
-
       // DTMNodeProxy dtmp = (DTMNodeProxy)node;
       // return (dtmp.node == this.node);
       // Patch attributed to Gary L Peskin <garyp@firstech.com>
-      return equals((Node) node);
-    }
-    catch (ClassCastException cce)
-    {
-      return false;
-    }
+      return node instanceof Node && equals((Node) node);
+  }
+
+  @Override
+  public int hashCode() {
+      int hash = 7;
+      hash = 29 * hash + Objects.hashCode(this.dtm);
+      hash = 29 * hash + this.node;
+      return hash;
   }
 
   /**
@@ -181,6 +182,7 @@
    *
    * @see org.w3c.dom.Node
    */
+  @Override
   public final String getNodeName()
   {
     return dtm.getNodeName(node);
@@ -199,6 +201,7 @@
    *
    *
    */
+  @Override
   public final String getTarget()
   {
     return dtm.getNodeName(node);
@@ -209,6 +212,7 @@
    *
    * @see org.w3c.dom.Node as of DOM Level 2
    */
+  @Override
   public final String getLocalName()
   {
     return dtm.getLocalName(node);
@@ -218,6 +222,7 @@
    * @return The prefix for this node.
    * @see org.w3c.dom.Node as of DOM Level 2
    */
+  @Override
   public final String getPrefix()
   {
     return dtm.getPrefix(node);
@@ -230,6 +235,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Node as of DOM Level 2 -- DTMNodeProxy is read-only
    */
+  @Override
   public final void setPrefix(String prefix) throws DOMException
   {
     throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
@@ -240,6 +246,7 @@
    *
    * @see org.w3c.dom.Node as of DOM Level 2
    */
+  @Override
   public final String getNamespaceURI()
   {
     return dtm.getNamespaceURI(node);
@@ -277,6 +284,7 @@
    * @return false
    * @see org.w3c.dom.Node as of DOM Level 2
    */
+  @Override
   public final boolean isSupported(String feature, String version)
   {
     return implementation.hasFeature(feature,version);
@@ -290,6 +298,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Node
    */
+  @Override
   public final String getNodeValue() throws DOMException
   {
     return dtm.getNodeValue(node);
@@ -312,6 +321,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
    */
+  @Override
   public final void setNodeValue(String nodeValue) throws DOMException
   {
     throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
@@ -322,6 +332,7 @@
    *
    * @see org.w3c.dom.Node
    */
+  @Override
   public final short getNodeType()
   {
     return (short) dtm.getNodeType(node);
@@ -332,6 +343,7 @@
    *
    * @see org.w3c.dom.Node
    */
+  @Override
   public final Node getParentNode()
   {
 
@@ -361,6 +373,7 @@
    *
    * @see org.w3c.dom.Node
    */
+  @Override
   public final NodeList getChildNodes()
   {
 
@@ -377,6 +390,7 @@
    *
    * @see org.w3c.dom.Node
    */
+  @Override
   public final Node getFirstChild()
   {
 
@@ -390,6 +404,7 @@
    *
    * @see org.w3c.dom.Node
    */
+  @Override
   public final Node getLastChild()
   {
 
@@ -403,6 +418,7 @@
    *
    * @see org.w3c.dom.Node
    */
+  @Override
   public final Node getPreviousSibling()
   {
 
@@ -416,6 +432,7 @@
    *
    * @see org.w3c.dom.Node
    */
+  @Override
   public final Node getNextSibling()
   {
 
@@ -435,6 +452,7 @@
    *
    * @see org.w3c.dom.Node
    */
+  @Override
   public final NamedNodeMap getAttributes()
   {
 
@@ -448,6 +466,7 @@
    * @param name
    *
    */
+  @Override
   public boolean hasAttribute(String name)
   {
     return DTM.NULL != dtm.getAttributeNode(node,null,name);
@@ -462,6 +481,7 @@
    *
    *
    */
+  @Override
   public boolean hasAttributeNS(String namespaceURI, String localName)
   {
     return DTM.NULL != dtm.getAttributeNode(node,namespaceURI,localName);
@@ -472,6 +492,7 @@
    *
    * @see org.w3c.dom.Node
    */
+  @Override
   public final Document getOwnerDocument()
   {
         // Note that this uses the DOM-compatable version of the call
@@ -488,6 +509,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
    */
+  @Override
   public final Node insertBefore(Node newChild, Node refChild)
     throws DOMException
   {
@@ -504,6 +526,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
    */
+  @Override
   public final Node replaceChild(Node newChild, Node oldChild)
     throws DOMException
   {
@@ -519,6 +542,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
    */
+  @Override
   public final Node removeChild(Node oldChild) throws DOMException
   {
     throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
@@ -533,6 +557,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
    */
+  @Override
   public final Node appendChild(Node newChild) throws DOMException
   {
     throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
@@ -543,6 +568,7 @@
    *
    * @see org.w3c.dom.Node
    */
+  @Override
   public final boolean hasChildNodes()
   {
     return (DTM.NULL != dtm.getFirstChild(node));
@@ -555,6 +581,7 @@
    *
    * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
    */
+  @Override
   public final Node cloneNode(boolean deep)
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -565,6 +592,7 @@
    *
    * @see org.w3c.dom.Document
    */
+  @Override
   public final DocumentType getDoctype()
   {
     return null;
@@ -575,6 +603,7 @@
    *
    * @see org.w3c.dom.Document
    */
+  @Override
   public final DOMImplementation getImplementation()
   {
     return implementation;
@@ -587,6 +616,7 @@
    *
    * @see org.w3c.dom.Document
    */
+  @Override
   public final Element getDocumentElement()
   {
                 int dochandle=dtm.getDocument();
@@ -634,6 +664,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Document
    */
+  @Override
   public final Element createElement(String tagName) throws DOMException
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -644,6 +675,7 @@
    *
    * @see org.w3c.dom.Document
    */
+  @Override
   public final DocumentFragment createDocumentFragment()
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -656,6 +688,7 @@
    *
    * @see org.w3c.dom.Document
    */
+  @Override
   public final Text createTextNode(String data)
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -668,6 +701,7 @@
    *
    * @see org.w3c.dom.Document
    */
+  @Override
   public final Comment createComment(String data)
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -682,6 +716,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Document
    */
+  @Override
   public final CDATASection createCDATASection(String data)
     throws DOMException
   {
@@ -698,8 +733,9 @@
    * @throws DOMException
    * @see org.w3c.dom.Document
    */
+  @Override
   public final ProcessingInstruction createProcessingInstruction(
-                                                                 String target, String data) throws DOMException
+                                String target, String data) throws DOMException
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   }
@@ -713,6 +749,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Document
    */
+  @Override
   public final Attr createAttribute(String name) throws DOMException
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -727,6 +764,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Document
    */
+  @Override
   public final EntityReference createEntityReference(String name)
     throws DOMException
   {
@@ -739,6 +777,7 @@
    *
    * @see org.w3c.dom.Document
    */
+  @Override
   public final NodeList getElementsByTagName(String tagname)
   {
        Vector listVector = new Vector();
@@ -819,6 +858,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Document as of DOM Level 2 -- DTMNodeProxy is read-only
    */
+  @Override
   public final Node importNode(Node importedNode, boolean deep)
     throws DOMException
   {
@@ -835,8 +875,9 @@
    * @throws DOMException
    * @see org.w3c.dom.Document as of DOM Level 2
    */
+  @Override
   public final Element createElementNS(
-                                       String namespaceURI, String qualifiedName) throws DOMException
+                 String namespaceURI, String qualifiedName) throws DOMException
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   }
@@ -851,8 +892,9 @@
    * @throws DOMException
    * @see org.w3c.dom.Document as of DOM Level 2
    */
+  @Override
   public final Attr createAttributeNS(
-                                      String namespaceURI, String qualifiedName) throws DOMException
+                  String namespaceURI, String qualifiedName) throws DOMException
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   }
@@ -865,6 +907,7 @@
    *
    * @see org.w3c.dom.Document as of DOM Level 2
    */
+  @Override
   public final NodeList getElementsByTagNameNS(String namespaceURI,
                                                String localName)
   {
@@ -952,6 +995,7 @@
    *
    * @see org.w3c.dom.Document as of DOM Level 2
    */
+  @Override
   public final Element getElementById(String elementId)
   {
        return (Element) dtm.getNode(dtm.getElementById(elementId));
@@ -966,6 +1010,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Text
    */
+  @Override
   public final Text splitText(int offset) throws DOMException
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -978,6 +1023,7 @@
    * @throws DOMException
    * @see org.w3c.dom.CharacterData
    */
+  @Override
   public final String getData() throws DOMException
   {
     return dtm.getNodeValue(node);
@@ -990,6 +1036,7 @@
    * @throws DOMException
    * @see org.w3c.dom.CharacterData
    */
+  @Override
   public final void setData(String data) throws DOMException
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1000,6 +1047,7 @@
    *
    * @see org.w3c.dom.CharacterData
    */
+  @Override
   public final int getLength()
   {
     // %OPT% This should do something smarter?
@@ -1016,6 +1064,7 @@
    * @throws DOMException
    * @see org.w3c.dom.CharacterData
    */
+  @Override
   public final String substringData(int offset, int count) throws DOMException
   {
     return getData().substring(offset,offset+count);
@@ -1028,6 +1077,7 @@
    * @throws DOMException
    * @see org.w3c.dom.CharacterData
    */
+  @Override
   public final void appendData(String arg) throws DOMException
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1041,6 +1091,7 @@
    * @throws DOMException
    * @see org.w3c.dom.CharacterData
    */
+  @Override
   public final void insertData(int offset, String arg) throws DOMException
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1054,6 +1105,7 @@
    * @throws DOMException
    * @see org.w3c.dom.CharacterData
    */
+  @Override
   public final void deleteData(int offset, int count) throws DOMException
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1068,6 +1120,7 @@
    * @throws DOMException
    * @see org.w3c.dom.CharacterData
    */
+  @Override
   public final void replaceData(int offset, int count, String arg)
     throws DOMException
   {
@@ -1079,6 +1132,7 @@
    *
    * @see org.w3c.dom.Element
    */
+  @Override
   public final String getTagName()
   {
     return dtm.getNodeName(node);
@@ -1091,12 +1145,13 @@
    *
    * @see org.w3c.dom.Element
    */
+  @Override
   public final String getAttribute(String name)
   {
-
     DTMNamedNodeMap  map = new DTMNamedNodeMap(dtm, node);
-    Node node = map.getNamedItem(name);
-    return (null == node) ? EMPTYSTRING : node.getNodeValue();  }
+    Node n = map.getNamedItem(name);
+    return (null == n) ? EMPTYSTRING : n.getNodeValue();
+  }
 
   /**
    *
@@ -1106,6 +1161,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Element
    */
+  @Override
   public final void setAttribute(String name, String value)
     throws DOMException
   {
@@ -1119,6 +1175,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Element
    */
+  @Override
   public final void removeAttribute(String name) throws DOMException
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1131,9 +1188,9 @@
    *
    * @see org.w3c.dom.Element
    */
+  @Override
   public final Attr getAttributeNode(String name)
   {
-
     DTMNamedNodeMap  map = new DTMNamedNodeMap(dtm, node);
     return (Attr)map.getNamedItem(name);
   }
@@ -1147,6 +1204,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Element
    */
+  @Override
   public final Attr setAttributeNode(Attr newAttr) throws DOMException
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1161,6 +1219,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Element
    */
+  @Override
   public final Attr removeAttributeNode(Attr oldAttr) throws DOMException
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1171,12 +1230,14 @@
    *
    *
    */
+  @Override
   public boolean hasAttributes()
   {
     return DTM.NULL != dtm.getFirstAttribute(node);
   }
 
   /** @see org.w3c.dom.Element */
+  @Override
   public final void normalize()
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1190,6 +1251,7 @@
    *
    * @see org.w3c.dom.Element
    */
+  @Override
   public final String getAttributeNS(String namespaceURI, String localName)
   {
     Node retNode = null;
@@ -1208,6 +1270,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Element
    */
+  @Override
   public final void setAttributeNS(
                                    String namespaceURI, String qualifiedName, String value)
     throws DOMException
@@ -1223,6 +1286,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Element
    */
+  @Override
   public final void removeAttributeNS(String namespaceURI, String localName)
     throws DOMException
   {
@@ -1237,6 +1301,7 @@
    *
    * @see org.w3c.dom.Element
    */
+  @Override
   public final Attr getAttributeNodeNS(String namespaceURI, String localName)
   {
        Attr retAttr = null;
@@ -1256,6 +1321,7 @@
    * @throws DOMException
    * @see org.w3c.dom.Element
    */
+  @Override
   public final Attr setAttributeNodeNS(Attr newAttr) throws DOMException
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1266,6 +1332,7 @@
    *
    * @see org.w3c.dom.Attr
    */
+  @Override
   public final String getName()
   {
     return dtm.getNodeName(node);
@@ -1276,6 +1343,7 @@
    *
    * @see org.w3c.dom.Attr
    */
+  @Override
   public final boolean getSpecified()
   {
     // We really don't know which attributes might have come from the
@@ -1290,6 +1358,7 @@
    *
    * @see org.w3c.dom.Attr
    */
+  @Override
   public final String getValue()
   {
     return dtm.getNodeValue(node);
@@ -1300,6 +1369,7 @@
    * @param value
    * @see org.w3c.dom.Attr
    */
+  @Override
   public final void setValue(String value)
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1311,6 +1381,7 @@
    *
    * @see org.w3c.dom.Attr as of DOM Level 2
    */
+  @Override
   public final Element getOwnerElement()
   {
     if (getNodeType() != Node.ATTRIBUTE_NODE)
@@ -1331,9 +1402,9 @@
    *
    * @throws DOMException
    */
+  @Override
   public Node adoptNode(Node source) throws DOMException
   {
-
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   }
 
@@ -1348,9 +1419,9 @@
    *
    * NEEDSDOC ($objectName$) @return
    */
+  @Override
   public String getInputEncoding()
   {
-
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   }
 
@@ -1383,7 +1454,6 @@
    */
   public boolean getStandalone()
   {
-
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   }
 
@@ -1418,9 +1488,9 @@
    *
    * NEEDSDOC ($objectName$) @return
    */
+  @Override
   public boolean getStrictErrorChecking()
   {
-
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   }
 
@@ -1439,6 +1509,7 @@
    *
    * NEEDSDOC @param strictErrorChecking
    */
+  @Override
   public void setStrictErrorChecking(boolean strictErrorChecking)
   {
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
@@ -1457,7 +1528,6 @@
    */
   public String getVersion()
   {
-
     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   }
 
@@ -1482,10 +1552,12 @@
    */
   static class DTMNodeProxyImplementation implements DOMImplementation
   {
+    @Override
     public DocumentType createDocumentType(String qualifiedName,String publicId, String systemId)
     {
       throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
     }
+    @Override
     public Document createDocument(String namespaceURI,String qualfiedName,DocumentType doctype)
     {
       // Could create a DTM... but why, when it'd have to be permanantly empty?
@@ -1500,6 +1572,7 @@
      * methods we can't support. I'm not sure which would be more useful
      * to the caller.
      */
+    @Override
     public boolean hasFeature(String feature,String version)
     {
       if( ("CORE".equals(feature.toUpperCase()) || "XML".equals(feature.toUpperCase()))
@@ -1530,6 +1603,7 @@
      *   childNodes, etc.
      * @since DOM Level 3
      */
+    @Override
     public Object getFeature(String feature, String version) {
         // we don't have any alternate node, either this node does the job
         // or we don't have anything that does
@@ -1542,6 +1616,7 @@
 
 //RAMESH : Pending proper implementation of DOM Level 3
 
+    @Override
     public Object setUserData(String key,
                               Object data,
                               UserDataHandler handler) {
@@ -1557,6 +1632,7 @@
      *   on this node, or <code>null</code> if there was none.
      * @since DOM Level 3
      */
+    @Override
     public Object getUserData(String key) {
         return getOwnerDocument().getUserData( key);
     }
@@ -1581,6 +1657,7 @@
      *   childNodes, etc.
      * @since DOM Level 3
      */
+    @Override
     public Object getFeature(String feature, String version) {
         // we don't have any alternate node, either this node does the job
         // or we don't have anything that does
@@ -1629,6 +1706,7 @@
      *   <code>true</code> otherwise <code>false</code>.
      * @since DOM Level 3
      */
+    @Override
     public boolean isEqualNode(Node arg) {
         if (arg == this) {
             return true;
@@ -1705,6 +1783,7 @@
      * @return th URI for the namespace
      * @since DOM Level 3
      */
+    @Override
     public String lookupNamespaceURI(String specifiedPrefix) {
         short type = this.getNodeType();
         switch (type) {
@@ -1797,6 +1876,7 @@
      *   is the default namespace, <code>false</code> otherwise.
      * @since DOM Level 3
      */
+    @Override
     public boolean isDefaultNamespace(String namespaceURI){
        /*
         // REVISIT: remove casts when DOM L3 becomes REC.
@@ -1871,6 +1951,7 @@
      * @param namespaceURI
      * @return the prefix for the namespace
      */
+    @Override
     public String lookupPrefix(String namespaceURI){
 
         // REVISIT: When Namespaces 1.1 comes out this may not be true
@@ -1932,6 +2013,7 @@
      *   <code>false</code> otherwise.
      * @since DOM Level 3
      */
+    @Override
     public boolean isSameNode(Node other) {
         // we do not use any wrapper so the answer is obvious
         return this == other;
@@ -1980,8 +2062,9 @@
      *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than
      *   fit in a <code>DOMString</code> variable on the implementation
      *   platform.
-       * @since DOM Level 3
+     * @since DOM Level 3
      */
+    @Override
     public void setTextContent(String textContent)
         throws DOMException {
         setNodeValue(textContent);
@@ -2031,6 +2114,7 @@
      *   platform.
      * @since DOM Level 3
      */
+    @Override
     public String getTextContent() throws DOMException {
         return getNodeValue();  // overriden in some subclasses
     }
@@ -2043,6 +2127,7 @@
      *   node.
      * @since DOM Level 3
      */
+    @Override
     public short compareDocumentPosition(Node other) throws DOMException {
         return 0;
     }
@@ -2071,14 +2156,16 @@
      * Yes. (F2F 26 Sep 2001)
      * @since DOM Level 3
      */
+    @Override
     public String getBaseURI() {
         return null;
     }
 
-        /**
+    /**
      * DOM Level 3
      * Renaming node
      */
+    @Override
     public Node renameNode(Node n,
                            String namespaceURI,
                            String name)
@@ -2091,14 +2178,16 @@
      *  DOM Level 3
      *  Normalize document.
      */
+    @Override
     public void normalizeDocument(){
 
     }
     /**
-     *  The configuration used when <code>Document.normalizeDocument</code> is
+     * The configuration used when <code>Document.normalizeDocument</code> is
      * invoked.
      * @since DOM Level 3
      */
+    @Override
     public DOMConfiguration getDomConfig(){
        return null;
     }
@@ -2110,8 +2199,8 @@
     /**
      * DOM Level 3
      */
+    @Override
     public void setDocumentURI(String documentURI){
-
         fDocumentURI= documentURI;
     }
 
@@ -2123,6 +2212,7 @@
      * over this attribute.
      * @since DOM Level 3
      */
+    @Override
     public String getDocumentURI(){
         return fDocumentURI;
     }
@@ -2154,9 +2244,10 @@
         actualEncoding = value;
     }
 
-     /**
+   /**
     * DOM Level 3
     */
+    @Override
     public Text replaceWholeText(String content)
                                  throws DOMException{
 /*
@@ -2210,6 +2301,7 @@
      * nodes to this node, concatenated in document order.
      * @since DOM Level 3
      */
+    @Override
     public String getWholeText(){
 
 /*
@@ -2235,13 +2327,11 @@
      * Returns whether this text node contains whitespace in element content,
      * often abusively called "ignorable whitespace".
      */
+    @Override
     public boolean isElementContentWhitespace(){
         return false;
     }
 
-
-
-
      /**
      * NON-DOM: set the type of this attribute to be ID type.
      *
@@ -2254,6 +2344,7 @@
      /**
      * DOM Level 3: register the given attribute node as an ID attribute
      */
+    @Override
     public void setIdAttribute(String name, boolean makeId) {
         //PENDING
     }
@@ -2262,6 +2353,7 @@
     /**
      * DOM Level 3: register the given attribute node as an ID attribute
      */
+    @Override
     public void setIdAttributeNode(Attr at, boolean makeId) {
         //PENDING
     }
@@ -2269,6 +2361,7 @@
     /**
      * DOM Level 3: register the given attribute node as an ID attribute
      */
+    @Override
     public void setIdAttributeNS(String namespaceURI, String localName,
                                     boolean makeId) {
         //PENDING
@@ -2277,16 +2370,19 @@
          * Method getSchemaTypeInfo.
          * @return TypeInfo
          */
+    @Override
     public TypeInfo getSchemaTypeInfo(){
       return null; //PENDING
     }
 
+    @Override
     public boolean isId() {
         return false; //PENDING
     }
 
 
     private String xmlEncoding;
+    @Override
     public String getXmlEncoding( ) {
         return xmlEncoding;
     }
@@ -2295,23 +2391,25 @@
     }
 
     private boolean xmlStandalone;
+    @Override
     public boolean getXmlStandalone() {
         return xmlStandalone;
     }
 
+    @Override
     public void setXmlStandalone(boolean xmlStandalone) throws DOMException {
         this.xmlStandalone = xmlStandalone;
     }
 
     private String xmlVersion;
+    @Override
     public String getXmlVersion() {
         return xmlVersion;
     }
 
+    @Override
     public void setXmlVersion(String xmlVersion) throws DOMException {
         this.xmlVersion = xmlVersion;
     }
 
-
-
 }
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/serializer/Encodings.java b/jaxp/src/com/sun/org/apache/xml/internal/serializer/Encodings.java
index 3584569..d4d95ff 100644
--- a/jaxp/src/com/sun/org/apache/xml/internal/serializer/Encodings.java
+++ b/jaxp/src/com/sun/org/apache/xml/internal/serializer/Encodings.java
@@ -33,6 +33,14 @@
 import java.util.HashMap;
 import java.util.Properties;
 import java.util.StringTokenizer;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Map.Entry;
 
 import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
 
@@ -79,36 +87,17 @@
         throws UnsupportedEncodingException
     {
 
-        for (int i = 0; i < _encodings.length; ++i)
-        {
-            if (_encodings[i].name.equalsIgnoreCase(encoding))
-            {
-                try
-                {
-                    return new BufferedWriter(new OutputStreamWriter(
-                        output,
-                        _encodings[i].javaName));
-                }
-                catch (java.lang.IllegalArgumentException iae) // java 1.1.8
-                {
-                    // keep trying
-                }
-                catch (UnsupportedEncodingException usee)
-                {
-
-                    // keep trying
-                }
+        final EncodingInfo ei = _encodingInfos.findEncoding(toUpperCaseFast(encoding));
+        if (ei != null) {
+            try {
+                return new BufferedWriter(new OutputStreamWriter(
+                        output, ei.javaName));
+            } catch (UnsupportedEncodingException usee) {
+                // keep trying
             }
         }
 
-        try
-        {
-            return new BufferedWriter(new OutputStreamWriter(output, encoding));
-        }
-        catch (java.lang.IllegalArgumentException iae) // java 1.1.8
-        {
-            throw new UnsupportedEncodingException(encoding);
-        }
+        return new BufferedWriter(new OutputStreamWriter(output, encoding));
     }
 
 
@@ -141,12 +130,24 @@
         EncodingInfo ei;
 
         String normalizedEncoding = toUpperCaseFast(encoding);
-        ei = (EncodingInfo) _encodingTableKeyJava.get(normalizedEncoding);
-        if (ei == null)
-            ei = (EncodingInfo) _encodingTableKeyMime.get(normalizedEncoding);
+        ei = _encodingInfos.findEncoding(normalizedEncoding);
         if (ei == null) {
             // We shouldn't have to do this, but just in case.
-            ei = new EncodingInfo(null,null);
+            try {
+                // This may happen if the caller tries to use
+                // an encoding that wasn't registered in the
+                // (java name)->(preferred mime name) mapping file.
+                // In that case we attempt to load the charset for the
+                // given encoding, and if that succeeds - we create a new
+                // EncodingInfo instance - assuming the canonical name
+                // of the charset can be used as the mime name.
+                final Charset c = Charset.forName(encoding);
+                final String name = c.name();
+                ei = new EncodingInfo(name, name);
+                _encodingInfos.putEncoding(normalizedEncoding, ei);
+            } catch (IllegalCharsetNameException | UnsupportedCharsetException x) {
+                ei = new EncodingInfo(null,null);
+            }
         }
 
         return ei;
@@ -269,8 +270,8 @@
      */
     private static String convertJava2MimeEncoding(String encoding)
     {
-        EncodingInfo enc =
-            (EncodingInfo) _encodingTableKeyJava.get(encoding.toUpperCase());
+        final EncodingInfo enc =
+             _encodingInfos.getEncodingFromJavaKey(toUpperCaseFast(encoding));
         if (null != enc)
             return enc.name;
         return encoding;
@@ -285,38 +286,37 @@
      */
     public static String convertMime2JavaEncoding(String encoding)
     {
-
-        for (int i = 0; i < _encodings.length; ++i)
-        {
-            if (_encodings[i].name.equalsIgnoreCase(encoding))
-            {
-                return _encodings[i].javaName;
-            }
-        }
-
-        return encoding;
+        final EncodingInfo info = _encodingInfos.findEncoding(toUpperCaseFast(encoding));
+        return info != null ? info.javaName : encoding;
     }
 
-    /**
-     * Load a list of all the supported encodings.
-     *
-     * System property "encodings" formatted using URL syntax may define an
-     * external encodings list. Thanks to Sergey Ushakov for the code
-     * contribution!
-     */
-    private static EncodingInfo[] loadEncodingInfo()
-    {
-        try
-        {
+    // Using an inner static class here prevent initialization races
+    // where the hash maps could be used before they were populated.
+    //
+    private final static class EncodingInfos {
+        // These maps are final and not modified after initialization.
+        private final Map<String, EncodingInfo> _encodingTableKeyJava = new HashMap<>();
+        private final Map<String, EncodingInfo> _encodingTableKeyMime = new HashMap<>();
+        // This map will be added to after initialization: make sure it's
+        // thread-safe. This map should not be used frequently - only in cases
+        // where the mapping requested was not declared in the Encodings.properties
+        // file.
+        private final Map<String, EncodingInfo> _encodingDynamicTable =
+                Collections.synchronizedMap(new HashMap<String, EncodingInfo>());
+
+        private EncodingInfos() {
+            loadEncodingInfo();
+        }
+
+        // Opens the file/resource containing java charset name -> preferred mime
+        // name mapping and returns it as an InputStream.
+        private InputStream openEncodingsFileStream() throws MalformedURLException, IOException {
             String urlString = null;
             InputStream is = null;
 
-            try
-            {
+            try {
                 urlString = SecuritySupport.getSystemProperty(ENCODINGS_PROP, "");
-            }
-            catch (SecurityException e)
-            {
+            } catch (SecurityException e) {
             }
 
             if (urlString != null && urlString.length() > 0) {
@@ -327,84 +327,188 @@
             if (is == null) {
                 is = SecuritySupport.getResourceAsStream(ENCODINGS_FILE);
             }
+            return is;
+        }
 
+        // Loads the Properties resource containing the mapping:
+        //    java charset name -> preferred mime name
+        // and returns it.
+        private Properties loadProperties() throws MalformedURLException, IOException {
             Properties props = new Properties();
-            if (is != null) {
-                props.load(is);
-                is.close();
-            } else {
-                // Seems to be no real need to force failure here, let the
-                // system do its best... The issue is not really very critical,
-                // and the output will be in any case _correct_ though maybe not
-                // always human-friendly... :)
-                // But maybe report/log the resource problem?
-                // Any standard ways to report/log errors (in static context)?
-            }
-
-            int totalEntries = props.size();
-            int totalMimeNames = 0;
-            Enumeration keys = props.keys();
-            for (int i = 0; i < totalEntries; ++i)
-            {
-                String javaName = (String) keys.nextElement();
-                String val = props.getProperty(javaName);
-                totalMimeNames++;
-                int pos = val.indexOf(' ');
-                for (int j = 0; j < pos; ++j)
-                    if (val.charAt(j) == ',')
-                        totalMimeNames++;
-            }
-            EncodingInfo[] ret = new EncodingInfo[totalMimeNames];
-            int j = 0;
-            keys = props.keys();
-            for (int i = 0; i < totalEntries; ++i)
-            {
-                String javaName = (String) keys.nextElement();
-                String val = props.getProperty(javaName);
-                int pos = val.indexOf(' ');
-                String mimeName;
-                //int lastPrintable;
-                if (pos < 0)
-                {
-                    // Maybe report/log this problem?
-                    //  "Last printable character not defined for encoding " +
-                    //  mimeName + " (" + val + ")" ...
-                    mimeName = val;
-                    //lastPrintable = 0x00FF;
+            try (InputStream is = openEncodingsFileStream()) {
+                if (is != null) {
+                    props.load(is);
+                } else {
+                    // Seems to be no real need to force failure here, let the
+                    // system do its best... The issue is not really very critical,
+                    // and the output will be in any case _correct_ though maybe not
+                    // always human-friendly... :)
+                    // But maybe report/log the resource problem?
+                    // Any standard ways to report/log errors (in static context)?
                 }
-                else
-                {
-                    //lastPrintable =
-                    //    Integer.decode(val.substring(pos).trim()).intValue();
-                    StringTokenizer st =
-                        new StringTokenizer(val.substring(0, pos), ",");
-                    for (boolean first = true;
-                        st.hasMoreTokens();
-                        first = false)
-                    {
-                        mimeName = st.nextToken();
-                        ret[j] =
-                            new EncodingInfo(mimeName, javaName);
-                        _encodingTableKeyMime.put(
-                            mimeName.toUpperCase(),
-                            ret[j]);
-                        if (first)
-                            _encodingTableKeyJava.put(
-                                javaName.toUpperCase(),
-                                ret[j]);
-                        j++;
+            }
+            return props;
+        }
+
+        // Parses the mime list associated to a java charset name.
+        // The first mime name in the list is supposed to be the preferred
+        // mime name.
+        private String[] parseMimeTypes(String val) {
+            int pos = val.indexOf(' ');
+            //int lastPrintable;
+            if (pos < 0) {
+                // Maybe report/log this problem?
+                //  "Last printable character not defined for encoding " +
+                //  mimeName + " (" + val + ")" ...
+                return new String[] { val };
+                //lastPrintable = 0x00FF;
+            }
+            //lastPrintable =
+            //    Integer.decode(val.substring(pos).trim()).intValue();
+            StringTokenizer st =
+                    new StringTokenizer(val.substring(0, pos), ",");
+            String[] values = new String[st.countTokens()];
+            for (int i=0; st.hasMoreTokens(); i++) {
+                values[i] = st.nextToken();
+            }
+            return values;
+        }
+
+        // This method here attempts to find the canonical charset name for the
+        // the given name - which is supposed to be either a java name or a mime
+        // name.
+        // For that, it attempts to load the charset using the given name, and
+        // then returns the charset's canonical name.
+        // If the charset could not be loaded from the given name,
+        // the method returns null.
+        private String findCharsetNameFor(String name) {
+            try {
+                return Charset.forName(name).name();
+            } catch (Exception x) {
+                return null;
+            }
+        }
+
+        // This method here attempts to find the canonical charset name for the
+        // the set javaName+mimeNames - which are supposed to all refer to the
+        // same charset.
+        // For that it attempts to load the charset using the javaName, and if
+        // not found, attempts again using each of the mime names in turn.
+        // If the charset could be loaded from the javaName, then the javaName
+        // itself is returned as charset name. Otherwise, each of the mime names
+        // is tried in turn, until a charset can be loaded from one of the names,
+        // and the loaded charset's canonical name is returned.
+        // If no charset can be loaded from either the javaName or one of the
+        // mime names, then null is returned.
+        //
+        // Note that the returned name is the 'java' name that will be used in
+        // instances of EncodingInfo.
+        // This is important because EncodingInfo uses that 'java name' later on
+        // in calls to String.getBytes(javaName).
+        // As it happens, sometimes only one element of the set mime names/javaName
+        // is known by Charset: sometimes only one of the mime names is known,
+        // sometime only the javaName is known, sometimes all are known.
+        //
+        // By using this method here, we fix the problem where one of the mime
+        // names is known but the javaName is unknown, by associating the charset
+        // loaded from one of the mime names with the unrecognized javaName.
+        //
+        // When none of the mime names or javaName are known - there's not much we can
+        // do... It can mean that this encoding is not supported for this
+        // OS. If such a charset is ever use it will result in having all characters
+        // escaped.
+        //
+        private String findCharsetNameFor(String javaName, String[] mimes) {
+            String cs = findCharsetNameFor(javaName);
+            if (cs != null) return javaName;
+            for (String m : mimes) {
+                cs = findCharsetNameFor(m);
+                if (cs != null) break;
+            }
+            return cs;
+        }
+
+        /**
+         * Loads a list of all the supported encodings.
+         *
+         * System property "encodings" formatted using URL syntax may define an
+         * external encodings list. Thanks to Sergey Ushakov for the code
+         * contribution!
+         */
+        private void loadEncodingInfo() {
+            try {
+                // load (java name)->(preferred mime name) mapping.
+                final Properties props = loadProperties();
+
+                // create instances of EncodingInfo from the loaded mapping
+                Enumeration keys = props.keys();
+                Map<String, EncodingInfo> canonicals = new HashMap<>();
+                while (keys.hasMoreElements()) {
+                    final String javaName = (String) keys.nextElement();
+                    final String[] mimes = parseMimeTypes(props.getProperty(javaName));
+
+                    final String charsetName = findCharsetNameFor(javaName, mimes);
+                    if (charsetName != null) {
+                        final String kj = toUpperCaseFast(javaName);
+                        final String kc = toUpperCaseFast(charsetName);
+                        for (int i = 0; i < mimes.length; ++i) {
+                            final String mimeName = mimes[i];
+                            final String km = toUpperCaseFast(mimeName);
+                            EncodingInfo info = new EncodingInfo(mimeName, charsetName);
+                            _encodingTableKeyMime.put(km, info);
+                            if (!canonicals.containsKey(kc)) {
+                                // canonicals will map the charset name to
+                                //   the info containing the prefered mime name
+                                //   (the preferred mime name is the first mime
+                                //   name in the list).
+                                canonicals.put(kc, info);
+                                _encodingTableKeyJava.put(kc, info);
+                            }
+                            _encodingTableKeyJava.put(kj, info);
+                        }
+                    } else {
+                        // None of the java or mime names on the line were
+                        // recognized => this charset is not supported?
                     }
                 }
+
+                // Fix up the _encodingTableKeyJava so that the info mapped to
+                // the java name contains the preferred mime name.
+                // (a given java name can correspond to several mime name,
+                //  but we want the _encodingTableKeyJava to point to the
+                //  preferred mime name).
+                for (Entry<String, EncodingInfo> e : _encodingTableKeyJava.entrySet()) {
+                    e.setValue(canonicals.get(toUpperCaseFast(e.getValue().javaName)));
+                }
+
+            } catch (java.net.MalformedURLException mue) {
+                throw new com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException(mue);
+            } catch (java.io.IOException ioe) {
+                throw new com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException(ioe);
             }
-            return ret;
         }
-        catch (java.net.MalformedURLException mue)
-        {
-            throw new com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException(mue);
+
+        EncodingInfo findEncoding(String normalizedEncoding) {
+            EncodingInfo info = _encodingTableKeyJava.get(normalizedEncoding);
+            if (info == null) {
+                info = _encodingTableKeyMime.get(normalizedEncoding);
+            }
+            if (info == null) {
+                info = _encodingDynamicTable.get(normalizedEncoding);
+            }
+            return info;
         }
-        catch (java.io.IOException ioe)
-        {
-            throw new com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException(ioe);
+
+        EncodingInfo getEncodingFromMimeKey(String normalizedMimeName) {
+            return _encodingTableKeyMime.get(normalizedMimeName);
+        }
+
+        EncodingInfo getEncodingFromJavaKey(String normalizedJavaName) {
+            return _encodingTableKeyJava.get(normalizedJavaName);
+        }
+
+        void putEncoding(String key, EncodingInfo info) {
+            _encodingDynamicTable.put(key, info);
         }
     }
 
@@ -457,7 +561,6 @@
         return codePoint;
     }
 
-    private static final HashMap _encodingTableKeyJava = new HashMap();
-    private static final HashMap _encodingTableKeyMime = new HashMap();
-    private static final EncodingInfo[] _encodings = loadEncodingInfo();
+    private final static EncodingInfos _encodingInfos = new EncodingInfos();
+
 }
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/serializer/utils/URI.java b/jaxp/src/com/sun/org/apache/xml/internal/serializer/utils/URI.java
index 8af2fd8..4d5375a 100644
--- a/jaxp/src/com/sun/org/apache/xml/internal/serializer/utils/URI.java
+++ b/jaxp/src/com/sun/org/apache/xml/internal/serializer/utils/URI.java
@@ -23,7 +23,7 @@
 package com.sun.org.apache.xml.internal.serializer.utils;
 
 import java.io.IOException;
-import java.io.Serializable;
+import java.util.Objects;
 
 
 /**
@@ -863,7 +863,7 @@
   public String getSchemeSpecificPart()
   {
 
-    StringBuffer schemespec = new StringBuffer();
+    final StringBuilder schemespec = new StringBuilder();
 
     if (m_userinfo != null || m_host != null || m_port != -1)
     {
@@ -955,7 +955,7 @@
                         boolean p_includeFragment)
   {
 
-    StringBuffer pathString = new StringBuffer(m_path);
+    final StringBuilder pathString = new StringBuilder(m_path);
 
     if (p_includeQueryString && m_queryString != null)
     {
@@ -1321,6 +1321,7 @@
    * @return true if p_test is a URI with all values equal to this
    *         URI, false otherwise
    */
+  @Override
   public boolean equals(Object p_test)
   {
 
@@ -1343,15 +1344,29 @@
     return false;
   }
 
+  @Override
+  public int hashCode() {
+    int hash = 5;
+    hash = 41 * hash + Objects.hashCode(this.m_scheme);
+    hash = 41 * hash + Objects.hashCode(this.m_userinfo);
+    hash = 41 * hash + Objects.hashCode(this.m_host);
+    hash = 41 * hash + this.m_port;
+    hash = 41 * hash + Objects.hashCode(this.m_path);
+    hash = 41 * hash + Objects.hashCode(this.m_queryString);
+    hash = 41 * hash + Objects.hashCode(this.m_fragment);
+    return hash;
+  }
+
   /**
    * Get the URI as a string specification. See RFC 2396 Section 5.2.
    *
    * @return the URI string specification
    */
+  @Override
   public String toString()
   {
 
-    StringBuffer uriSpecString = new StringBuffer();
+    final StringBuilder uriSpecString = new StringBuilder();
 
     if (m_scheme != null)
     {
@@ -1543,7 +1558,7 @@
    *
    *
    * @param p_char the character to check
-   * @return true if the char is betweeen '0' and '9', 'a' and 'f'
+   * @return true if the char is between '0' and '9', 'a' and 'f'
    *         or 'A' and 'F', false otherwise
    */
   private static boolean isHex(char p_char)
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/utils/URI.java b/jaxp/src/com/sun/org/apache/xml/internal/utils/URI.java
index b2606a7..f9e67ab 100644
--- a/jaxp/src/com/sun/org/apache/xml/internal/utils/URI.java
+++ b/jaxp/src/com/sun/org/apache/xml/internal/utils/URI.java
@@ -27,6 +27,7 @@
 
 import com.sun.org.apache.xml.internal.res.XMLErrorResources;
 import com.sun.org.apache.xml.internal.res.XMLMessages;
+import java.util.Objects;
 
 /**
  * A class to represent a Uniform Resource Identifier (URI). This class
@@ -883,7 +884,7 @@
   public String getSchemeSpecificPart()
   {
 
-    StringBuffer schemespec = new StringBuffer();
+    final StringBuilder schemespec = new StringBuilder();
 
     if (m_userinfo != null || m_host != null || m_port != -1)
     {
@@ -975,7 +976,7 @@
                         boolean p_includeFragment)
   {
 
-    StringBuffer pathString = new StringBuffer(m_path);
+    final StringBuilder pathString = new StringBuilder(m_path);
 
     if (p_includeQueryString && m_queryString != null)
     {
@@ -1341,6 +1342,7 @@
    * @return true if p_test is a URI with all values equal to this
    *         URI, false otherwise
    */
+  @Override
   public boolean equals(Object p_test)
   {
 
@@ -1363,15 +1365,29 @@
     return false;
   }
 
+  @Override
+  public int hashCode() {
+    int hash = 7;
+    hash = 59 * hash + Objects.hashCode(this.m_scheme);
+    hash = 59 * hash + Objects.hashCode(this.m_userinfo);
+    hash = 59 * hash + Objects.hashCode(this.m_host);
+    hash = 59 * hash + this.m_port;
+    hash = 59 * hash + Objects.hashCode(this.m_path);
+    hash = 59 * hash + Objects.hashCode(this.m_queryString);
+    hash = 59 * hash + Objects.hashCode(this.m_fragment);
+    return hash;
+  }
+
   /**
    * Get the URI as a string specification. See RFC 2396 Section 5.2.
    *
    * @return the URI string specification
    */
+  @Override
   public String toString()
   {
 
-    StringBuffer uriSpecString = new StringBuffer();
+    final StringBuilder uriSpecString = new StringBuilder();
 
     if (m_scheme != null)
     {
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java
index 20ed918..8f79f86 100644
--- a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java
+++ b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java
@@ -22,17 +22,17 @@
  */
 package com.sun.org.apache.xml.internal.utils;
 
-import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
+import com.sun.org.apache.xalan.internal.XalanConstants;
 import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
+import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
 import java.util.HashMap;
-
+import javax.xml.XMLConstants;
 import javax.xml.parsers.FactoryConfigurationError;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParserFactory;
-
+import org.xml.sax.SAXException;
 import org.xml.sax.XMLReader;
 import org.xml.sax.helpers.XMLReaderFactory;
-import org.xml.sax.SAXException;
 
 /**
  * Creates XMLReader objects and caches them for re-use.
@@ -63,6 +63,11 @@
     private HashMap m_inUse;
 
     private boolean m_useServicesMechanism = true;
+     /**
+     * protocols allowed for external DTD references in source file and/or stylesheet.
+     */
+    private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+
     /**
      * Hidden constructor
      */
@@ -131,6 +136,7 @@
                 try {
                     reader.setFeature(NAMESPACES_FEATURE, true);
                     reader.setFeature(NAMESPACE_PREFIXES_FEATURE, false);
+                    reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD);
                 } catch (SAXException se) {
                     // Try to carry on if we've got a parser that
                     // doesn't know about namespace prefixes.
@@ -181,4 +187,22 @@
         m_useServicesMechanism = flag;
     }
 
+    /**
+     * Get property value
+     */
+    public String getProperty(String name) {
+        if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
+            return _accessExternalDTD;
+        }
+        return null;
+    }
+
+    /**
+     * Set property.
+     */
+    public void setProperty(String name, String value) {
+        if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
+            _accessExternalDTD = (String)value;
+        }
+    }
 }
diff --git a/jaxp/src/com/sun/org/apache/xpath/internal/Arg.java b/jaxp/src/com/sun/org/apache/xpath/internal/Arg.java
index bc3d13a..311d07e 100644
--- a/jaxp/src/com/sun/org/apache/xpath/internal/Arg.java
+++ b/jaxp/src/com/sun/org/apache/xpath/internal/Arg.java
@@ -24,6 +24,7 @@
 
 import com.sun.org.apache.xml.internal.utils.QName;
 import com.sun.org.apache.xpath.internal.objects.XObject;
+import java.util.Objects;
 
 /**
  * This class holds an instance of an argument on
@@ -182,7 +183,7 @@
   {
 
     m_qname = new QName("");
-    ;  // so that string compares can be done.
+       // so that string compares can be done.
     m_val = null;
     m_expression = null;
     m_isVisible = true;
@@ -223,6 +224,11 @@
     m_expression = null;
   }
 
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(this.m_qname);
+    }
+
   /**
    * Equality function specialized for the variable name.  If the argument
    * is not a qname, it will deligate to the super class.
@@ -231,6 +237,7 @@
    * @return  <code>true</code> if this object is the same as the obj
    *          argument; <code>false</code> otherwise.
    */
+  @Override
   public boolean equals(Object obj)
   {
     if(obj instanceof QName)
diff --git a/jaxp/src/com/sun/xml/internal/stream/StaxXMLInputSource.java b/jaxp/src/com/sun/xml/internal/stream/StaxXMLInputSource.java
index 351693f..106f9f9 100644
--- a/jaxp/src/com/sun/xml/internal/stream/StaxXMLInputSource.java
+++ b/jaxp/src/com/sun/xml/internal/stream/StaxXMLInputSource.java
@@ -43,6 +43,9 @@
     XMLEventReader fEventReader ;
     XMLInputSource fInputSource ;
 
+    //indicate if the source is resolved by a resolver
+    boolean fHasResolver = false;
+
     /** Creates a new instance of StaxXMLInputSource */
     public StaxXMLInputSource(XMLStreamReader streamReader) {
         fStreamReader = streamReader ;
@@ -57,6 +60,12 @@
         fInputSource = inputSource ;
 
     }
+
+    public StaxXMLInputSource(XMLInputSource inputSource, boolean hasResolver){
+        fInputSource = inputSource ;
+        fHasResolver = hasResolver;
+    }
+
     public XMLStreamReader getXMLStreamReader(){
         return fStreamReader ;
     }
@@ -72,4 +81,8 @@
     public boolean hasXMLStreamOrXMLEventReader(){
         return (fStreamReader == null) && (fEventReader == null) ? false : true ;
     }
+
+    public boolean hasResolver() {
+        return fHasResolver;
+    }
 }
diff --git a/jaxp/src/javax/xml/XMLConstants.java b/jaxp/src/javax/xml/XMLConstants.java
index 2e570f1..b923a6c 100644
--- a/jaxp/src/javax/xml/XMLConstants.java
+++ b/jaxp/src/javax/xml/XMLConstants.java
@@ -73,7 +73,7 @@
      * <p>The official XML Namespace name URI.</p>
      *
      * <p>Defined by the XML specification to be
-     * "<code>http://www.w3.org/XML/1998/namespace</code>".</p>
+     * "{@code http://www.w3.org/XML/1998/namespace}".</p>
      *
      * @see <a
      * href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">
@@ -85,7 +85,7 @@
     /**
      * <p>The official XML Namespace prefix.</p>
      *
-     * <p>Defined by the XML specification to be "<code>xml</code>".</p>
+     * <p>Defined by the XML specification to be "{@code xml}".</p>
      *
      * @see <a
      * href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">
@@ -99,7 +99,7 @@
      * XMLConstants.XMLNS_ATTRIBUTE}, Namespace name URI.</p>
      *
      * <p>Defined by the XML specification to be
-     * "<code>http://www.w3.org/2000/xmlns/</code>".</p>
+     * "{@code http://www.w3.org/2000/xmlns/}".</p>
      *
      * @see <a
      * href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">
@@ -117,7 +117,7 @@
      *
      * <p>It is <strong><em>NOT</em></strong> valid to use as a
      * prefix.  Defined by the XML specification to be
-     * "<code>xmlns</code>".</p>
+     * "{@code xmlns}".</p>
      *
      * @see <a
      * href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">
@@ -128,7 +128,7 @@
     /**
      * <p>W3C XML Schema Namespace URI.</p>
      *
-     * <p>Defined to be "<code>http://www.w3.org/2001/XMLSchema</code>".
+     * <p>Defined to be "{@code http://www.w3.org/2001/XMLSchema}".
      *
      * @see <a href=
      *  "http://www.w3.org/TR/xmlschema-1/#Instance_Document_Constructions">
@@ -141,7 +141,7 @@
     /**
      * <p>W3C XML Schema Instance Namespace URI.</p>
      *
-     * <p>Defined to be "<code>http://www.w3.org/2001/XMLSchema-instance</code>".</p>
+     * <p>Defined to be "{@code http://www.w3.org/2001/XMLSchema-instance}".</p>
      *
      * @see <a href=
      *  "http://www.w3.org/TR/xmlschema-1/#Instance_Document_Constructions">
@@ -154,7 +154,7 @@
         /**
          * <p>W3C XPath Datatype Namespace URI.</p>
          *
-         * <p>Defined to be "<code>http://www.w3.org/2003/11/xpath-datatypes</code>".</p>
+         * <p>Defined to be "{@code http://www.w3.org/2003/11/xpath-datatypes}".</p>
          *
          * @see <a href="http://www.w3.org/TR/xpath-datamodel">XQuery 1.0 and XPath 2.0 Data Model</a>
          */
@@ -163,14 +163,14 @@
     /**
      * <p>XML Document Type Declaration Namespace URI as an arbitrary value.</p>
      *
-     * <p>Since not formally defined by any existing standard, arbitrarily define to be "<code>http://www.w3.org/TR/REC-xml</code>".
+     * <p>Since not formally defined by any existing standard, arbitrarily define to be "{@code http://www.w3.org/TR/REC-xml}".
      */
     public static final String XML_DTD_NS_URI = "http://www.w3.org/TR/REC-xml";
 
         /**
          * <p>RELAX NG Namespace URI.</p>
          *
-         * <p>Defined to be "<code>http://relaxng.org/ns/structure/1.0</code>".</p>
+         * <p>Defined to be "{@code http://relaxng.org/ns/structure/1.0}".</p>
          *
          * @see <a href="http://relaxng.org/spec-20011203.html">RELAX NG Specification</a>
          */
@@ -181,14 +181,212 @@
          *
          * <ul>
          *   <li>
-         *     <code>true</code> instructs the implementation to process XML securely.
+         *     {@code true} instructs the implementation to process XML securely.
          *     This may set limits on XML constructs to avoid conditions such as denial of service attacks.
          *   </li>
          *   <li>
-         *     <code>false</code> instructs the implementation to process XML acording the letter of the XML specifications
-         *     ingoring security issues such as limits on XML constructs to avoid conditions such as denial of service attacks.
+         *     {@code false} instructs the implementation to process XML in accordance with the XML specifications
+         *     ignoring security issues such as limits on XML constructs to avoid conditions such as denial of service attacks.
          *   </li>
          * </ul>
          */
         public static final String FEATURE_SECURE_PROCESSING = "http://javax.xml.XMLConstants/feature/secure-processing";
+
+
+        /**
+         * <p>Property: accessExternalDTD</p>
+         *
+         * <p>
+         * Restrict access to external DTDs and external Entity References to the protocols specified.
+         * If access is denied due to the restriction of this property, a runtime exception that
+         * is specific to the context is thrown. In the case of {@link javax.xml.parsers.SAXParser}
+         * for example, {@link org.xml.sax.SAXException} is thrown.
+         * </p>
+         *
+         * <p>
+         * <b>Value: </b> a list of protocols separated by comma. A protocol is the scheme portion of a
+         * {@link java.net.URI}, or in the case of the JAR protocol, "jar" plus the scheme portion
+         * separated by colon.
+         * A scheme is defined as:
+         *
+         * <blockquote>
+         * scheme = alpha *( alpha | digit | "+" | "-" | "." )<br>
+         * where alpha = a-z and A-Z.<br><br>
+         *
+         * And the JAR protocol:<br>
+         *
+         * jar[:scheme]<br><br>
+         *
+         * Protocols including the keyword "jar" are case-insensitive. Any whitespaces as defined by
+         * {@link java.lang.Character#isSpaceChar } in the value will be ignored.
+         * Examples of protocols are file, http, jar:file.
+         *
+         * </blockquote>
+         *</p>
+         *
+         *<p>
+         * <b>Default value:</b> The default value is implementation specific and therefore not specified.
+         * The following options are provided for consideration:
+         * <blockquote>
+         * <UL>
+         *     <LI>an empty string to deny all access to external references;</LI>
+         *     <LI>a specific protocol, such as file, to give permission to only the protocol;</LI>
+         *     <LI>the keyword "all" to grant  permission to all protocols.</LI>
+         *</UL><br>
+         *      When FEATURE_SECURE_PROCESSING is enabled,  it is recommended that implementations
+         *      restrict external connections by default, though this may cause problems for applications
+         *      that process XML/XSD/XSL with external references.
+         * </blockquote>
+         * </p>
+         *
+         * <p>
+         * <b>Granting all access:</b>  the keyword "all" grants permission to all protocols.
+         * </p>
+         * <p>
+         * <b>System Property:</b> The value of this property can be set or overridden by
+         * system property {@code javax.xml.accessExternalDTD}.
+         * </p>
+         *
+         * <p>
+         * <b>${JAVA_HOME}/lib/jaxp.properties:</b> This configuration file is in standard
+         * {@link java.util.Properties} format. If the file exists and the system property is specified,
+         * its value will be used to override the default of the property.
+         * </p>
+         *
+         * <p>
+         *
+         * </p>
+         * @since 1.7
+         */
+        public static final String ACCESS_EXTERNAL_DTD = "http://javax.xml.XMLConstants/property/accessExternalDTD";
+
+        /**
+         * <p>Property: accessExternalSchema</p>
+         *
+         * <p>
+         * Restrict access to the protocols specified for external reference set by the
+         * schemaLocation attribute, Import and Include element. If access is denied
+         * due to the restriction of this property, a runtime exception that is specific
+         * to the context is thrown. In the case of {@link javax.xml.validation.SchemaFactory}
+         * for example, org.xml.sax.SAXException is thrown.
+         * </p>
+         * <p>
+         * <b>Value:</b> a list of protocols separated by comma. A protocol is the scheme portion of a
+         * {@link java.net.URI}, or in the case of the JAR protocol, "jar" plus the scheme portion
+         * separated by colon.
+         * A scheme is defined as:
+         *
+         * <blockquote>
+         * scheme = alpha *( alpha | digit | "+" | "-" | "." )<br>
+         * where alpha = a-z and A-Z.<br><br>
+         *
+         * And the JAR protocol:<br>
+         *
+         * jar[:scheme]<br><br>
+         *
+         * Protocols including the keyword "jar" are case-insensitive. Any whitespaces as defined by
+         * {@link java.lang.Character#isSpaceChar } in the value will be ignored.
+         * Examples of protocols are file, http, jar:file.
+         *
+         * </blockquote>
+         *</p>
+         *
+         *<p>
+         * <b>Default value:</b> The default value is implementation specific and therefore not specified.
+         * The following options are provided for consideration:
+         * <blockquote>
+         * <UL>
+         *     <LI>an empty string to deny all access to external references;</LI>
+         *     <LI>a specific protocol, such as file, to give permission to only the protocol;</LI>
+         *     <LI>the keyword "all" to grant  permission to all protocols.</LI>
+         *</UL><br>
+         *      When FEATURE_SECURE_PROCESSING is enabled,  it is recommended that implementations
+         *      restrict external connections by default, though this may cause problems for applications
+         *      that process XML/XSD/XSL with external references.
+         * </blockquote>
+         * </p>
+         * <p>
+         * <b>Granting all access:</b>  the keyword "all" grants permission to all protocols.
+         * </p>
+         *
+         * <p>
+         * <b>System Property:</b> The value of this property can be set or overridden by
+         * system property {@code javax.xml.accessExternalSchema}
+         * </p>
+         *
+         * <p>
+         * <b>${JAVA_HOME}/lib/jaxp.properties:</b> This configuration file is in standard
+         * java.util.Properties format. If the file exists and the system property is specified,
+         * its value will be used to override the default of the property.
+         *
+         * @since 1.7
+         * </p>
+         */
+        public static final String ACCESS_EXTERNAL_SCHEMA = "http://javax.xml.XMLConstants/property/accessExternalSchema";
+
+        /**
+         * <p>Property: accessExternalStylesheet</p>
+         *
+         * <p>
+         * Restrict access to the protocols specified for external references set by the
+         * stylesheet processing instruction, Import and Include element, and document function.
+         * If access is denied due to the restriction of this property, a runtime exception
+         * that is specific to the context is thrown. In the case of constructing new
+         * {@link javax.xml.transform.Transformer} for example,
+         * {@link javax.xml.transform.TransformerConfigurationException}
+         * will be thrown by the {@link javax.xml.transform.TransformerFactory}.
+         * </p>
+         * <p>
+         * <b>Value:</b> a list of protocols separated by comma. A protocol is the scheme portion of a
+         * {@link java.net.URI}, or in the case of the JAR protocol, "jar" plus the scheme portion
+         * separated by colon.
+         * A scheme is defined as:
+         *
+         * <blockquote>
+         * scheme = alpha *( alpha | digit | "+" | "-" | "." )<br>
+         * where alpha = a-z and A-Z.<br><br>
+         *
+         * And the JAR protocol:<br>
+         *
+         * jar[:scheme]<br><br>
+         *
+         * Protocols including the keyword "jar" are case-insensitive. Any whitespaces as defined by
+         * {@link java.lang.Character#isSpaceChar } in the value will be ignored.
+         * Examples of protocols are file, http, jar:file.
+         *
+         * </blockquote>
+         *</p>
+         *
+         *<p>
+         * <b>Default value:</b> The default value is implementation specific and therefore not specified.
+         * The following options are provided for consideration:
+         * <blockquote>
+         * <UL>
+         *     <LI>an empty string to deny all access to external references;</LI>
+         *     <LI>a specific protocol, such as file, to give permission to only the protocol;</LI>
+         *     <LI>the keyword "all" to grant  permission to all protocols.</LI>
+         *</UL><br>
+         *      When FEATURE_SECURE_PROCESSING is enabled,  it is recommended that implementations
+         *      restrict external connections by default, though this may cause problems for applications
+         *      that process XML/XSD/XSL with external references.
+         * </blockquote>
+         * </p>
+         * <p>
+         * <b>Granting all access:</b>  the keyword "all" grants permission to all protocols.
+         * </p>
+         *
+         * <p>
+         * <b>System Property:</b> The value of this property can be set or overridden by
+         * system property {@code javax.xml.accessExternalStylesheet}
+         * </p>
+         *
+         * <p>
+         * <b>${JAVA_HOME}/lib/jaxp.properties: </b> This configuration file is in standard
+         * java.util.Properties format. If the file exists and the system property is specified,
+         * its value will be used to override the default of the property.
+         *
+         * @since 1.7
+         */
+        public static final String ACCESS_EXTERNAL_STYLESHEET = "http://javax.xml.XMLConstants/property/accessExternalStylesheet";
+
 }
diff --git a/jaxp/src/javax/xml/parsers/DocumentBuilderFactory.java b/jaxp/src/javax/xml/parsers/DocumentBuilderFactory.java
index 0ef1c13..748a163 100644
--- a/jaxp/src/javax/xml/parsers/DocumentBuilderFactory.java
+++ b/jaxp/src/javax/xml/parsers/DocumentBuilderFactory.java
@@ -351,6 +351,31 @@
     /**
      * Allows the user to set specific attributes on the underlying
      * implementation.
+     * <p>
+     * All implementations that implement JAXP 1.5 or newer are required to
+     * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and
+     * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties.
+     * </p>
+     * <ul>
+     *   <li>
+     *      <p>
+     *      Setting the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property
+     *      restricts the access to external DTDs, external Entity References to the
+     *      protocols specified by the property.
+     *      If access is denied during parsing due to the restriction of this property,
+     *      {@link org.xml.sax.SAXException} will be thrown by the parse methods defined by
+     *      {@link javax.xml.parsers.DocumentBuilder}.
+     *      </p>
+     *      <p>
+     *      Setting the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property
+     *      restricts the access to external Schema set by the schemaLocation attribute to
+     *      the protocols specified by the property.  If access is denied during parsing
+     *      due to the restriction of this property, {@link org.xml.sax.SAXException}
+     *      will be thrown by the parse methods defined by
+     *      {@link javax.xml.parsers.DocumentBuilder}.
+     *      </p>
+     *   </li>
+     * </ul>
      *
      * @param name The name of the attribute.
      * @param value The value of the attribute.
diff --git a/jaxp/src/javax/xml/parsers/SAXParser.java b/jaxp/src/javax/xml/parsers/SAXParser.java
index ef7b2e9..5461413 100644
--- a/jaxp/src/javax/xml/parsers/SAXParser.java
+++ b/jaxp/src/javax/xml/parsers/SAXParser.java
@@ -441,6 +441,29 @@
      * A list of the core features and properties can be found at
      * <a href="http://sax.sourceforge.net/?selected=get-set">
      * http://sax.sourceforge.net/?selected=get-set</a>.</p>
+     * <p>
+     * All implementations that implement JAXP 1.5 or newer are required to
+     * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and
+     * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties.
+     * </p>
+     * <ul>
+     *   <li>
+     *      <p>
+     *      Setting the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property
+     *      restricts the access to external DTDs, external Entity References to
+     *      the protocols specified by the property.  If access is denied during parsing
+     *      due to the restriction of this property, {@link org.xml.sax.SAXException}
+     *      will be thrown by the parse methods defined by {@link javax.xml.parsers.SAXParser}.
+     *      </p>
+     *      <p>
+     *      Setting the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property
+     *      restricts the access to external Schema set by the schemaLocation attribute to
+     *      the protocols specified by the property.  If access is denied during parsing
+     *      due to the restriction of this property, {@link org.xml.sax.SAXException}
+     *      will be thrown by the parse methods defined by the {@link javax.xml.parsers.SAXParser}.
+     *      </p>
+     *   </li>
+     * </ul>
      *
      * @param name The name of the property to be set.
      * @param value The value of the property to be set.
diff --git a/jaxp/src/javax/xml/stream/XMLInputFactory.java b/jaxp/src/javax/xml/stream/XMLInputFactory.java
index 2bfbad5..d894893 100644
--- a/jaxp/src/javax/xml/stream/XMLInputFactory.java
+++ b/jaxp/src/javax/xml/stream/XMLInputFactory.java
@@ -433,9 +433,26 @@
   public abstract void setXMLReporter(XMLReporter reporter);
 
   /**
-   * Allows the user to set specific feature/property on the underlying implementation. The underlying implementation
-   * is not required to support every setting of every property in the specification and may use IllegalArgumentException
-   * to signal that an unsupported property may not be set with the specified value.
+   * Allows the user to set specific feature/property on the underlying
+   * implementation. The underlying implementation is not required to support
+   * every setting of every property in the specification and may use
+   * IllegalArgumentException to signal that an unsupported property may not be
+   * set with the specified value.
+   * <p>
+   * All implementations that implement JAXP 1.5 or newer are required to
+   * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property.
+   * </p>
+   * <ul>
+   *   <li>
+   *        <p>
+   *        Access to external DTDs, external Entity References is restricted to the
+   *        protocols specified by the property. If access is denied during parsing
+   *        due to the restriction of this property, {@link javax.xml.stream.XMLStreamException}
+   *        will be thrown by the {@link javax.xml.stream.XMLStreamReader#next()} or
+   *        {@link javax.xml.stream.XMLEventReader#nextEvent()} method.
+   *        </p>
+   *   </li>
+   * </ul>
    * @param name The name of the property (may not be null)
    * @param value The value of the property
    * @throws java.lang.IllegalArgumentException if the property is not supported
diff --git a/jaxp/src/javax/xml/transform/TransformerFactory.java b/jaxp/src/javax/xml/transform/TransformerFactory.java
index 6152885..9c4a076 100644
--- a/jaxp/src/javax/xml/transform/TransformerFactory.java
+++ b/jaxp/src/javax/xml/transform/TransformerFactory.java
@@ -325,6 +325,46 @@
      * be an option that the implementation provides.
      * An <code>IllegalArgumentException</code> is thrown if the underlying
      * implementation doesn't recognize the attribute.
+     * <p>
+     * All implementations that implement JAXP 1.5 or newer are required to
+     * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD}  and
+     * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_STYLESHEET} properties.
+     * </p>
+     * <ul>
+     *   <li>
+     *      <p>
+     *      Access to external DTDs in the source file is restricted to the protocols
+     *      specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property.
+     *      If access is denied during transformation due to the restriction of this property,
+     *      {@link javax.xml.transform.TransformerException} will be thrown by
+     *      {@link javax.xml.transform.Transformer#transform(Source, Result)}.
+     *      </p>
+     *      <p>
+     *      Access to external DTDs in the stylesheet is restricted to the protocols
+     *      specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property.
+     *      If access is denied during the creation of a new transformer due to the
+     *      restriction of this property,
+     *      {@link javax.xml.transform.TransformerConfigurationException} will be thrown
+     *      by the {@link #newTransformer(Source)} method.
+     *      </p>
+     *      <p>
+     *      Access to external reference set by the stylesheet processing instruction,
+     *      Import and Include element is restricted to the protocols specified by the
+     *      {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_STYLESHEET} property.
+     *      If access is denied during the creation of a new transformer due to the
+     *      restriction of this property,
+     *      {@link javax.xml.transform.TransformerConfigurationException} will be thrown
+     *      by the {@link #newTransformer(Source)} method.
+     *      </p>
+     *      <p>
+     *      Access to external document through XSLT document function is restricted
+     *      to the protocols specified by the property. If access is denied during
+     *      the transformation due to the restriction of this property,
+     *      {@link javax.xml.transform.TransformerException} will be thrown by the
+     *      {@link javax.xml.transform.Transformer#transform(Source, Result)} method.
+     *      </p>
+     *   </li>
+     * </ul>
      *
      * @param name The name of the attribute.
      * @param value The value of the attribute.
diff --git a/jaxp/src/javax/xml/validation/SchemaFactory.java b/jaxp/src/javax/xml/validation/SchemaFactory.java
index 6f156af0..d99f450 100644
--- a/jaxp/src/javax/xml/validation/SchemaFactory.java
+++ b/jaxp/src/javax/xml/validation/SchemaFactory.java
@@ -390,8 +390,44 @@
      * possible for a {@link SchemaFactory} to recognize a property name but
      * to be unable to change the current value.</p>
      *
-     * <p>{@link SchemaFactory}s are not required to recognize setting
-     * any specific property names.</p>
+     * <p>
+     * All implementations that implement JAXP 1.5 or newer are required to
+     * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and
+     * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties.
+     * </p>
+     * <ul>
+     *   <li>
+     *      <p>Access to external DTDs in Schema files is restricted to the protocols
+     *      specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property.
+     *      If access is denied during the creation of new Schema due to the restriction
+     *      of this property, {@link org.xml.sax.SAXException} will be thrown by the
+     *      {@link #newSchema(Source)} or {@link #newSchema(File)}
+     *      or {@link #newSchema(URL)} or  or {@link #newSchema(Source[])} method.</p>
+     *
+     *      <p>Access to external DTDs in xml source files is restricted to the protocols
+     *      specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property.
+     *      If access is denied during validation due to the restriction
+     *      of this property, {@link org.xml.sax.SAXException} will be thrown by the
+     *      {@link javax.xml.validation.Validator#validate(Source)} or
+     *      {@link javax.xml.validation.Validator#validate(Source, Result)} method.</p>
+     *
+     *      <p>Access to external reference set by the schemaLocation attribute is
+     *      restricted to the protocols specified by the
+     *      {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property.
+     *      If access is denied during validation due to the restriction of this property,
+     *      {@link org.xml.sax.SAXException} will be thrown by the
+     *      {@link javax.xml.validation.Validator#validate(Source)} or
+     *      {@link javax.xml.validation.Validator#validate(Source, Result)} method.</p>
+     *
+     *      <p>Access to external reference set by the Import
+     *      and Include element is restricted to the protocols specified by the
+     *      {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property.
+     *      If access is denied during the creation of new Schema due to the restriction
+     *      of this property, {@link org.xml.sax.SAXException} will be thrown by the
+     *      {@link #newSchema(Source)} or {@link #newSchema(File)}
+     *      or {@link #newSchema(URL)} or {@link #newSchema(Source[])} method.</p>
+     *   </li>
+     * </ul>
      *
      * @param name The property name, which is a non-null fully-qualified URI.
      * @param object The requested value for the property.
diff --git a/jaxp/src/javax/xml/validation/Validator.java b/jaxp/src/javax/xml/validation/Validator.java
index ee66a6d..fad7c5a 100644
--- a/jaxp/src/javax/xml/validation/Validator.java
+++ b/jaxp/src/javax/xml/validation/Validator.java
@@ -440,8 +440,27 @@
      * in specific contexts, such as before, during, or after
      * a validation.</p>
      *
-     * <p>{@link Validator}s are not required to recognize setting
-     * any specific property names.</p>
+     * <p>
+     * All implementations that implement JAXP 1.5 or newer are required to
+     * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and
+     * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties.
+     * </p>
+     * <ul>
+     *   <li>
+     *      <p>Access to external DTDs in source or Schema file is restricted to
+     *      the protocols specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD}
+     *      property.  If access is denied during validation due to the restriction
+     *      of this property, {@link org.xml.sax.SAXException} will be thrown by the
+     *      {@link #validate(Source)} method.</p>
+     *
+     *      <p>Access to external reference set by the schemaLocation attribute is
+     *      restricted to the protocols specified by the
+     *      {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property.
+     *      If access is denied during validation due to the restriction of this property,
+     *      {@link org.xml.sax.SAXException} will be thrown by the
+     *      {@link #validate(Source)} method.</p>
+     *   </li>
+     * </ul>
      *
      * @param name The property name, which is a non-null fully-qualified URI.
      * @param object The requested value for the property.
diff --git a/jaxws/.hgtags b/jaxws/.hgtags
index 6ba4754..b60c92c 100644
--- a/jaxws/.hgtags
+++ b/jaxws/.hgtags
@@ -211,3 +211,4 @@
 72e03566f0a61282cc48ebc869803b256cccd66c jdk8-b87
 24fa5452e5d4e9df8b85196283275a6ca4b4adb4 jdk8-b88
 88838e08e4ef6a254867c8126070a1975683108d jdk8-b89
+3e5b9ea5ac35ea7096da484e24a863cf4552179f jdk8-b90
diff --git a/jdk/.hgtags b/jdk/.hgtags
index 303bb67..7be0eb3 100644
--- a/jdk/.hgtags
+++ b/jdk/.hgtags
@@ -211,3 +211,4 @@
 d5228e624826a10ccc5b05f30ad8d839b58fe48d jdk8-b87
 8dbb4b159e04de3c447c9242c70505e71f8624c7 jdk8-b88
 845025546e35519fbb8970e79fc2a834063a5e19 jdk8-b89
+c63eda8f63008a4398d2c22ac8d72f7fef6f9238 jdk8-b90
diff --git a/jdk/make/com/sun/Makefile b/jdk/make/com/sun/Makefile
index 052cd54..e33b27f 100644
--- a/jdk/make/com/sun/Makefile
+++ b/jdk/make/com/sun/Makefile
@@ -31,13 +31,6 @@
 PRODUCT = sun
 include $(BUILDDIR)/common/Defs.gmk
 
-ifndef OPENJDK
-  ORG_EXISTS := $(call DirExists,$(CLOSED_SRC)/share/classes/sun/org,,)
-  ifneq ("$(ORG_EXISTS)", "") 
-    SCRIPT_SUBDIR = script
-  endif
-endif
-
 # jarsigner is part of JRE
 SUBDIRS = java security net/ssl jarsigner
 
diff --git a/jdk/make/com/sun/script/Makefile b/jdk/make/com/sun/script/Makefile
deleted file mode 100644
index 58e134f..0000000
--- a/jdk/make/com/sun/script/Makefile
+++ /dev/null
@@ -1,62 +0,0 @@
-#
-# Copyright (c) 2005, 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.
-#
-
-
-BUILDDIR = ../../..
-PACKAGE = com.sun.script
-PRODUCT = sun
-include $(BUILDDIR)/common/Defs.gmk
-
-AUTO_FILES_JAVA_DIRS = com/sun/script
-
-#
-# Files that need to be copied
-#
-SERVICEDIR = $(CLASSBINDIR)/META-INF/services
-                                                                                                
-FILES_copy = \
-	$(SERVICEDIR)/javax.script.ScriptEngineFactory
-
-include $(BUILDDIR)/common/Classes.gmk
-
-all: classes copy-files
-
-#
-# Copy the service provider configuration file into the resource
-# directory.
-#
-
-copy-files: $(FILES_copy)
-                                                                                                
-$(SERVICEDIR)/%: $(SHARE_SRC)/classes/com/sun/script/javascript/META-INF/services/%
-	$(install-file)
-                                                                                                
-.PHONY: copy-files
-
-
-clean::
-	$(RM) -r $(CLASSDESTDIR)/com/sun/script/javascript
-	$(RM) $(FILES_copy)
-
diff --git a/jdk/make/common/Release.gmk b/jdk/make/common/Release.gmk
index 2cdfc0e..ce2dda5 100644
--- a/jdk/make/common/Release.gmk
+++ b/jdk/make/common/Release.gmk
@@ -969,26 +969,35 @@
 
 # Create the list of db *.zip files to bundle with jdk
 ABS_DB_PATH  :=$(call FullPath,$(CLOSED_SHARE_SRC)/db)
-DB_ZIP_LIST = $(shell $(LS) $(ABS_DB_PATH)/*.zip 2>/dev/null)
+DB_BINARY_BUNDLE = $(shell $(LS) $(ABS_DB_PATH)/db-derby-*-bin.zip 2>/dev/null)
 
 # Java DB image. Move the Java DB demo directory into the JDK's demo
 # dir and in the process, rename it to db.  Also remove index.html,
-# since it presumes docs are co-located. Also remove register.html (no
-# longer relevant).
-initial-image-jdk-db: $(DB_ZIP_LIST)
+# since it presumes docs are co-located, javadoc, docs and tests and
+# update the copyright year of the JDK READMEs to that of the release.
+initial-image-jdk-db: $(DB_BINARY_BUNDLE)
 	$(MKDIR) -p $(JDK_IMAGE_DIR)/db
-	for d in $(DB_ZIP_LIST); do \
-          ($(CD) $(JDK_IMAGE_DIR)/db && $(UNZIP) -o $$d); \
-	done
-	$(CP) $(ABS_DB_PATH)/README-JDK.html $(JDK_IMAGE_DIR)/db
+	$(CD) $(JDK_IMAGE_DIR)/db && $(UNZIP) -o $(DB_BINARY_BUNDLE)
+	$(CD) $(JDK_IMAGE_DIR)/db && $(MV) db-derby-*-bin/* .
+	$(CD) $(JDK_IMAGE_DIR)/db && $(RM) -r db-derby-*-bin
+	$(CAT) $(ABS_DB_PATH)/README-JDK.html  | \
+		$(SED) "s/XXXX/$(shell cat $(JDK_TOPDIR)/src/closed/share/db/COPYRIGHTYEAR)/" > \
+		$(JDK_IMAGE_DIR)/db/README-JDK.html
+	$(CAT) $(ABS_DB_PATH)/3RDPARTY  | \
+		$(SED) "s/XXXX/$(shell cat $(JDK_TOPDIR)/src/closed/share/db/COPYRIGHTYEAR)/" > \
+		$(JDK_IMAGE_DIR)/db/3RDPARTY
 ifndef NO_DEMOS
-	$(RM) -rf $(DEMODIR)/db
+	$(RM) -r $(DEMODIR)/db
 	$(MV) $(JDK_IMAGE_DIR)/db/demo $(DEMODIR)/db
-	$(CP) $(ABS_DB_PATH)/README-JDK-DEMOS.html $(DEMODIR)/db/
+	$(CAT) $(ABS_DB_PATH)/README-JDK-DEMOS.html  | \
+		$(SED) "s/XXXX/$(shell cat $(JDK_TOPDIR)/src/closed/share/db/COPYRIGHTYEAR)/" > \
+		$(DEMODIR)/db/README-JDK-DEMOS.html
 else
-	$(RM) -rf $(JDK_IMAGE_DIR)/db/demo
+	$(RM) -r $(JDK_IMAGE_DIR)/db/demo
 endif
-	$(RM) $(JDK_IMAGE_DIR)/db/index.html $(JDK_IMAGE_DIR)/db/register.html
+	@# remove stuff from original distro we don't want
+	$(RM) $(JDK_IMAGE_DIR)/db/index.html $(JDK_IMAGE_DIR)/db/KEYS
+	$(RM) -r $(JDK_IMAGE_DIR)/db/{docs,javadoc,test}
 endif
 
 # The launcher source files we need for src.zip
diff --git a/jdk/make/sun/Makefile b/jdk/make/sun/Makefile
index 35fb554..c9d6f9c 100644
--- a/jdk/make/sun/Makefile
+++ b/jdk/make/sun/Makefile
@@ -31,12 +31,6 @@
 PRODUCT  = sun
 include $(BUILDDIR)/common/Defs.gmk
 
-# Rhino/Mozilla java sources
-ORG_EXISTS := $(call DirExists,$(CLOSED_SRC)/share/classes/sun/org,,)
-ifneq ("$(ORG_EXISTS)", "")
-  ORG_SUBDIR = org
-endif
-
 # Non windows subdirs
 ifneq ($(PLATFORM), windows)
   ifndef OPENJDK
@@ -83,7 +77,7 @@
                      $(LWAWT_PRE_SUBDIR) $(DISPLAY_LIBS) $(DGA_SUBDIR) $(LWAWT_SUBDIR) \
                      jawt font jpeg cmm $(DISPLAY_TOOLS)
 SUBDIRS_management = management
-SUBDIRS_misc       = $(ORG_SUBDIR) rmi tracing
+SUBDIRS_misc       = rmi tracing
 SUBDIRS_tools      = native2ascii serialver tools jconsole
 
 ifndef OPENJDK
diff --git a/jdk/make/sun/awt/mapfile-vers b/jdk/make/sun/awt/mapfile-vers
index 5c6cfea..f68ef5c 100644
--- a/jdk/make/sun/awt/mapfile-vers
+++ b/jdk/make/sun/awt/mapfile-vers
@@ -87,6 +87,7 @@
                 Java_sun_java2d_pipe_ShapeSpanIterator_skipDownTo;
 
 		Java_java_awt_Dimension_initIDs;
+		Java_java_awt_Choice_initIDs;
 		Java_java_awt_event_MouseEvent_initIDs;
 		Java_java_awt_image_DataBufferInt_initIDs;
 		Java_java_awt_image_SinglePixelPackedSampleModel_initIDs;
diff --git a/jdk/make/sun/awt/mapfile-vers-bsd b/jdk/make/sun/awt/mapfile-vers-bsd
index f606b3f..dcc59f0 100644
--- a/jdk/make/sun/awt/mapfile-vers-bsd
+++ b/jdk/make/sun/awt/mapfile-vers-bsd
@@ -87,6 +87,7 @@
                 Java_sun_java2d_pipe_ShapeSpanIterator_skipDownTo;
 
 		Java_java_awt_Dimension_initIDs;
+		Java_java_awt_Choice_initIDs;
 		Java_java_awt_event_MouseEvent_initIDs;
 		Java_java_awt_image_DataBufferInt_initIDs;
 		Java_java_awt_image_SinglePixelPackedSampleModel_initIDs;
diff --git a/jdk/make/sun/awt/mapfile-vers-linux b/jdk/make/sun/awt/mapfile-vers-linux
index b7033b8..03f0cc0 100644
--- a/jdk/make/sun/awt/mapfile-vers-linux
+++ b/jdk/make/sun/awt/mapfile-vers-linux
@@ -87,6 +87,7 @@
                 Java_sun_java2d_pipe_ShapeSpanIterator_skipDownTo;
 
 		Java_java_awt_Dimension_initIDs;
+		Java_java_awt_Choice_initIDs;
 		Java_java_awt_event_MouseEvent_initIDs;
 		Java_java_awt_image_DataBufferInt_initIDs;
 		Java_java_awt_image_SinglePixelPackedSampleModel_initIDs;
diff --git a/jdk/make/sun/javazic/tzdata/VERSION b/jdk/make/sun/javazic/tzdata/VERSION
index 85db871..8ad1064 100644
--- a/jdk/make/sun/javazic/tzdata/VERSION
+++ b/jdk/make/sun/javazic/tzdata/VERSION
@@ -21,4 +21,4 @@
 # or visit www.oracle.com if you need additional information or have any
 # questions.
 #
-tzdata2012i
+tzdata2013c
diff --git a/jdk/make/sun/javazic/tzdata/africa b/jdk/make/sun/javazic/tzdata/africa
index 7db9b3d..2f5d3c5 100644
--- a/jdk/make/sun/javazic/tzdata/africa
+++ b/jdk/make/sun/javazic/tzdata/africa
@@ -27,9 +27,9 @@
 
 # This data is by no means authoritative; if you think you know better,
 # go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
+# tz@iana.org for general use in the future).
 
-# From Paul Eggert (2006-03-22):
+# From Paul Eggert (2013-02-21):
 #
 # A good source for time zone historical data outside the U.S. is
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
@@ -48,6 +48,10 @@
 # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
 # I found in the UCLA library.
 #
+# For data circa 1899, a common source is:
+# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+# <http://www.jstor.org/stable/1774359>.
+#
 # A reliable and entertaining source about time zones is
 # Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
 #
@@ -139,8 +143,12 @@
 			1:00	-	WAT
 
 # Botswana
+# From Paul Eggert (2013-02-21):
+# Milne says they were regulated by the Cape Town Signal in 1899;
+# assume they switched to 2:00 when Cape Town did.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Gaborone	1:43:40 -	LMT	1885
+			1:30	-	SAST	1903 Mar
 			2:00	-	CAT	1943 Sep 19 2:00
 			2:00	1:00	CAST	1944 Mar 19 2:00
 			2:00	-	CAT
@@ -212,6 +220,11 @@
 
 # Egypt
 
+# Milne says Cairo used 2:05:08.9, the local mean time of the Abbasizeh
+# observatory; round to nearest.  Milne also says that the official time for
+# Egypt was mean noon at the Great Pyramid, 2:04:30.5, but apparently this
+# did not apply to Cairo, Alexandria, or Port Said.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Egypt	1940	only	-	Jul	15	0:00	1:00	S
 Rule	Egypt	1940	only	-	Oct	 1	0:00	0	-
@@ -352,7 +365,7 @@
 Rule	Egypt	2010	only	-	Sep	lastThu	23:00s	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Cairo	2:05:00 -	LMT	1900 Oct
+Zone	Africa/Cairo	2:05:09 -	LMT	1900 Oct
 			2:00	Egypt	EE%sT
 
 # Equatorial Guinea
@@ -447,6 +460,20 @@
 
 # Libya
 
+# From Even Scharning (2012-11-10):
+# Libya set their time one hour back at 02:00 on Saturday November 10.
+# http://www.libyaherald.com/2012/11/04/clocks-to-go-back-an-hour-on-saturday/
+# Here is an official source [in Arabic]: http://ls.ly/fb6Yc
+#
+# Steffen Thorsen forwarded a translation (2012-11-10) in
+# http://mm.icann.org/pipermail/tz/2012-November/018451.html
+#
+# From Tim Parenti (2012-11-11):
+# Treat the 2012-11-10 change as a zone change from UTC+2 to UTC+1.
+# The DST rules planned for 2013 and onward roughly mirror those of Europe
+# (either two days before them or five days after them, so as to fall on
+# lastFri instead of lastSun).
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Libya	1951	only	-	Oct	14	2:00	1:00	S
 Rule	Libya	1952	only	-	Jan	 1	0:00	0	-
@@ -461,17 +488,21 @@
 Rule	Libya	1986	only	-	Oct	 3	0:00	0	-
 Rule	Libya	1987	1989	-	Apr	 1	0:00	1:00	S
 Rule	Libya	1987	1989	-	Oct	 1	0:00	0	-
+Rule	Libya	1997	only	-	Apr	 4	0:00	1:00	S
+Rule	Libya	1997	only	-	Oct	 4	0:00	0	-
+Rule	Libya	2013	max	-	Mar	lastFri	1:00	1:00	S
+Rule	Libya	2013	max	-	Oct	lastFri	2:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Tripoli	0:52:44 -	LMT	1920
 			1:00	Libya	CE%sT	1959
 			2:00	-	EET	1982
 			1:00	Libya	CE%sT	1990 May  4
-# The following entries are from Shanks & Pottenger;
+# The 1996 and 1997 entries are from Shanks & Pottenger;
 # the IATA SSIM data contain some obvious errors.
 			2:00	-	EET	1996 Sep 30
-			1:00	-	CET	1997 Apr  4
-			1:00	1:00	CEST	1997 Oct  4
-			2:00	-	EET
+			1:00	Libya	CE%sT	1997 Oct  4
+			2:00	-	EET	2012 Nov 10 2:00
+			1:00	Libya	CE%sT
 
 # Madagascar
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -838,6 +869,41 @@
 # 3:00 am Friday, July 20, 2012 and will again be advanced by 60 minutes
 # August 20, 2012 from 2:00 am.
 
+# From Paul Eggert (2013-03-06):
+# Morocco's daylight-saving transitions due to Ramadan seem to be
+# announced a bit in advance.  On 2012-07-11 the Moroccan government
+# announced that year's Ramadan daylight-saving transitions would be
+# 2012-07-20 and 2012-08-20; see
+# <http://www.mmsp.gov.ma/fr/actualites.aspx?id=288>.
+#
+# To estimate what the Moroccan government will do in future years,
+# transition dates for 2013 through 2021 were determined by running
+# the following program under GNU Emacs 24.3:
+#
+# (let ((islamic-year 1434))
+#   (while (< islamic-year 1444)
+#     (let ((a
+#	     (calendar-gregorian-from-absolute
+#	      (calendar-islamic-to-absolute (list 9 1 islamic-year))))
+#	    (b
+#	     (calendar-gregorian-from-absolute
+#	      (calendar-islamic-to-absolute (list 10 1 islamic-year)))))
+#	(insert
+#	 (format
+#	  (concat "Rule\tMorocco\t%d\tonly\t-\t%s\t %2d\t 3:00\t0\t-\n"
+#		  "Rule\tMorocco\t%d\tonly\t-\t%s\t %2d\t 2:00\t1:00\tS\n")
+#	  (car (cdr (cdr a))) (calendar-month-name (car a) t) (car (cdr a))
+#	  (car (cdr (cdr b))) (calendar-month-name (car b) t) (car (cdr b)))))
+#     (setq islamic-year (+ 1 islamic-year))))
+#
+# with the results hand-edited for 2020-2022, when the normal spring-forward
+# date falls during the estimated Ramadan.
+#
+# From 2023 through 2038 Ramadan is not predicted to overlap with
+# daylight saving time.  Starting in 2039 there will be overlap again,
+# but 32-bit time_t values roll around in 2038 so for now do not worry
+# about dates after 2038.
+
 # RULE	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 
 Rule	Morocco	1939	only	-	Sep	12	 0:00	1:00	S
@@ -863,10 +929,28 @@
 Rule	Morocco	2010	only	-	Aug	 8	 0:00	0	-
 Rule	Morocco	2011	only	-	Apr	 3	 0:00	1:00	S
 Rule	Morocco	2011	only	-	Jul	 31	 0	0	-
-Rule	Morocco	2012	max	-	Apr	 lastSun 2:00	1:00	S
+Rule	Morocco	2012	2019	-	Apr	 lastSun 2:00	1:00	S
 Rule	Morocco	2012	max	-	Sep	 lastSun 3:00	0	-
 Rule	Morocco	2012	only	-	Jul	 20	 3:00	0	-
 Rule	Morocco	2012	only	-	Aug	 20	 2:00	1:00	S
+Rule	Morocco	2013	only	-	Jul	  9	 3:00	0	-
+Rule	Morocco	2013	only	-	Aug	  8	 2:00	1:00	S
+Rule	Morocco	2014	only	-	Jun	 29	 3:00	0	-
+Rule	Morocco	2014	only	-	Jul	 29	 2:00	1:00	S
+Rule	Morocco	2015	only	-	Jun	 18	 3:00	0	-
+Rule	Morocco	2015	only	-	Jul	 18	 2:00	1:00	S
+Rule	Morocco	2016	only	-	Jun	  7	 3:00	0	-
+Rule	Morocco	2016	only	-	Jul	  7	 2:00	1:00	S
+Rule	Morocco	2017	only	-	May	 27	 3:00	0	-
+Rule	Morocco	2017	only	-	Jun	 26	 2:00	1:00	S
+Rule	Morocco	2018	only	-	May	 16	 3:00	0	-
+Rule	Morocco	2018	only	-	Jun	 15	 2:00	1:00	S
+Rule	Morocco	2019	only	-	May	  6	 3:00	0	-
+Rule	Morocco	2019	only	-	Jun	  5	 2:00	1:00	S
+Rule	Morocco	2020	only	-	May	 24	 2:00	1:00	S
+Rule	Morocco	2021	only	-	May	 13	 2:00	1:00	S
+Rule	Morocco	2022	only	-	May	  3	 2:00	1:00	S
+Rule	Morocco	2023	max	-	Apr	 lastSun 2:00	1:00	S
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Africa/Casablanca	-0:30:20 -	LMT	1913 Oct 26
diff --git a/jdk/make/sun/javazic/tzdata/antarctica b/jdk/make/sun/javazic/tzdata/antarctica
index 64b71d5..daa03ea 100644
--- a/jdk/make/sun/javazic/tzdata/antarctica
+++ b/jdk/make/sun/javazic/tzdata/antarctica
@@ -73,38 +73,8 @@
 Rule	ChileAQ	2010	only	-	Apr	Sun>=1	3:00u	0	-
 Rule	ChileAQ	2011	only	-	May	Sun>=2	3:00u	0	-
 Rule	ChileAQ	2011	only	-	Aug	Sun>=16	4:00u	1:00	S
-Rule	ChileAQ	2012	only	-	Apr	Sun>=23	3:00u	0	-
-Rule	ChileAQ	2012	only	-	Sep	Sun>=2	4:00u	1:00	S
-Rule	ChileAQ	2013	max	-	Mar	Sun>=9	3:00u	0	-
-Rule	ChileAQ	2013	max	-	Oct	Sun>=9	4:00u	1:00	S
-
-# These rules are stolen from the `australasia' file.
-Rule	AusAQ	1917	only	-	Jan	 1	0:01	1:00	-
-Rule	AusAQ	1917	only	-	Mar	25	2:00	0	-
-Rule	AusAQ	1942	only	-	Jan	 1	2:00	1:00	-
-Rule	AusAQ	1942	only	-	Mar	29	2:00	0	-
-Rule	AusAQ	1942	only	-	Sep	27	2:00	1:00	-
-Rule	AusAQ	1943	1944	-	Mar	lastSun	2:00	0	-
-Rule	AusAQ	1943	only	-	Oct	 3	2:00	1:00	-
-Rule	ATAQ	1967	only	-	Oct	Sun>=1	2:00s	1:00	-
-Rule	ATAQ	1968	only	-	Mar	lastSun	2:00s	0	-
-Rule	ATAQ	1968	1985	-	Oct	lastSun	2:00s	1:00	-
-Rule	ATAQ	1969	1971	-	Mar	Sun>=8	2:00s	0	-
-Rule	ATAQ	1972	only	-	Feb	lastSun	2:00s	0	-
-Rule	ATAQ	1973	1981	-	Mar	Sun>=1	2:00s	0	-
-Rule	ATAQ	1982	1983	-	Mar	lastSun	2:00s	0	-
-Rule	ATAQ	1984	1986	-	Mar	Sun>=1	2:00s	0	-
-Rule	ATAQ	1986	only	-	Oct	Sun>=15	2:00s	1:00	-
-Rule	ATAQ	1987	1990	-	Mar	Sun>=15	2:00s	0	-
-Rule	ATAQ	1987	only	-	Oct	Sun>=22	2:00s	1:00	-
-Rule	ATAQ	1988	1990	-	Oct	lastSun	2:00s	1:00	-
-Rule	ATAQ	1991	1999	-	Oct	Sun>=1	2:00s	1:00	-
-Rule	ATAQ	1991	2005	-	Mar	lastSun	2:00s	0	-
-Rule	ATAQ	2000	only	-	Aug	lastSun	2:00s	1:00	-
-Rule	ATAQ	2001	max	-	Oct	Sun>=1	2:00s	1:00	-
-Rule	ATAQ	2006	only	-	Apr	Sun>=1	2:00s	0	-
-Rule	ATAQ	2007	only	-	Mar	lastSun	2:00s	0	-
-Rule	ATAQ	2008	max	-	Apr	Sun>=1	2:00s	0	-
+Rule	ChileAQ	2012	max	-	Apr	Sun>=23	3:00u	0	-
+Rule	ChileAQ	2012	max	-	Sep	Sun>=2	4:00u	1:00	S
 
 # Argentina - year-round bases
 # Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05
@@ -147,10 +117,7 @@
 # </a>
 
 # From Steffen Thorsen (2010-03-10):
-# We got these changes from the Australian Antarctic Division:
-# - Macquarie Island will stay on UTC+11 for winter and therefore not
-# switch back from daylight savings time when other parts of Australia do
-# on 4 April.
+# We got these changes from the Australian Antarctic Division: ...
 #
 # - Casey station reverted to its normal time of UTC+8 on 5 March 2010.
 # The change to UTC+11 is being considered as a regular summer thing but
@@ -161,9 +128,6 @@
 #
 # - Mawson station stays on UTC+5.
 #
-# In addition to the Rule changes for Casey/Davis, it means that Macquarie
-# will no longer be like Hobart and will have to have its own Zone created.
-#
 # Background:
 # <a href="http://www.timeanddate.com/news/time/antartica-time-changes-2010.html">
 # http://www.timeanddate.com/news/time/antartica-time-changes-2010.html
@@ -190,12 +154,6 @@
 			6:00	-	MAWT	2009 Oct 18 2:00
 						# Mawson Time
 			5:00	-	MAWT
-Zone Antarctica/Macquarie 0	-	zzz	1911
-			10:00	-	EST	1916 Oct 1 2:00
-			10:00	1:00	EST	1917 Feb
-			10:00	AusAQ	EST	1967
-			10:00	ATAQ	EST	2010 Apr 4 3:00
-			11:00	-	MIST	# Macquarie Island Time
 # References:
 # <a href="http://www.antdiv.gov.au/aad/exop/sfo/casey/casey_aws.html">
 # Casey Weather (1998-02-26)
diff --git a/jdk/make/sun/javazic/tzdata/asia b/jdk/make/sun/javazic/tzdata/asia
index 9ef3ef8..7818c02 100644
--- a/jdk/make/sun/javazic/tzdata/asia
+++ b/jdk/make/sun/javazic/tzdata/asia
@@ -27,9 +27,9 @@
 
 # This data is by no means authoritative; if you think you know better,
 # go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
+# tz@iana.org for general use in the future).
 
-# From Paul Eggert (2006-03-22):
+# From Paul Eggert (2013-02-21):
 #
 # A good source for time zone historical data outside the U.S. is
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
@@ -48,6 +48,10 @@
 # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
 # I found in the UCLA library.
 #
+# For data circa 1899, a common source is:
+# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+# <http://www.jstor.org/stable/1774359>.
+#
 # A reliable and entertaining source about time zones is
 # Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
 #
@@ -302,9 +306,12 @@
 			8:00	-	BNT
 
 # Burma / Myanmar
+
+# Milne says 6:24:40 was the meridian of the time ball observatory at Rangoon.
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Rangoon	6:24:40 -	LMT	1880		# or Yangon
-			6:24:36	-	RMT	1920	   # Rangoon Mean Time?
+			6:24:40	-	RMT	1920	   # Rangoon Mean Time?
 			6:30	-	BURT	1942 May   # Burma Time
 			9:00	-	JST	1945 May 3
 			6:30	-	MMT		   # Myanmar Time
@@ -407,7 +414,8 @@
 			8:00	PRC	C%sT
 # Zhongyuan Time ("Central plain Time")
 # most of China
-Zone	Asia/Shanghai	8:05:52	-	LMT	1928
+# Milne gives 8:05:56.7; round to nearest.
+Zone	Asia/Shanghai	8:05:57	-	LMT	1928
 			8:00	Shang	C%sT	1949
 			8:00	PRC	C%sT
 # Long-shu Time (probably due to Long and Shu being two names of that area)
@@ -504,6 +512,10 @@
 			8:00	PRC	C%sT
 
 
+# Hong Kong (Xianggang)
+
+# Milne gives 7:36:41.7; round this.
+
 # From Lee Yiu Chung (2009-10-24):
 # I found there are some mistakes for the...DST rule for Hong
 # Kong. [According] to the DST record from Hong Kong Observatory (actually,
@@ -570,7 +582,6 @@
 # The Japanese surrender of Hong Kong was signed 1945-09-15.
 # For lack of anything better, use start of those days as the transition times.
 
-# Hong Kong (Xianggang)
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	HK	1941	only	-	Apr	1	3:30	1:00	S
 Rule	HK	1941	only	-	Sep	30	3:30	0	-
@@ -592,7 +603,7 @@
 Rule	HK	1979	only	-	May	Sun>=8	3:30	1:00	S
 Rule	HK	1979	only	-	Oct	Sun>=16	3:30	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Hong_Kong	7:36:36 -	LMT	1904 Oct 30
+Zone	Asia/Hong_Kong	7:36:42 -	LMT	1904 Oct 30
 			8:00	HK	HK%sT	1941 Dec 25
 			9:00	-	JST	1945 Sep 15
 			8:00	HK	HK%sT
@@ -669,6 +680,9 @@
 ###############################################################################
 
 # Cyprus
+#
+# Milne says the Eastern Telegraph Company used 2:14:00.  Stick with LMT.
+#
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Cyprus	1975	only	-	Apr	13	0:00	1:00	S
 Rule	Cyprus	1975	only	-	Oct	12	0:00	0	-
@@ -1222,7 +1236,6 @@
 Rule	Zion	2012	only	-	Sep	23	2:00	0	S
 
 # From Ephraim Silverberg (2012-10-18):
-
 # Yesterday, the Interior Ministry Committee, after more than a year
 # past, approved sending the proposed June 2011 changes to the Time
 # Decree Law back to the Knesset for second and third (final) votes
@@ -1235,6 +1248,10 @@
 # later (i.e. at 02:00 the first Monday after October 2).
 # [Rosh Hashana holidays are factored in until 2100.]
 
+# From Ephraim Silverberg (2012-11-05):
+# The Knesset passed today (in second and final readings) the amendment to the
+# Time Decree Law making the changes ... law.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Zion	2013	max	-	Mar	Fri>=23	2:00	1:00	D
 Rule	Zion	2013	2026	-	Oct	Sun>=2	2:00	0	S
@@ -1824,8 +1841,11 @@
 			5:45	-	NPT	# Nepal Time
 
 # Oman
+
+# Milne says 3:54:24 was the meridian of the Muscat Tidal Observatory.
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Muscat	3:54:20 -	LMT	1920
+Zone	Asia/Muscat	3:54:24 -	LMT	1920
 			4:00	-	GST
 
 # Pakistan
@@ -2072,8 +2092,7 @@
 # occurred before our cutoff date of 1970.
 # However, as we get more information, we may need to add entries
 # for parts of the West Bank as they transitioned from Israel's rules
-# to Palestine's rules.  If you have more info about this, please
-# send it to tz@elsie.nci.nih.gov for incorporation into future editions.
+# to Palestine's rules.
 
 # From IINS News Service - Israel - 1998-03-23 10:38:07 Israel time,
 # forwarded by Ephraim Silverberg:
@@ -2295,11 +2314,20 @@
 # http://www.timeanddate.com/news/time/gaza-west-bank-dst-2012.html
 # </a>
 
-# From Arthur David Olson (2012-03-27):
-# The timeanddate article for 2012 says that "the end date has not yet been
-# announced" and that "Last year, both...paused daylight saving time during...
-# Ramadan. It is not yet known [for] 2012."
-# For now, assume both switch back on the last Friday in September. XXX
+# From Steffen Thorsen (2013-03-26):
+# The following news sources tells that Palestine will "start daylight saving
+# time from midnight on Friday, March 29, 2013" (translated).
+# [These are in Arabic and are for Gaza and for Ramallah, respectively.]
+# http://www.samanews.com/index.php?act=Show&id=154120
+# http://safa.ps/details/news/99844/%D8%B1%D8%A7%D9%85-%D8%A7%D9%84%D9%84%D9%87-%D8%A8%D8%AF%D8%A1-%D8%A7%D9%84%D8%AA%D9%88%D9%82%D9%8A%D8%AA-%D8%A7%D9%84%D8%B5%D9%8A%D9%81%D9%8A-29-%D8%A7%D9%84%D8%AC%D8%A7%D8%B1%D9%8A.html
+
+# From Paul Eggert (2013-04-15):
+# For future dates, guess the last Thursday in March at 24:00 through
+# the first Friday on or after September 21 at 01:00.  This is consistent with
+# the predictions in today's editions of the following URLs,
+# which are for Gaza and Hebron respectively:
+# http://www.timeanddate.com/worldclock/timezone.html?n=702
+# http://www.timeanddate.com/worldclock/timezone.html?n=2364
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule EgyptAsia	1957	only	-	May	10	0:00	1:00	S
@@ -2313,19 +2341,20 @@
 Rule Palestine	1999	2003	-	Oct	Fri>=15	0:00	0	-
 Rule Palestine	2004	only	-	Oct	 1	1:00	0	-
 Rule Palestine	2005	only	-	Oct	 4	2:00	0	-
-Rule Palestine	2006	2008	-	Apr	 1	0:00	1:00	S
+Rule Palestine	2006	2007	-	Apr	 1	0:00	1:00	S
 Rule Palestine	2006	only	-	Sep	22	0:00	0	-
 Rule Palestine	2007	only	-	Sep	Thu>=8	2:00	0	-
-Rule Palestine	2008	only	-	Aug	lastFri	0:00	0	-
-Rule Palestine	2009	only	-	Mar	lastFri	0:00	1:00	S
-Rule Palestine	2009	only	-	Sep	Fri>=1	2:00	0	-
-Rule Palestine	2010	only	-	Mar	lastSat	0:01	1:00	S
+Rule Palestine	2008	2009	-	Mar	lastFri	0:00	1:00	S
+Rule Palestine	2008	only	-	Sep	 1	0:00	0	-
+Rule Palestine	2009	only	-	Sep	Fri>=1	1:00	0	-
+Rule Palestine	2010	only	-	Mar	26	0:00	1:00	S
 Rule Palestine	2010	only	-	Aug	11	0:00	0	-
-
-# From Arthur David Olson (2011-09-20):
-# 2011 transitions per http://www.timeanddate.com as of 2011-09-20.
-# From Paul Eggert (2012-10-12):
-# 2012 transitions per http://www.timeanddate.com as of 2012-10-12.
+Rule Palestine	2011	only	-	Apr	 1	0:01	1:00	S
+Rule Palestine	2011	only	-	Aug	 1	0:00	0	-
+Rule Palestine	2011	only	-	Aug	30	0:00	1:00	S
+Rule Palestine	2011	only	-	Sep	30	0:00	0	-
+Rule Palestine	2012	max	-	Mar	lastThu	24:00	1:00	S
+Rule Palestine	2012	max	-	Sep	Fri>=21	1:00	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Gaza	2:17:52	-	LMT	1900 Oct
@@ -2333,26 +2362,20 @@
 			2:00 EgyptAsia	EE%sT	1967 Jun  5
 			2:00	Zion	I%sT	1996
 			2:00	Jordan	EE%sT	1999
-			2:00 Palestine	EE%sT	2011 Apr  2 12:01
-			2:00	1:00	EEST	2011 Aug  1
-			2:00	-	EET	2012 Mar 30
-			2:00	1:00	EEST	2012 Sep 21 1:00
-			2:00	-	EET
+			2:00 Palestine	EE%sT	2008 Aug 29 0:00
+			2:00	-	EET	2008 Sep
+			2:00 Palestine	EE%sT	2010
+			2:00	-	EET	2010 Mar 27 0:01
+			2:00 Palestine	EE%sT	2011 Aug  1
+			2:00	-	EET	2012
+			2:00 Palestine	EE%sT
 
 Zone	Asia/Hebron	2:20:23	-	LMT	1900 Oct
 			2:00	Zion	EET	1948 May 15
 			2:00 EgyptAsia	EE%sT	1967 Jun  5
 			2:00	Zion	I%sT	1996
 			2:00	Jordan	EE%sT	1999
-			2:00 Palestine	EE%sT	2008 Aug
-			2:00 	1:00	EEST	2008 Sep
-			2:00 Palestine	EE%sT	2011 Apr  1 12:01
-			2:00	1:00	EEST	2011 Aug  1
-			2:00	-	EET	2011 Aug 30
-			2:00	1:00	EEST	2011 Sep 30 3:00
-			2:00	-	EET	2012 Mar 30
-			2:00	1:00	EEST	2012 Sep 21 1:00
-			2:00	-	EET
+			2:00 Palestine	EE%sT
 
 # Paracel Is
 # no information
@@ -2421,6 +2444,13 @@
 # no information
 
 # Sri Lanka
+
+# From Paul Eggert (2013-02-21):
+# Milne says "Madras mean time use from May 1, 1898.  Prior to this Colombo
+# mean time, 5h. 4m. 21.9s. F., was used."  But 5:04:21.9 differs considerably
+# from Colombo's meridian 5:19:24, so for now ignore Milne and stick with
+# Shanks and Pottenger.
+
 # From Paul Eggert (1996-09-03):
 # "Sri Lanka advances clock by an hour to avoid blackout"
 # (www.virtual-pc.com/lankaweb/news/items/240596-2.html, 1996-05-24,
@@ -2720,6 +2750,12 @@
 
 # Vietnam
 
+# From Paul Eggert (2013-02-21):
+# Milne gives 7:16:56 for the meridian of Saigon in 1899, as being
+# used in Lower Laos, Cambodia, and Annam.  But this is quite a ways
+# from Saigon's location.  For now, ignore this and stick with Shanks
+# and Pottenger.
+
 # From Arthur David Olson (2008-03-18):
 # The English-language name of Vietnam's most populous city is "Ho Chi Min City";
 # we use Ho_Chi_Minh below to avoid a name of more than 14 characters.
@@ -2733,6 +2769,10 @@
 			7:00	-	ICT
 
 # Yemen
+
+# Milne says 2:59:54 was the meridian of the saluting battery at Aden,
+# and that Yemen was at 1:55:56, the meridian of the Hagia Sophia.
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Aden	3:00:48	-	LMT	1950
+Zone	Asia/Aden	2:59:54	-	LMT	1950
 			3:00	-	AST
diff --git a/jdk/make/sun/javazic/tzdata/australasia b/jdk/make/sun/javazic/tzdata/australasia
index 7f83448..db954a8 100644
--- a/jdk/make/sun/javazic/tzdata/australasia
+++ b/jdk/make/sun/javazic/tzdata/australasia
@@ -241,9 +241,26 @@
 # no times are set
 #
 # Macquarie
-# permanent occupation (scientific station) since 1948;
-# sealing and penguin oil station operated 1888/1917
-# like Australia/Hobart
+# Permanent occupation (scientific station) 1911-1915 and since 25 March 1948;
+# sealing and penguin oil station operated Nov 1899 to Apr 1919.  See the
+# Tasmania Parks & Wildlife Service history of sealing at Macquarie Island
+# <http://www.parks.tas.gov.au/index.aspx?base=1828>
+# <http://www.parks.tas.gov.au/index.aspx?base=1831>.
+# Guess that it was like Australia/Hobart while inhabited before 2010.
+#
+# From Steffen Thorsen (2010-03-10):
+# We got these changes from the Australian Antarctic Division:
+# - Macquarie Island will stay on UTC+11 for winter and therefore not
+# switch back from daylight savings time when other parts of Australia do
+# on 4 April.
+Zone Antarctica/Macquarie 0	-	zzz	1899 Nov
+			10:00	-	EST	1916 Oct 1 2:00
+			10:00	1:00	EST	1917 Feb
+			10:00	Aus	EST	1919 Apr
+			0	-	zzz	1948 Mar 25
+			10:00	Aus	EST	1967
+			10:00	AT	EST	2010 Apr 4 3:00
+			11:00	-	MIST	# Macquarie I Standard Time
 
 # Christmas
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -269,6 +286,9 @@
 			6:30	-	CCT	# Cocos Islands Time
 
 # Fiji
+
+# Milne gives 11:55:44 for Suva.
+
 # From Alexander Krivenyshev (2009-11-10):
 # According to Fiji Broadcasting Corporation,  Fiji plans to re-introduce DST
 # from November 29th 2009  to April 25th 2010.
@@ -362,7 +382,7 @@
 Rule	Fiji	2011	only	-	Mar	Sun>=1	3:00	0	-
 Rule	Fiji	2012	max	-	Jan	Sun>=18	3:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Pacific/Fiji	11:53:40 -	LMT	1915 Oct 26	# Suva
+Zone	Pacific/Fiji	11:55:44 -	LMT	1915 Oct 26	# Suva
 			12:00	Fiji	FJ%sT	# Fiji Time
 
 # French Polynesia
@@ -803,9 +823,9 @@
 
 # This data is by no means authoritative; if you think you know better,
 # go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
+# tz@iana.org for general use in the future).
 
-# From Paul Eggert (2006-03-22):
+# From Paul Eggert (2013-02-21):
 # A good source for time zone historical data outside the U.S. is
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
 # San Diego: ACS Publications, Inc. (2003).
@@ -823,6 +843,10 @@
 # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
 # I found in the UCLA library.
 #
+# For data circa 1899, a common source is:
+# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+# <http://www.jstor.org/stable/1774359>.
+#
 # A reliable and entertaining source about time zones is
 # Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
 #
diff --git a/jdk/make/sun/javazic/tzdata/europe b/jdk/make/sun/javazic/tzdata/europe
index 9a0d0b9..268504d 100644
--- a/jdk/make/sun/javazic/tzdata/europe
+++ b/jdk/make/sun/javazic/tzdata/europe
@@ -27,7 +27,7 @@
 
 # This data is by no means authoritative; if you think you know better,
 # go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
+# tz@iana.org for general use in the future).
 
 # From Paul Eggert (2006-03-22):
 # A good source for time zone historical data outside the U.S. is
@@ -53,6 +53,12 @@
 #	William Willett, The Waste of Daylight, 19th edition
 #	</a> (1914-03)
 #
+#	Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+#	<http://www.jstor.org/stable/1774359>.  He writes:
+#	"It is requested that corrections and additions to these tables
+#	may be sent to Mr. John Milne, Royal Geographical Society,
+#	Savile Row, London."  Nowadays please email them to tz@iana.org.
+#
 #	Brazil's Departamento Servico da Hora (DSH),
 #	<a href="http://pcdsh01.on.br/HISTHV.htm">
 #	History of Summer Time
@@ -689,6 +695,8 @@
 
 # Austria
 
+# Milne says Vienna time was 1:05:21.
+
 # From Paul Eggert (2006-03-22): Shanks & Pottenger give 1918-06-16 and
 # 1945-11-18, but the Austrian Federal Office of Metrology and
 # Surveying (BEV) gives 1918-09-16 and for Vienna gives the "alleged"
@@ -706,7 +714,7 @@
 Rule	Austria	1980	only	-	Apr	 6	0:00	1:00	S
 Rule	Austria	1980	only	-	Sep	28	0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Vienna	1:05:20 -	LMT	1893 Apr
+Zone	Europe/Vienna	1:05:21 -	LMT	1893 Apr
 			1:00	C-Eur	CE%sT	1920
 			1:00	Austria	CE%sT	1940 Apr  1 2:00s
 			1:00	C-Eur	CE%sT	1945 Apr  2 2:00s
@@ -1262,6 +1270,21 @@
 			1:00	Germany	CE%sT	1980
 			1:00	EU	CE%sT
 
+# From Tobias Conradi (2011-09-12):
+# Busingen <http://www.buesingen.de>, surrounded by the Swiss canton
+# Schaffhausen, did not start observing DST in 1980 as the rest of DE
+# (West Germany at that time) and DD (East Germany at that time) did.
+# DD merged into DE, the area is currently covered by code DE in ISO 3166-1,
+# which in turn is covered by the zone Europe/Berlin.
+#
+# Source for the time in Busingen 1980:
+# http://www.srf.ch/player/video?id=c012c029-03b7-4c2b-9164-aa5902cd58d3
+
+# From Arthur David Olson (2012-03-03):
+# Busingen and Zurich have shared clocks since 1970.
+
+Link	Europe/Zurich	Europe/Busingen
+
 # Georgia
 # Please see the "asia" file for Asia/Tbilisi.
 # Herodotus (Histories, IV.45) says Georgia north of the Phasis (now Rioni)
@@ -2066,6 +2089,70 @@
 
 # Russia
 
+# From Alexander Krivenyshev (2011-09-15):
+# Based on last Russian Government Decree # 725 on August 31, 2011
+# (Government document
+# <a href="http://www.government.ru/gov/results/16355/print/">
+# http://www.government.ru/gov/results/16355/print/
+# </a>
+# in Russian)
+# there are few corrections have to be made for some Russian time zones...
+# All updated Russian Time Zones were placed in table and translated to English
+# by WorldTimeZone.com at the link below:
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_russia36.htm">
+# http://www.worldtimezone.com/dst_news/dst_news_russia36.htm
+# </a>
+
+# From Sanjeev Gupta (2011-09-27):
+# Scans of [Decree #23 of January 8, 1992] are available at:
+# <a href="http://government.consultant.ru/page.aspx?1223966">
+# http://government.consultant.ru/page.aspx?1223966
+# They are in Cyrillic letters (presumably Russian).
+
+# From Arthur David Olson (2012-05-09):
+# Regarding the instant when clocks in time-zone-shifting parts of Russia
+# changed in September 2011:
+#
+# One source is
+# < a href="http://government.ru/gov/results/16355/>
+# http://government.ru/gov/results/16355/
+# </a>
+# which, according to translate.google.com, begins "Decree of August 31,
+# 2011 No 725" and contains no other dates or "effective date" information.
+#
+# Another source is
+# <a href="http://www.rg.ru/2011/09/06/chas-zona-dok.html">
+# http://www.rg.ru/2011/09/06/chas-zona-dok.html
+# </a>
+# which, according to translate.google.com, begins "Resolution of the
+# Government of the Russian Federation on August 31, 2011 N 725" and also
+# contains "Date first official publication: September 6, 2011 Posted on:
+# in the 'RG' - Federal Issue number 5573 September 6, 2011" but which
+# does not contain any "effective date" information.
+#
+# Another source is
+# <a href="http://en.wikipedia.org/wiki/Oymyakonsky_District#cite_note-RuTime-7">
+# http://en.wikipedia.org/wiki/Oymyakonsky_District#cite_note-RuTime-7
+# </a>
+# which, in note 8, contains "Resolution #725 of August 31, 2011...
+# Effective as of after 7 days following the day of the official publication"
+# but which does not contain any reference to September 6, 2011.
+#
+# The Wikipedia article refers to
+# <a href="http://base.consultant.ru/cons/cgi/online.cgi?req=doc;base=LAW;n=118896">
+# http://base.consultant.ru/cons/cgi/online.cgi?req=doc;base=LAW;n=118896
+# </a>
+# which seems to copy the text of the government.ru page.
+#
+# Tobias Conradi combines Wikipedia's
+# "as of after 7 days following the day of the official publication"
+# with www.rg.ru's "Date of first official publication: September 6, 2011" to get
+# September 13, 2011 as the cutover date (unusually, a Tuesday, as Tobias Conradi notes).
+#
+# None of the sources indicates a time of day for changing clocks.
+#
+# Go with 2011-09-13 0:00s.
+
 # From Paul Eggert (2006-03-22):
 # Except for Moscow after 1919-07-01, I invented the time zone abbreviations.
 # Moscow time zone abbreviations after 1919-07-01, and Moscow rules after 1991,
@@ -2293,14 +2380,32 @@
 # [parts of] Respublika Sakha (Yakutiya).
 
 # From Oscar van Vlijmen (2009-11-29):
-# The Sakha districts are: Bulunskij, Verkhoyanskij, Tomponskij, Ust'-Majskij,
-# Ust'-Yanskij.
+# The Sakha districts are: Bulunskij, Verkhoyanskij, ... Ust'-Yanskij.
 Zone Asia/Vladivostok	 8:47:44 -	LMT	1922 Nov 15
 			 9:00	-	VLAT	1930 Jun 21 # Vladivostok Time
 			10:00	Russia	VLA%sT	1991 Mar 31 2:00s
 			 9:00	Russia	VLA%sST	1992 Jan 19 2:00s
 			10:00	Russia	VLA%sT	2011 Mar 27 2:00s
 			11:00	-	VLAT
+
+# From Arthur David Olson (2012-05-09):
+# Tomponskij and Ust'-Majskij switched from Vladivostok time to Yakutsk time
+# in 2011.
+#
+# From Paul Eggert (2012-11-25):
+# Shanks and Pottenger (2003) has Khandyga on Yakutsk time.
+# Make a wild guess that it switched to Vladivostok time in 2004.
+# This transition is no doubt wrong, but we have no better info.
+#
+Zone Asia/Khandyga	 9:02:13 -	LMT	1919 Dec 15
+			 8:00	-	YAKT	1930 Jun 21 # Yakutsk Time
+			 9:00	Russia	YAK%sT	1991 Mar 31 2:00s
+			 8:00	Russia	YAK%sT	1992 Jan 19 2:00s
+			 9:00	Russia	YAK%sT	2004
+			10:00	Russia	VLA%sT	2011 Mar 27 2:00s
+			11:00	-	VLAT	2011 Sep 13 0:00s # Decree 725?
+			10:00	-	YAKT
+
 #
 # Sakhalinskaya oblast'.
 # The Zone name should be Yuzhno-Sakhalinsk, but that's too long.
@@ -2319,14 +2424,26 @@
 
 # From Oscar van Vlijmen (2009-11-29):
 # The Sakha districts are: Abyjskij, Allaikhovskij, Verkhhhnekolymskij, Momskij,
-# Nizhnekolymskij, Ojmyakonskij, Srednekolymskij.
+# Nizhnekolymskij, ... Srednekolymskij.
 Zone Asia/Magadan	10:03:12 -	LMT	1924 May  2
 			10:00	-	MAGT	1930 Jun 21 # Magadan Time
 			11:00	Russia	MAG%sT	1991 Mar 31 2:00s
 			10:00	Russia	MAG%sT	1992 Jan 19 2:00s
 			11:00	Russia	MAG%sT	2011 Mar 27 2:00s
 			12:00	-	MAGT
-#
+
+# From Arthur David Olson (2012-05-09):
+# Ojmyakonskij and the Kuril Islands switched from
+# Magadan time to Vladivostok time in 2011.
+Zone Asia/Ust-Nera	 9:32:54 -	LMT	1919 Dec 15
+			 8:00	-	YAKT	1930 Jun 21 # Yakutsk Time
+			 9:00	Russia	YAKT	1981 Apr  1
+			11:00	Russia	MAG%sT	1991 Mar 31 2:00s
+			10:00	Russia	MAG%sT	1992 Jan 19 2:00s
+			11:00	Russia	MAG%sT	2011 Mar 27 2:00s
+			12:00	-	MAGT	2011 Sep 13 0:00s # Decree 725?
+			11:00	-	VLAT
+
 # From Oscar van Vlijmen (2001-08-25): [This region consists of]
 # Kamchatskaya oblast', Koryakskij avtonomnyj okrug.
 #
diff --git a/jdk/make/sun/javazic/tzdata/northamerica b/jdk/make/sun/javazic/tzdata/northamerica
index c303326..858bf81 100644
--- a/jdk/make/sun/javazic/tzdata/northamerica
+++ b/jdk/make/sun/javazic/tzdata/northamerica
@@ -29,7 +29,7 @@
 
 # This data is by no means authoritative; if you think you know better,
 # go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
+# tz@iana.org for general use in the future).
 
 # From Paul Eggert (1999-03-22):
 # A reliable and entertaining source about time zones is
@@ -1042,6 +1042,9 @@
 #	William Willett, The Waste of Daylight, 19th edition
 #	</a> (1914-03)
 #
+#	Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+#	<http://www.jstor.org/stable/1774359>.
+#
 # See the `europe' file for Greenland.
 
 # Canada
@@ -2577,6 +2580,8 @@
 
 # Bahamas
 #
+# For 1899 Milne gives -5:09:29.5; round that.
+#
 # From Sue Williams (2006-12-07):
 # The Bahamas announced about a month ago that they plan to change their DST
 # rules to sync with the U.S. starting in 2007....
@@ -2586,11 +2591,14 @@
 Rule	Bahamas	1964	1975	-	Oct	lastSun	2:00	0	S
 Rule	Bahamas	1964	1975	-	Apr	lastSun	2:00	1:00	D
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Nassau	-5:09:24 -	LMT	1912 Mar 2
+Zone	America/Nassau	-5:09:30 -	LMT	1912 Mar 2
 			-5:00	Bahamas	E%sT	1976
 			-5:00	US	E%sT
 
 # Barbados
+
+# For 1899 Milne gives -3:58:29.2; round that.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Barb	1977	only	-	Jun	12	2:00	1:00	D
 Rule	Barb	1977	1978	-	Oct	Sun>=1	2:00	0	S
@@ -2598,8 +2606,8 @@
 Rule	Barb	1979	only	-	Sep	30	2:00	0	S
 Rule	Barb	1980	only	-	Sep	25	2:00	0	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Barbados	-3:58:28 -	LMT	1924		# Bridgetown
-			-3:58:28 -	BMT	1932	  # Bridgetown Mean Time
+Zone America/Barbados	-3:58:29 -	LMT	1924		# Bridgetown
+			-3:58:29 -	BMT	1932	  # Bridgetown Mean Time
 			-4:00	Barb	A%sT
 
 # Belize
@@ -2617,6 +2625,9 @@
 
 # Bermuda
 
+# For 1899 Milne gives -4:19:18.3 as the meridian of the clock tower,
+# Bermuda dockyard, Ireland I; round that.
+
 # From Dan Jones, reporting in The Royal Gazette (2006-06-26):
 
 # Next year, however, clocks in the US will go forward on the second Sunday
@@ -2626,7 +2637,7 @@
 # http://www.theroyalgazette.com/apps/pbcs.dll/article?AID=/20060529/NEWS/105290135
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Atlantic/Bermuda	-4:19:04 -	LMT	1930 Jan  1 2:00    # Hamilton
+Zone Atlantic/Bermuda	-4:19:18 -	LMT	1930 Jan  1 2:00    # Hamilton
 			-4:00	-	AST	1974 Apr 28 2:00
 			-4:00	Bahamas	A%sT	1976
 			-4:00	US	A%sT
@@ -2638,6 +2649,9 @@
 			-5:00	-	EST
 
 # Costa Rica
+
+# Milne gives -5:36:13.3 as San Jose mean time; round to nearest.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	CR	1979	1980	-	Feb	lastSun	0:00	1:00	D
 Rule	CR	1979	1980	-	Jun	Sun>=1	0:00	0	S
@@ -2648,14 +2662,19 @@
 Rule	CR	1992	only	-	Mar	15	0:00	0	S
 # There are too many San Joses elsewhere, so we'll use `Costa Rica'.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Costa_Rica	-5:36:20 -	LMT	1890		# San Jose
-			-5:36:20 -	SJMT	1921 Jan 15 # San Jose Mean Time
+Zone America/Costa_Rica	-5:36:13 -	LMT	1890		# San Jose
+			-5:36:13 -	SJMT	1921 Jan 15 # San Jose Mean Time
 			-6:00	CR	C%sT
 # Coco
 # no information; probably like America/Costa_Rica
 
 # Cuba
 
+# From Paul Eggert (2013-02-21):
+# Milne gives -5:28:50.45 for the observatory at Havana, -5:29:23.57
+# for the port, and -5:30 for meteorological observations.
+# For now, stick with Shanks & Pottenger.
+
 # From Arthur David Olson (1999-03-29):
 # The 1999-03-28 exhibition baseball game held in Havana, Cuba, between
 # the Cuban National Team and the Baltimore Orioles was carried live on
@@ -3004,24 +3023,21 @@
 # apparently using the same start and end date as USA/Canada.
 # So this means they have already changed their time.
 #
-# (Sources in French):
-# <a href="http://www.alterpresse.org/spip.php?article12510">
 # http://www.alterpresse.org/spip.php?article12510
-# </a>
-# <a href="http://radiovision2000haiti.net/home/?p=13253">
 # http://radiovision2000haiti.net/home/?p=13253
-# </a>
 #
-# Our coverage:
-# <a href="http://www.timeanddate.com/news/time/haiti-dst-2012.html">
-# http://www.timeanddate.com/news/time/haiti-dst-2012.html
-# </a>
-
 # From Arthur David Olson (2012-03-11):
 # The alterpresse.org source seems to show a US-style leap from 2:00 a.m. to
 # 3:00 a.m. rather than the traditional Haitian jump at midnight.
-# Assume a US-style fall back as well XXX.
-# Do not yet assume that the change carries forward past 2012 XXX.
+# Assume a US-style fall back as well.
+
+# From Steffen Thorsen (2013-03-10):
+# It appears that Haiti is observing DST this year as well, same rules
+# as US/Canada.  They did it last year as well, and it looks like they
+# are going to observe DST every year now...
+#
+# http://radiovision2000haiti.net/public/haiti-avis-changement-dheure-dimanche/
+# http://www.canalplushaiti.net/?p=6714
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Haiti	1983	only	-	May	8	0:00	1:00	D
@@ -3033,8 +3049,8 @@
 Rule	Haiti	1988	1997	-	Oct	lastSun	1:00s	0	S
 Rule	Haiti	2005	2006	-	Apr	Sun>=1	0:00	1:00	D
 Rule	Haiti	2005	2006	-	Oct	lastSun	0:00	0	S
-Rule	Haiti	2012	only	-	Mar	Sun>=8	2:00	1:00	D
-Rule	Haiti	2012	only	-	Nov	Sun>=1	2:00	0	S
+Rule	Haiti	2012	max	-	Mar	Sun>=8	2:00	1:00	D
+Rule	Haiti	2012	max	-	Nov	Sun>=1	2:00	0	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Port-au-Prince -4:49:20 -	LMT	1890
 			-4:49	-	PPMT	1917 Jan 24 12:00 # P-a-P MT
diff --git a/jdk/make/sun/javazic/tzdata/southamerica b/jdk/make/sun/javazic/tzdata/southamerica
index 0d6797e..d1865d3 100644
--- a/jdk/make/sun/javazic/tzdata/southamerica
+++ b/jdk/make/sun/javazic/tzdata/southamerica
@@ -27,13 +27,17 @@
 
 # This data is by no means authoritative; if you think you know better,
 # go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
+# tz@iana.org for general use in the future).
 
 # From Paul Eggert (2006-03-22):
 # A good source for time zone historical data outside the U.S. is
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
 # San Diego: ACS Publications, Inc. (2003).
 #
+# For data circa 1899, a common source is:
+# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+# <http://www.jstor.org/stable/1774359>.
+#
 # Gwillim Law writes that a good source
 # for recent time zone data is the International Air Transport
 # Association's Standard Schedules Information Manual (IATA SSIM),
@@ -404,21 +408,11 @@
 # <a/>
 # is the official page for the Province Government).
 #
-# There's also a note in only one of the major national papers (La Nación) at
-# <a href="http://www.lanacion.com.ar/nota.asp?nota_id=1107912">
+# There's also a note in only one of the major national papers ...
 # http://www.lanacion.com.ar/nota.asp?nota_id=1107912
-# </a>
 #
-# The press release says:
-#  (...) anunció que el próximo domingo a las 00:00 los puntanos deberán
-# atrasar una hora sus relojes.
-#
-# A partir de entonces, San Luis establecerá el huso horario propio de
-# la Provincia. De esta manera, durante el periodo del calendario anual
-# 2009, el cambio horario quedará comprendido entre las 00:00 del tercer
-# domingo de marzo y las 24:00 del segundo sábado de octubre.
-# Quick&dirty translation
-# (...) announced that next Sunday, at 00:00, Puntanos (the San Luis
+# The press release says [quick and dirty translation]:
+# ... announced that next Sunday, at 00:00, Puntanos (the San Luis
 # inhabitants) will have to turn back one hour their clocks
 #
 # Since then, San Luis will establish its own Province timezone. Thus,
@@ -480,6 +474,9 @@
 # rules...San Luis is still using "Western ARgentina Time" and it got
 # stuck on Summer daylight savings time even though the summer is over.
 
+# From Paul Eggert (2013-02-21):
+# Milne says Cordoba time was -4:16:48.2.  Round to the nearest second.
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 #
 # Buenos Aires (BA), Capital Federal (CF),
@@ -835,9 +832,9 @@
 
 # From Guilherme Bernardes Rodrigues (2011-10-07):
 # There is news in the media, however there is still no decree about it.
-# I just send a e-mail to Zulmira Brandão at
+# I just send a e-mail to Zulmira Brandao at
 # <a href="http://pcdsh01.on.br/">http://pcdsh01.on.br/</a> the
-# oficial agency about time in Brazil, and she confirmed that the old rule is
+# official agency about time in Brazil, and she confirmed that the old rule is
 # still in force.
 
 # From Guilherme Bernardes Rodrigues (2011-10-14)
@@ -1266,9 +1263,13 @@
 # b. Saturday, September 1, 2012, clocks should go forward 60 minutes; that is,
 # at 23:59:59, instead of passing to 0:00, the time should be adjusted to be
 # 01:00 on September 2.
-#
-# Note that...this is yet another "temporary" change that will be reevaluated
-# AGAIN in 2013.
+
+# From Steffen Thorsen (2013-02-15):
+# According to several news sources, Chile has extended DST this year,
+# they will end DST later and start DST earlier than planned.  They
+# hope to save energy.  The new end date is 2013-04-28 00:00 and new
+# start date is 2013-09-08 00:00....
+# http://www.gob.cl/informa/2013/02/15/gobierno-anuncia-fechas-de-cambio-de-hora-para-el-ano-2013.htm
 
 # NOTE: ChileAQ rules for Antarctic bases are stored separately in the
 # 'antarctica' file.
@@ -1311,10 +1312,8 @@
 Rule	Chile	2010	only	-	Apr	Sun>=1	3:00u	0	-
 Rule	Chile	2011	only	-	May	Sun>=2	3:00u	0	-
 Rule	Chile	2011	only	-	Aug	Sun>=16	4:00u	1:00	S
-Rule	Chile	2012	only	-	Apr	Sun>=23	3:00u	0	-
-Rule	Chile	2012	only	-	Sep	Sun>=2	4:00u	1:00	S
-Rule	Chile	2013	max	-	Mar	Sun>=9	3:00u	0	-
-Rule	Chile	2013	max	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	Chile	2012	max	-	Apr	Sun>=23	3:00u	0	-
+Rule	Chile	2012	max	-	Sep	Sun>=2	4:00u	1:00	S
 # IATA SSIM anomalies: (1992-02) says 1992-03-14;
 # (1996-09) says 1998-03-08.  Ignore these.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -1336,17 +1335,23 @@
 # San Felix, and Antarctic bases, are like America/Santiago.
 
 # Colombia
+
+# Milne gives 4:56:16.4 for Bogota time in 1899; round to nearest.  He writes,
+# "A variation of fifteen minutes in the public clocks of Bogota is not rare."
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	CO	1992	only	-	May	 3	0:00	1:00	S
 Rule	CO	1993	only	-	Apr	 4	0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Bogota	-4:56:20 -	LMT	1884 Mar 13
-			-4:56:20 -	BMT	1914 Nov 23 # Bogota Mean Time
+Zone	America/Bogota	-4:56:16 -	LMT	1884 Mar 13
+			-4:56:16 -	BMT	1914 Nov 23 # Bogota Mean Time
 			-5:00	CO	CO%sT	# Colombia Time
 # Malpelo, Providencia, San Andres
 # no information; probably like America/Bogota
 
 # Curacao
+
+# Milne gives 4:35:46.9 for Curacao mean time; round to nearest.
 #
 # From Paul Eggert (2006-03-22):
 # Shanks & Pottenger say that The Bottom and Philipsburg have been at
@@ -1363,7 +1368,7 @@
 # though, as far as we know.
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Curacao	-4:35:44 -	LMT	1912 Feb 12	# Willemstad
+Zone	America/Curacao	-4:35:47 -	LMT	1912 Feb 12	# Willemstad
 			-4:30	-	ANT	1965 # Netherlands Antilles Time
 			-4:00	-	AST
 
@@ -1377,6 +1382,8 @@
 
 # Ecuador
 #
+# Milne says the Sentral and South American Telegraph Company used -5:24:15.
+#
 # From Paul Eggert (2007-03-04):
 # Apparently Ecuador had a failed experiment with DST in 1992.
 # <http://midena.gov.ec/content/view/1261/208/> (2007-02-27) and
@@ -1582,7 +1589,16 @@
 # forward 60 minutes, in all the territory of the Paraguayan Republic.
 # ...
 Rule	Para	2010	max	-	Oct	Sun>=1	0:00	1:00	S
-Rule	Para	2010	max	-	Apr	Sun>=8	0:00	0	-
+Rule	Para	2010	2012	-	Apr	Sun>=8	0:00	0	-
+#
+# From Steffen Thorsen (2013-03-07):
+# Paraguay will end DST on 2013-03-24 00:00....
+# http://www.ande.gov.py/interna.php?id=1075
+#
+# From Carlos Raul Perasso (2013-03-15):
+# The change in Paraguay is now final.  Decree number 10780
+# http://www.presidencia.gov.py/uploads/pdf/presidencia-3b86ff4b691c79d4f5927ca964922ec74772ce857c02ca054a52a37b49afc7fb.pdf
+Rule	Para	2013	max	-	Mar	Sun>=22	0:00	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Asuncion	-3:50:40 -	LMT	1890
diff --git a/jdk/make/sun/javazic/tzdata/zone.tab b/jdk/make/sun/javazic/tzdata/zone.tab
index ef380cd..cbcdc07 100644
--- a/jdk/make/sun/javazic/tzdata/zone.tab
+++ b/jdk/make/sun/javazic/tzdata/zone.tab
@@ -65,7 +65,6 @@
 AQ	-7824+10654	Antarctica/Vostok	Vostok Station, Lake Vostok
 AQ	-6640+14001	Antarctica/DumontDUrville	Dumont-d'Urville Station, Terre Adelie
 AQ	-690022+0393524	Antarctica/Syowa	Syowa Station, E Ongul I
-AQ	-5430+15857	Antarctica/Macquarie	Macquarie Island Station, Macquarie Island
 AR	-3436-05827	America/Argentina/Buenos_Aires	Buenos Aires (BA, CF)
 AR	-3124-06411	America/Argentina/Cordoba	most locations (CB, CC, CN, ER, FM, MN, SE, SF)
 AR	-2447-06525	America/Argentina/Salta	(SA, LP, NQ, RN)
@@ -81,6 +80,7 @@
 AS	-1416-17042	Pacific/Pago_Pago
 AT	+4813+01620	Europe/Vienna
 AU	-3133+15905	Australia/Lord_Howe	Lord Howe Island
+AU	-5430+15857	Antarctica/Macquarie	Macquarie Island
 AU	-4253+14719	Australia/Hobart	Tasmania - most locations
 AU	-3956+14352	Australia/Currie	Tasmania - King Island
 AU	-3749+14458	Australia/Melbourne	Victoria
@@ -182,7 +182,8 @@
 CX	-1025+10543	Indian/Christmas
 CY	+3510+03322	Asia/Nicosia
 CZ	+5005+01426	Europe/Prague
-DE	+5230+01322	Europe/Berlin
+DE	+5230+01322	Europe/Berlin	most locations
+DE	+4742+00841	Europe/Busingen	Busingen
 DJ	+1136+04309	Africa/Djibouti
 DK	+5540+01235	Europe/Copenhagen
 DM	+1518-06124	America/Dominica
@@ -364,8 +365,10 @@
 RU	+5601+09250	Asia/Krasnoyarsk	Moscow+04 - Yenisei River
 RU	+5216+10420	Asia/Irkutsk	Moscow+05 - Lake Baikal
 RU	+6200+12940	Asia/Yakutsk	Moscow+06 - Lena River
+RU	+623923+1353314	Asia/Khandyga	Moscow+06 - Tomponsky, Ust-Maysky
 RU	+4310+13156	Asia/Vladivostok	Moscow+07 - Amur River
 RU	+4658+14242	Asia/Sakhalin	Moscow+07 - Sakhalin Island
+RU	+643337+1431336	Asia/Ust-Nera	Moscow+07 - Oymyakonsky
 RU	+5934+15048	Asia/Magadan	Moscow+08 - Magadan
 RU	+5301+15839	Asia/Kamchatka	Moscow+08 - Kamchatka
 RU	+6445+17729	Asia/Anadyr	Moscow+08 - Bering Sea
diff --git a/jdk/make/sun/nio/cs/Makefile b/jdk/make/sun/nio/cs/Makefile
index 73fe55f..3b45c77 100644
--- a/jdk/make/sun/nio/cs/Makefile
+++ b/jdk/make/sun/nio/cs/Makefile
@@ -87,9 +87,6 @@
 #
 # Extra rules to build character converters.
 
-SERVICE_DESCRIPTION = java.nio.charset.spi.CharsetProvider
-SERVICE_DESCRIPTION_PATH = META-INF/services/$(SERVICE_DESCRIPTION)
-
 GENCSDATASRC = $(BUILDDIR)/tools/CharsetMapping
 GENCSSRCDIR = $(BUILDDIR)/tools/src/build/tools/charsetmapping
 GENCSEXT = $(GENSRCDIR)/sun/nio/cs/ext
@@ -118,10 +115,6 @@
 		$(GENCSSRCDIR)/HKSCS.java
 	$(BOOT_JAVA_CMD) -jar $(CHARSETMAPPING_JARFILE) $(GENCSDATASRC) $(GENCSEXT) dbcs
 
-$(CLASSDESTDIR)/$(SERVICE_DESCRIPTION_PATH): \
-  $(SHARE_SRC)/classes/sun/nio/cs/ext/$(SERVICE_DESCRIPTION_PATH)
-	$(install-file)
-
 # no compression unless requested
 ifndef COMPRESS_JARS
   CREATE_JAR_OPTS_NOMANIFEST = cf0
@@ -129,10 +122,9 @@
   CREATE_JAR_OPTS_NOMANIFEST = cf
 endif
 
-$(CHARSETS_JAR): $(FILES_class) $(CLASSDESTDIR)/$(SERVICE_DESCRIPTION_PATH) $(FILES_DAT)
+$(CHARSETS_JAR): $(FILES_class) $(FILES_DAT)
 	$(BOOT_JAR_CMD) $(CREATE_JAR_OPTS_NOMANIFEST) $(CHARSETS_JAR) \
 	      -C $(CLASSDESTDIR) sun \
-	      -C $(CLASSDESTDIR) $(SERVICE_DESCRIPTION_PATH)  \
 	      $(BOOT_JAR_JFLAGS)
 	@$(java-vm-cleanup)
 
diff --git a/jdk/make/sun/org/mozilla/Makefile b/jdk/make/sun/org/mozilla/Makefile
deleted file mode 100644
index 0805da6..0000000
--- a/jdk/make/sun/org/mozilla/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-#
-# Makefile for building Mozilla JavaScript modules
-#
-
-BUILDDIR = ../../..
-PRODUCT = org
-include $(BUILDDIR)/common/Defs.gmk
-
-SUBDIRS = javascript
-include $(BUILDDIR)/common/Subdirs.gmk
-
-all build clean clobber::
-	$(SUBDIRS-loop)
-
diff --git a/jdk/make/sun/org/mozilla/javascript/Makefile b/jdk/make/sun/org/mozilla/javascript/Makefile
deleted file mode 100644
index f381b94..0000000
--- a/jdk/make/sun/org/mozilla/javascript/Makefile
+++ /dev/null
@@ -1,64 +0,0 @@
-#
-# Copyright (c) 2005, 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.
-#
-
-#
-# Makefile for building all of sun.org.mozilla.javascript.internal.*
-#
-
-BUILDDIR = ../../../..
-PACKAGE = sun.org.mozilla.javascript.internal
-PRODUCT = sun
-include $(BUILDDIR)/common/Defs.gmk
-
-AUTO_FILES_JAVA_DIRS = sun/org/mozilla/javascript/internal
-
-RESOURCEDIR = \
-	$(CLASSDESTDIR)/sun/org/mozilla/javascript/internal/resources
-	
-FILES_copy = \
-	$(RESOURCEDIR)/Messages.properties \
-	$(RESOURCEDIR)/Messages_fr.properties
-
-#
-# Rules
-#
-
-include $(BUILDDIR)/common/Classes.gmk
-
-all: classes copy-files
-
-#
-# Copy resource messages file for Rhino JavaScript interpreter
-#
-
-copy-files: $(FILES_copy)
-
-$(RESOURCEDIR)/%: $(CLOSED_SRC)/share/classes/sun/org/mozilla/javascript/internal/resources/%
-	$(install-file)
-
-.PHONY: copy-files
-
-clean clobber::
-	$(RM) -rf $(CLASSDESTDIR)/sun/org/mozilla/javascript
diff --git a/jdk/make/sun/security/Makefile b/jdk/make/sun/security/Makefile
index 9e9f8c5..0a1a7aa 100644
--- a/jdk/make/sun/security/Makefile
+++ b/jdk/make/sun/security/Makefile
@@ -38,12 +38,10 @@
 SUBDIRS_MAKEFLAGS += JAVAC_WARNINGS_FATAL=true
 include $(BUILDDIR)/common/Defs.gmk
 
-# build sun/security/jgss/wrapper on non-windows non-macosx platforms
+# build sun/security/jgss/wrapper on non-windows platforms
 JGSS_WRAPPER =
 ifneq ($(PLATFORM), windows)
-    ifneq ($(PLATFORM), macosx)
-    	JGSS_WRAPPER = jgss/wrapper
-    endif
+  JGSS_WRAPPER = jgss/wrapper
 endif
 
 # Build PKCS#11 on all platforms
diff --git a/jdk/make/sun/security/ec/Makefile b/jdk/make/sun/security/ec/Makefile
index f04ec0e..bceb031 100644
--- a/jdk/make/sun/security/ec/Makefile
+++ b/jdk/make/sun/security/ec/Makefile
@@ -125,15 +125,6 @@
 AUTO_FILES_JAVA_DIRS = $(PKGDIR)
 
 #
-# Exclude the sources that get built by ../other/Makefile
-#
-AUTO_JAVA_PRUNE = \
-    ECParameters.java \
-    ECPrivateKeyImpl.java \
-    ECPublicKeyImpl.java \
-    NamedCurve.java
-
-#
 # Some licensees do not get the native ECC sources, but we still need to
 # be able to build "all" for them.  Check here to see if the sources are
 # available.  If not, then skip them.
diff --git a/jdk/make/sun/security/other/Makefile b/jdk/make/sun/security/other/Makefile
index 5a3d9b0..cb62c98 100644
--- a/jdk/make/sun/security/other/Makefile
+++ b/jdk/make/sun/security/other/Makefile
@@ -50,15 +50,6 @@
     com/sun/net/ssl/internal/ssl
 
 #
-# EC classes used by the packages above
-#
-FILES_java += \
-    sun/security/ec/ECParameters.java \
-    sun/security/ec/ECPrivateKeyImpl.java \
-    sun/security/ec/ECPublicKeyImpl.java \
-    sun/security/ec/NamedCurve.java
-
-#
 # Rules
 #
 include $(BUILDDIR)/common/Classes.gmk
diff --git a/jdk/make/tools/src/build/tools/cldrconverter/CLDRConverter.java b/jdk/make/tools/src/build/tools/cldrconverter/CLDRConverter.java
index f1185f1..9cbf02a 100644
--- a/jdk/make/tools/src/build/tools/cldrconverter/CLDRConverter.java
+++ b/jdk/make/tools/src/build/tools/cldrconverter/CLDRConverter.java
@@ -34,6 +34,8 @@
 import java.util.*;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
 
 
 /**
@@ -234,6 +236,17 @@
         }
     }
 
+    /**
+     * Configure the parser to allow access to DTDs on the file system.
+     */
+    private static void enableFileAccess(SAXParser parser) throws SAXNotSupportedException {
+        try {
+            parser.setProperty("http://javax.xml.XMLConstants/property/accessExternalDTD", "file");
+        } catch (SAXNotRecognizedException ignore) {
+            // property requires >= JAXP 1.5
+        }
+    }
+
     private static List<Bundle> readBundleList() throws Exception {
         ResourceBundle.Control defCon = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_DEFAULT);
         List<Bundle> retList = new ArrayList<>();
@@ -279,6 +292,7 @@
         SAXParserFactory factory = SAXParserFactory.newInstance();
         factory.setValidating(true);
         SAXParser parser = factory.newSAXParser();
+        enableFileAccess(parser);
         LDMLParseHandler handler = new LDMLParseHandler(id);
         File file = new File(SOURCE_FILE_DIR + File.separator + id + ".xml");
         if (!file.exists()) {
@@ -314,6 +328,7 @@
         SAXParserFactory factorySuppl = SAXParserFactory.newInstance();
         factorySuppl.setValidating(true);
         SAXParser parserSuppl = factorySuppl.newSAXParser();
+        enableFileAccess(parserSuppl);
         handlerSuppl = new SupplementDataParseHandler();
         File fileSupply = new File(SPPL_SOURCE_FILE);
         parserSuppl.parse(fileSupply, handlerSuppl);
@@ -322,6 +337,7 @@
         SAXParserFactory numberingParser = SAXParserFactory.newInstance();
         numberingParser.setValidating(true);
         SAXParser parserNumbering = numberingParser.newSAXParser();
+        enableFileAccess(parserNumbering);
         handlerNumbering = new NumberingSystemsParseHandler();
         File fileNumbering = new File(NUMBERING_SOURCE_FILE);
         parserNumbering.parse(fileNumbering, handlerNumbering);
@@ -330,6 +346,7 @@
         SAXParserFactory metazonesParser = SAXParserFactory.newInstance();
         metazonesParser.setValidating(true);
         SAXParser parserMetaZones = metazonesParser.newSAXParser();
+        enableFileAccess(parserMetaZones);
         handlerMetaZones = new MetaZonesParseHandler();
         File fileMetaZones = new File(METAZONES_SOURCE_FILE);
         parserNumbering.parse(fileMetaZones, handlerMetaZones);
diff --git a/jdk/make/tools/src/build/tools/deps/refs.allowed b/jdk/make/tools/src/build/tools/deps/refs.allowed
index ef1bec7..7c15a04 100644
--- a/jdk/make/tools/src/build/tools/deps/refs.allowed
+++ b/jdk/make/tools/src/build/tools/deps/refs.allowed
@@ -30,7 +30,5 @@
 
 # Residual references to java.beans.
 # The RemoveMethods tool does not yet purge the constant pool.
-# Rhino is due to be replaced so not worth addressing this dependency now.
 #
-java.beans.PropertyChangeListener=java.util.logging.LogManager,sun.org.mozilla.javascript.internal.Context,compact1,compact2,compact3
-java.beans.PropertyChangeEvent=sun.org.mozilla.javascript.internal.Context,compact3
+java.beans.PropertyChangeListener=java.util.logging.LogManager,compact1,compact2,compact3
diff --git a/jdk/makefiles/CompileDemos.gmk b/jdk/makefiles/CompileDemos.gmk
index f61d940..0a093b5 100644
--- a/jdk/makefiles/CompileDemos.gmk
+++ b/jdk/makefiles/CompileDemos.gmk
@@ -1,3 +1,4 @@
+
 #
 # Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -432,20 +433,22 @@
 ##################################################################################################
 
 ifndef OPENJDK
-    DB_DEMO_ZIPFILE := $(wildcard $(JDK_TOPDIR)/src/closed/share/db/*demo*.zip)
+    DB_DEMO_ZIPFILE := $(wildcard $(JDK_TOPDIR)/src/closed/share/db/*.zip)
 
     $(JDK_OUTPUTDIR)/demo/_the.db.unzipped: $(DB_DEMO_ZIPFILE)
 	$(MKDIR) -p $(@D)
 	$(RM) -r $(JDK_OUTPUTDIR)/demo/db $(JDK_OUTPUTDIR)/demo/demo
 	$(CD) $(JDK_OUTPUTDIR)/demo && $(UNZIP) -q -o $<
-	$(MV) $(JDK_OUTPUTDIR)/demo/demo $(JDK_OUTPUTDIR)/demo/db
+	$(MV) $(JDK_OUTPUTDIR)/demo/db-derby-*-bin/demo $(JDK_OUTPUTDIR)/demo/db
+	$(CD) $(JDK_OUTPUTDIR)/demo && $(RM) -r db-derby-*-bin
 	$(TOUCH) $@
 
 #    Copy this after the unzip above to avoid race with directory creation and mv command.
      $(JDK_OUTPUTDIR)/demo/db/README-JDK-DEMOS.html: \
 		$(JDK_TOPDIR)/src/closed/share/db/README-JDK-DEMOS.html \
 		| $(JDK_OUTPUTDIR)/demo/_the.db.unzipped
-	$(call install-file)
+	$(MKDIR) -p $(@D)
+	$(CAT) $< | $(SED) "s/XXXX/$(shell cat $(JDK_TOPDIR)/src/closed/share/db/COPYRIGHTYEAR)/" > $@
 
      BUILD_DEMOS += $(JDK_OUTPUTDIR)/demo/_the.db.unzipped $(JDK_OUTPUTDIR)/demo/db/README-JDK-DEMOS.html
 endif
diff --git a/jdk/makefiles/CompileLaunchers.gmk b/jdk/makefiles/CompileLaunchers.gmk
index 7ecad95..0621f4c 100644
--- a/jdk/makefiles/CompileLaunchers.gmk
+++ b/jdk/makefiles/CompileLaunchers.gmk
@@ -472,6 +472,7 @@
 			  -D "JDK_FNAME=unpack200.exe" \
 			  -D "JDK_INTERNAL_NAME=unpack200" \
 			  -D "JDK_FTYPE=0x1L",\
+	        DEBUG_SYMBOLS:=true,\
 		MANIFEST:=$(JDK_TOPDIR)/src/windows/resource/unpack200_proto.exe.manifest))
 
 ifeq ($(OPENJDK_TARGET_OS),windows)
@@ -555,6 +556,7 @@
 			 $(call SET_SHARED_LIBRARY_NAME,$(LIBRARY_PREFIX)$(SHARED_LIBRARY_SUFFIX)), \
 		OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/jexec_obj,\
 		OUTPUT_DIR:=$(BUILD_JEXEC_DST_DIR),\
+		DEBUG_SYMBOLS:=true,\
 		PROGRAM:=jexec))
 
 	BUILD_LAUNCHERS += $(BUILD_JEXEC)
diff --git a/jdk/makefiles/CompileNativeLibraries.gmk b/jdk/makefiles/CompileNativeLibraries.gmk
index bb30367..1836cbb 100644
--- a/jdk/makefiles/CompileNativeLibraries.gmk
+++ b/jdk/makefiles/CompileNativeLibraries.gmk
@@ -2560,7 +2560,6 @@
 ##########################################################################################
 
 ifneq ($(OPENJDK_TARGET_OS), windows)
-ifneq ($(OPENJDK_TARGET_OS), macosx)
 $(eval $(call SetupNativeCompilation,BUILD_LIBJ2GSS,\
 		LIBRARY:=j2gss,\
                 OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\
@@ -2581,7 +2580,6 @@
 
 BUILD_LIBRARIES += $(BUILD_LIBJ2GSS)
 endif
-endif
 
 ##########################################################################################
 
diff --git a/jdk/makefiles/CopyFiles.gmk b/jdk/makefiles/CopyFiles.gmk
index ab3a360..272fd1f 100644
--- a/jdk/makefiles/CopyFiles.gmk
+++ b/jdk/makefiles/CopyFiles.gmk
@@ -458,24 +458,6 @@
 
 ifndef OPENJDK
 
-JS_RESOURCES_FILES := Messages.properties Messages_fr.properties
-JS_RESOURCES_SRC_DIR := $(JDK_TOPDIR)/src/closed/share/classes/sun/org/mozilla/javascript/internal/resources
-JS_RESOURCES_DST_DIR := $(JDK_OUTPUTDIR)/classes/sun/org/mozilla/javascript/internal/resources
-
-JS_RESOURCES_SRC := $(foreach F,$(JS_RESOURCES_FILES),$(JS_RESOURCES_SRC_DIR)/$(F))
-JS_RESOURCES_DST := $(foreach F,$(JS_RESOURCES_FILES),$(JS_RESOURCES_DST_DIR)/$(F))
-
-$(JS_RESOURCES_DST_DIR)/% : $(JS_RESOURCES_SRC_DIR)/%
-	$(call install-file)
-
-COPY_FILES += $(JS_RESOURCES_DST)
-
-endif
-
-##########################################################################################
-
-ifndef OPENJDK
-
 #
 # Solaris X11 Direct Graphics Access library
 #
diff --git a/jdk/makefiles/CopyIntoClasses.gmk b/jdk/makefiles/CopyIntoClasses.gmk
index 8b5a1cd..88ab3c4 100644
--- a/jdk/makefiles/CopyIntoClasses.gmk
+++ b/jdk/makefiles/CopyIntoClasses.gmk
@@ -172,10 +172,6 @@
 else
     ALL_META-INF_DIRS:=$(ALL_META-INF_DIRS_share)
 endif
-# Filter out META-INF dirs that shouldn't be included
-ifdef OPENJDK
-  ALL_META-INF_DIRS:=$(filter-out %com/sun/script/javascript/META-INF,$(ALL_META-INF_DIRS))
-endif
 
 ifndef OPENJDK
     ALL_META-INF_DIRS += $(JDK_TOPDIR)/src/closed/share/classes/sun/java2d/cmm/kcms/META-INF
diff --git a/jdk/makefiles/CreateJars.gmk b/jdk/makefiles/CreateJars.gmk
index 8127b05..3225a86 100644
--- a/jdk/makefiles/CreateJars.gmk
+++ b/jdk/makefiles/CreateJars.gmk
@@ -201,7 +201,6 @@
 	META-INF/services/com.sun.jdi.connect.spi.TransportService \
 	META-INF/services/com.sun.tools.attach.spi.AttachProvider \
 	META-INF/services/com.sun.tools.xjc.Plugin \
-	META-INF/services/java.nio.charset.spi.CharsetProvider \
 	META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor \
 	org/relaxng/datatype \
 	sun/awt/HKSCS.class \
@@ -217,19 +216,7 @@
 	sun/net/spi/nameservice/dns \
 	sun/nio/cs/ext \
 	sun/rmi/rmic \
-	sun/security/ec/ECDHKeyAgreement.class \
-	sun/security/ec/ECDSASignature.class \
-	sun/security/ec/ECDSASignature\$$$$Raw.class \
-	sun/security/ec/ECDSASignature\$$$$SHA1.class \
-	sun/security/ec/ECDSASignature\$$$$SHA224.class \
-	sun/security/ec/ECDSASignature\$$$$SHA256.class \
-	sun/security/ec/ECDSASignature\$$$$SHA384.class \
-	sun/security/ec/ECDSASignature\$$$$SHA512.class \
-	sun/security/ec/ECKeyFactory.class \
-	sun/security/ec/ECKeyPairGenerator.class \
-	sun/security/ec/SunEC\$$$$1.class \
-	sun/security/ec/SunEC.class \
-	sun/security/ec/SunECEntries.class \
+	sun/security/ec \
 	sun/security/internal \
 	sun/security/mscapi \
 	sun/security/pkcs11 \
@@ -428,8 +415,7 @@
 		SUFFIXES:=.class .dat,\
 		INCLUDES:=sun/nio/cs/ext,\
 		EXTRA_FILES := sun/awt/HKSCS.class \
-			       $(CHARSETS_EXTRA_FILES) \
-                               META-INF/services/java.nio.charset.spi.CharsetProvider, \
+			       $(CHARSETS_EXTRA_FILES), \
 		JAR:=$(IMAGES_OUTPUTDIR)/lib/charsets.jar, \
 		SKIP_METAINF := true, \
                 CHECK_COMPRESS_JAR:=true))
diff --git a/jdk/makefiles/GensrcSwing.gmk b/jdk/makefiles/GensrcSwing.gmk
index f5741ae..5350c14 100644
--- a/jdk/makefiles/GensrcSwing.gmk
+++ b/jdk/makefiles/GensrcSwing.gmk
@@ -68,10 +68,17 @@
 # Dummy variable so far, in the old build system it was false by default
 SWINGBEAN_DEBUG_FLAG = false
 # GenDocletBeanInfo is compiled in Tools.gmk and picks up from $(JDK_OUTPUTDIR)/btclasses
-$(JDK_OUTPUTDIR)/gensrc_no_srczip/_the.generated_beaninfo: $(BEANS_SRC) $(JDK_OUTPUTDIR)/gensrc_no_srczip/javax/swing/SwingBeanInfoBase.java $(JDK_OUTPUTDIR)/gensrc/sun/swing/BeanInfoUtils.java $(BUILD_TOOLS)
+# LocaleDataMetaInfo needs to be generated before running this to avoid confusing errors
+# in the build log.
+$(JDK_OUTPUTDIR)/gensrc_no_srczip/_the.generated_beaninfo: $(BEANS_SRC) \
+		$(JDK_OUTPUTDIR)/gensrc_no_srczip/javax/swing/SwingBeanInfoBase.java \
+		$(JDK_OUTPUTDIR)/gensrc/sun/swing/BeanInfoUtils.java $(BUILD_TOOLS) \
+		| $(GENSRC_LOCALEDATAMETAINFO)
 	$(ECHO) Generating beaninfo
 	$(MKDIR) -p $(JDK_OUTPUTDIR)/gensrc_no_srczip/javax/swing
-	$(JAVA) -Djava.awt.headless=true $(NEW_JAVADOC) -doclet GenDocletBeanInfo \
+	$(JAVA) -Djava.awt.headless=true $(NEW_JAVADOC) \
+	-sourcepath "$(JDK_TOPDIR)/src/share/classes$(PATH_SEP)$(JDK_OUTPUTDIR)/gensrc" \
+	 -doclet GenDocletBeanInfo \
 	-x $(SWINGBEAN_DEBUG_FLAG) -d $(JDK_OUTPUTDIR)/gensrc_no_srczip/javax/swing \
 	-t $(DOCLETSRC_DIR)/SwingBeanInfo.template -docletpath $(JDK_OUTPUTDIR)/btclasses \
 	-XDignore.symbol.file=true \
diff --git a/jdk/makefiles/Images.gmk b/jdk/makefiles/Images.gmk
index 2dde16f..a1db8b9 100644
--- a/jdk/makefiles/Images.gmk
+++ b/jdk/makefiles/Images.gmk
@@ -352,11 +352,8 @@
         JDK_MAN_PAGES += jvisualvm.1
     endif
 
-    ifndef OPENJDK
-        MAN_SRC_BASEDIR:=$(JDK_TOPDIR)/src/closed
-    else
-        MAN_SRC_BASEDIR:=$(JDK_TOPDIR)/src
-    endif
+    # This variable is potentially overridden in the closed makefile.
+    MAN_SRC_BASEDIR ?= $(JDK_TOPDIR)/src
 
     ifeq ($(OPENJDK_TARGET_OS), linux)
         MAN_SRC_DIR:=$(MAN_SRC_BASEDIR)/linux/doc
@@ -532,17 +529,22 @@
     $(IMAGES_OUTPUTDIR)/_unzip/%.unzipped: $(JDK_TOPDIR)/src/closed/share/db/%
 	$(ECHO) Unzipping $(patsubst $(SRC_ROOT)/%,%,$<)
 	$(MKDIR) -p $(JDK_IMAGE_DIR)/db
-	cd $(JDK_IMAGE_DIR)/db && $(UNZIP) -q -o $< -x index.html 2> /dev/null
+	cd $(JDK_IMAGE_DIR)/db && $(UNZIP) -q -o $< -x */index.html */KEYS */test/* *javadoc/* */docs/* */demo/* 2> /dev/null
+	cd $(JDK_IMAGE_DIR)/db && $(MV) db-derby-*-bin/* . && $(RM) -r db-derby-*-bin
 	$(MKDIR) -p $(@D)
 	$(TOUCH) $@
 
     $(JDK_IMAGE_DIR)/db/README-JDK.html: $(JDK_TOPDIR)/src/closed/share/db/README-JDK.html
 	$(ECHO) $(LOG_INFO) Copying '$(patsubst $(OUTPUT_ROOT)/%,%,$@)'
-	$(install-file)
+	$(CAT) $< | $(SED) "s/XXXX/$(shell cat $(JDK_TOPDIR)/src/closed/share/db/COPYRIGHTYEAR)/" > $@
+
+    $(JDK_IMAGE_DIR)/db/3RDPARTY: $(JDK_TOPDIR)/src/closed/share/db/3RDPARTY
+	$(ECHO) $(LOG_INFO) Copying '$(patsubst $(OUTPUT_ROOT)/%,%,$@)'
+	$(CAT) $< | $(SED) "s/XXXX/$(shell cat $(JDK_TOPDIR)/src/closed/share/db/COPYRIGHTYEAR)/" > $@
 
     JDK_DB_TARGETS := $(patsubst $(JDK_TOPDIR)/src/closed/share/db/%,$(IMAGES_OUTPUTDIR)/_unzip/%.unzipped,\
-			$(call not-containing,demo,$(wildcard $(JDK_TOPDIR)/src/closed/share/db/*.zip))) \
-		      $(JDK_IMAGE_DIR)/db/README-JDK.html
+			$(wildcard $(JDK_TOPDIR)/src/closed/share/db/*.zip)) \
+		      $(JDK_IMAGE_DIR)/db/README-JDK.html $(JDK_IMAGE_DIR)/db/3RDPARTY
 
 endif
 
diff --git a/jdk/makefiles/mapfiles/libawt/mapfile-vers b/jdk/makefiles/mapfiles/libawt/mapfile-vers
index 924a282..8af9d14 100644
--- a/jdk/makefiles/mapfiles/libawt/mapfile-vers
+++ b/jdk/makefiles/mapfiles/libawt/mapfile-vers
@@ -86,6 +86,7 @@
                 Java_sun_java2d_pipe_ShapeSpanIterator_setRule;
                 Java_sun_java2d_pipe_ShapeSpanIterator_skipDownTo;
 
+		Java_java_awt_Choice_initIDs;
 		Java_java_awt_Dimension_initIDs;
 		Java_java_awt_event_MouseEvent_initIDs;
 		Java_java_awt_image_DataBufferInt_initIDs;
diff --git a/jdk/makefiles/mapfiles/libawt/mapfile-vers-linux b/jdk/makefiles/mapfiles/libawt/mapfile-vers-linux
index 2514670..b0bfb1c 100644
--- a/jdk/makefiles/mapfiles/libawt/mapfile-vers-linux
+++ b/jdk/makefiles/mapfiles/libawt/mapfile-vers-linux
@@ -86,6 +86,7 @@
                 Java_sun_java2d_pipe_ShapeSpanIterator_setRule;
                 Java_sun_java2d_pipe_ShapeSpanIterator_skipDownTo;
 
+		Java_java_awt_Choice_initIDs;
 		Java_java_awt_Dimension_initIDs;
 		Java_java_awt_event_MouseEvent_initIDs;
 		Java_java_awt_image_DataBufferInt_initIDs;
diff --git a/jdk/makefiles/profile-rtjar-includes.txt b/jdk/makefiles/profile-rtjar-includes.txt
index a90af14..d740e01 100644
--- a/jdk/makefiles/profile-rtjar-includes.txt
+++ b/jdk/makefiles/profile-rtjar-includes.txt
@@ -57,6 +57,7 @@
     java/time \
     java/util \
     javax/net \
+    javax/script \
     javax/security \
     jdk \
     sun/invoke \
@@ -111,7 +112,6 @@
     com/sun/nio/sctp \
     com/sun/org/apache/xml/internal/security \
     com/sun/rowset \
-    com/sun/script \
     com/sun/security/auth \
     com/sun/security/jgss \
     com/sun/security/ntlm \
@@ -125,7 +125,6 @@
     javax/lang/model \
     javax/management \
     javax/naming \
-    javax/script \
     javax/security/auth/kerberos \
     javax/security/sasl \
     javax/smartcardio \
@@ -140,7 +139,6 @@
     sun/net/www/protocol/http/ntlm \
     sun/net/www/protocol/http/spnego \
     sun/nio/ch/sctp \
-    sun/org/mozilla \
     sun/security/acl \
     sun/security/jgss \
     sun/security/krb5 \
@@ -161,10 +159,6 @@
     javax/management/remote/rmi/_RMIServerImpl_Tie.class \
     javax/management/remote/rmi/_RMIServer_Stub.class
 
-PROFILE_3_INCLUDE_METAINF_SERVICES := \
-    META-INF/services/javax.script.ScriptEngineFactory 
-
-
 FULL_JRE_RTJAR_INCLUDE_PACKAGES := \
     com/oracle \
     com/sun/accessibility/internal/resources \
diff --git a/jdk/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java
index dff48a4..f5cb0d5 100644
--- a/jdk/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java
+++ b/jdk/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -56,6 +56,8 @@
     void initializeImpl() {
         super.initializeImpl();
         final Scrollbar target = getTarget();
+        setLineIncrement(target.getUnitIncrement());
+        setPageIncrement(target.getBlockIncrement());
         setValues(target.getValue(), target.getVisibleAmount(),
                   target.getMinimum(), target.getMaximum());
 
diff --git a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java
index cad6e43..6ff3530 100644
--- a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java
+++ b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java
@@ -53,7 +53,12 @@
     private Clipboard clipboard;
     private MouseInfoPeer mouseInfoPeer;
 
-    public LWToolkit() {
+    /**
+     * Dynamic Layout Resize client code setting.
+     */
+    private volatile boolean dynamicLayoutSetting = true;
+
+    protected LWToolkit() {
     }
 
     /*
@@ -561,4 +566,37 @@
             ((LWWindowPeer)w.getPeer()).ungrab(false);
         }
     }
+
+    @Override
+    protected final Object lazilyLoadDesktopProperty(final String name) {
+        if (name.equals("awt.dynamicLayoutSupported")) {
+            return isDynamicLayoutSupported();
+        }
+        return super.lazilyLoadDesktopProperty(name);
+    }
+
+    @Override
+    public final void setDynamicLayout(final boolean dynamic) {
+        dynamicLayoutSetting = dynamic;
+    }
+
+    @Override
+    protected final boolean isDynamicLayoutSet() {
+        return dynamicLayoutSetting;
+    }
+
+    @Override
+    public final boolean isDynamicLayoutActive() {
+        // "Live resizing" is active by default and user's data is ignored.
+        return isDynamicLayoutSupported();
+    }
+
+    /**
+     * Returns true if dynamic layout of Containers on resize is supported by
+     * the underlying operating system and/or window manager.
+     */
+    protected final boolean isDynamicLayoutSupported() {
+        // "Live resizing" is supported by default.
+        return true;
+    }
 }
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java
index 791182c..e198024 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java
@@ -35,6 +35,7 @@
 
 import javax.print.*;
 import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.HashPrintRequestAttributeSet;
 
 import sun.java2d.*;
 import sun.print.*;
@@ -96,6 +97,14 @@
             return false;
         }
 
+        if (attributes == null) {
+            attributes = new HashPrintRequestAttributeSet();
+        }
+
+        if (getPrintService() instanceof StreamPrintService) {
+            return super.printDialog(attributes);
+        }
+
         return jobSetup(getPageable(), checkAllowedToPrintToFile());
     }
 
@@ -130,6 +139,10 @@
             return page;
         }
 
+        if (getPrintService() instanceof StreamPrintService) {
+            return super.pageDialog(page);
+        }
+
         PageFormat pageClone = (PageFormat) page.clone();
         boolean doIt = pageSetup(pageClone, null);
         return doIt ? pageClone : page;
diff --git a/jdk/src/macosx/native/sun/awt/AWTSurfaceLayers.m b/jdk/src/macosx/native/sun/awt/AWTSurfaceLayers.m
index 6e9fbbc..d12908c 100644
--- a/jdk/src/macosx/native/sun/awt/AWTSurfaceLayers.m
+++ b/jdk/src/macosx/native/sun/awt/AWTSurfaceLayers.m
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
 #import "LWCToolkit.h"
 
 #import <JavaNativeFoundation/JavaNativeFoundation.h>
+#import <QuartzCore/CATransaction.h>
 
 @implementation AWTSurfaceLayers
 
@@ -74,14 +75,12 @@
 }
 
 - (void) setBounds:(CGRect)rect {
-    layer.anchorPoint = CGPointMake(0, 0);
-
     // translates values to the coordinate system of the "root" layer
-    CGFloat newY = windowLayer.bounds.size.height - rect.origin.y - rect.size.height;
-    CGRect newRect = CGRectMake(rect.origin.x, newY, rect.size.width, rect.size.height);
-
-    layer.frame = newRect;
-
+    rect.origin.y = windowLayer.bounds.size.height - rect.origin.y - rect.size.height;
+    [CATransaction begin];
+    [CATransaction setDisableActions:YES];
+    layer.frame = rect;
+    [CATransaction commit];
     [AWTSurfaceLayers repaintLayersRecursively:layer];
 }
 
diff --git a/jdk/src/macosx/native/sun/java2d/opengl/CGLLayer.m b/jdk/src/macosx/native/sun/java2d/opengl/CGLLayer.m
index e0074eb..f300ea4 100644
--- a/jdk/src/macosx/native/sun/java2d/opengl/CGLLayer.m
+++ b/jdk/src/macosx/native/sun/java2d/opengl/CGLLayer.m
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -64,11 +64,13 @@
 
     //Disable CALayer's default animation
     NSMutableDictionary * actions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
+                                    [NSNull null], @"anchorPoint",
                                     [NSNull null], @"bounds",
                                     [NSNull null], @"contents",
                                     [NSNull null], @"contentsScale",
                                     [NSNull null], @"onOrderIn",
                                     [NSNull null], @"onOrderOut",
+                                    [NSNull null], @"position",
                                     [NSNull null], @"sublayers",
                                     nil];
     self.actions = actions;
diff --git a/jdk/src/share/bin/java.c b/jdk/src/share/bin/java.c
index f08a52a..73c5326 100644
--- a/jdk/src/share/bin/java.c
+++ b/jdk/src/share/bin/java.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -149,12 +149,15 @@
 static void FreeKnownVMs();
 static jboolean IsWildCardEnabled();
 
-#define ARG_CHECK(n, f, a) if (n < 1) { \
-    JLI_ReportErrorMessage(f, a); \
-    printUsage = JNI_TRUE; \
-    *pret = 1; \
-    return JNI_TRUE; \
-}
+#define ARG_CHECK(AC_arg_count, AC_failure_message, AC_questionable_arg) \
+    do { \
+        if (AC_arg_count < 1) { \
+            JLI_ReportErrorMessage(AC_failure_message, AC_questionable_arg); \
+            printUsage = JNI_TRUE; \
+            *pret = 1; \
+            return JNI_TRUE; \
+        } \
+    } while (JNI_FALSE)
 
 /*
  * Running Java code in primordial thread caused many problems. We will
@@ -310,29 +313,37 @@
  * mainThread.isAlive() to work as expected.
  */
 #define LEAVE() \
-    if ((*vm)->DetachCurrentThread(vm) != 0) { \
-        JLI_ReportErrorMessage(JVM_ERROR2); \
-        ret = 1; \
-    } \
-    (*vm)->DestroyJavaVM(vm); \
-    return ret \
+    do { \
+        if ((*vm)->DetachCurrentThread(vm) != JNI_OK) { \
+            JLI_ReportErrorMessage(JVM_ERROR2); \
+            ret = 1; \
+        } \
+        if (JNI_TRUE) { \
+            (*vm)->DestroyJavaVM(vm); \
+            return ret; \
+        } \
+    } while (JNI_FALSE)
 
-#define CHECK_EXCEPTION_NULL_LEAVE(e) \
-    if ((*env)->ExceptionOccurred(env)) { \
-        JLI_ReportExceptionDescription(env); \
-        LEAVE(); \
-    } \
-    if ((e) == NULL) { \
-        JLI_ReportErrorMessage(JNI_ERROR); \
-        LEAVE(); \
-    }
+#define CHECK_EXCEPTION_NULL_LEAVE(CENL_exception) \
+    do { \
+        if ((*env)->ExceptionOccurred(env)) { \
+            JLI_ReportExceptionDescription(env); \
+            LEAVE(); \
+        } \
+        if ((CENL_exception) == NULL) { \
+            JLI_ReportErrorMessage(JNI_ERROR); \
+            LEAVE(); \
+        } \
+    } while (JNI_FALSE)
 
-#define CHECK_EXCEPTION_LEAVE(rv) \
-    if ((*env)->ExceptionOccurred(env)) { \
-        JLI_ReportExceptionDescription(env); \
-        ret = (rv); \
-        LEAVE(); \
-    }
+#define CHECK_EXCEPTION_LEAVE(CEL_return_value) \
+    do { \
+        if ((*env)->ExceptionOccurred(env)) { \
+            JLI_ReportExceptionDescription(env); \
+            ret = (CEL_return_value); \
+            LEAVE(); \
+        } \
+    } while (JNI_FALSE)
 
 int JNICALL
 JavaMain(void * _args)
@@ -434,7 +445,7 @@
      * consistent in the UI we need to track and report the application main class.
      */
     appClass = GetApplicationClass(env);
-    NULL_CHECK(appClass);
+    NULL_CHECK_RETURN_VALUE(appClass, -1);
     /*
      * PostJVMInit uses the class name as the application name for GUI purposes,
      * for example, on OSX this sets the application name in the menu bar for
diff --git a/jdk/src/share/bin/java.h b/jdk/src/share/bin/java.h
index ad1a1ff..83e97e6 100644
--- a/jdk/src/share/bin/java.h
+++ b/jdk/src/share/bin/java.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -242,14 +242,18 @@
     InvocationFunctions ifn;
 } JavaMainArgs;
 
-#define NULL_CHECK0(e) if ((e) == 0) { \
-    JLI_ReportErrorMessage(JNI_ERROR); \
-    return 0; \
-  }
+#define NULL_CHECK_RETURN_VALUE(NCRV_check_pointer, NCRV_return_value) \
+    do { \
+        if ((NCRV_check_pointer) == NULL) { \
+            JLI_ReportErrorMessage(JNI_ERROR); \
+            return NCRV_return_value; \
+        } \
+    } while (JNI_FALSE)
 
-#define NULL_CHECK(e) if ((e) == 0) { \
-    JLI_ReportErrorMessage(JNI_ERROR); \
-    return; \
-  }
+#define NULL_CHECK0(NC0_check_pointer) \
+    NULL_CHECK_RETURN_VALUE(NC0_check_pointer, 0)
+
+#define NULL_CHECK(NC_check_pointer) \
+    NULL_CHECK_RETURN_VALUE(NC_check_pointer, )
 
 #endif /* _JAVA_H_ */
diff --git a/jdk/src/share/bin/wildcard.c b/jdk/src/share/bin/wildcard.c
index f8f6644..96dac73 100644
--- a/jdk/src/share/bin/wildcard.c
+++ b/jdk/src/share/bin/wildcard.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -136,8 +136,10 @@
 {
     WildcardIterator it = NEW_(WildcardIterator);
     HANDLE handle = FindFirstFile(wildcard, &find_data);
-    if (handle == INVALID_HANDLE_VALUE)
+    if (handle == INVALID_HANDLE_VALUE) {
+        JLI_MemFree(it);
         return NULL;
+    }
     it->handle = handle;
     it->firstFile = find_data.cFileName;
     return it;
diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java
index d281e11..0fbdefb 100644
--- a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java
@@ -790,16 +790,12 @@
     }
 
     private void startPass(int pass) {
-        if (updateListeners == null) {
+        if (updateListeners == null || !imageMetadata.interlaceFlag) {
             return;
         }
 
-        int y = 0;
-        int yStep = 1;
-        if (imageMetadata.interlaceFlag) {
-            y = interlaceOffset[interlacePass];
-            yStep = interlaceIncrement[interlacePass];
-        }
+        int y = interlaceOffset[interlacePass];
+        int yStep = interlaceIncrement[interlacePass];
 
         int[] vals = ReaderUtil.
             computeUpdatedPixels(sourceRegion,
diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java
index a6033c9..19a7a08 100644
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java
@@ -99,6 +99,7 @@
         return this == def.canon;
     }
 
+    @Override
     public int compareTo(Attribute that) {
         return this.def.compareTo(that.def);
     }
@@ -212,20 +213,20 @@
     // Metadata.
     //
     // We define metadata using similar layouts
-    // for all five kinds of metadata attributes.
+    // for all five kinds of metadata attributes and 2 type metadata attributes
     //
     // Regular annotations are a counted list of [RSHNH[RUH(1)]][...]
     //   pack.method.attribute.RuntimeVisibleAnnotations=[NH[(1)]][RSHNH[RUH(1)]][TB...]
     //
     // Parameter annotations are a counted list of regular annotations.
-    //   pack.method.attribute.RuntimeVisibleParameterAnnotations=[NH[(1)]][NH[(1)]][RSHNH[RUH(1)]][TB...]
+    //   pack.method.attribute.RuntimeVisibleParameterAnnotations=[NB[(1)]][NH[(1)]][RSHNH[RUH(1)]][TB...]
     //
     // RuntimeInvisible annotations are defined similarly...
     // Non-method annotations are defined similarly...
     //
     // Annotation are a simple tagged value [TB...]
     //   pack.attribute.method.AnnotationDefault=[TB...]
-    //
+
     static {
         String mdLayouts[] = {
             Attribute.normalizeLayoutString
@@ -238,6 +239,9 @@
              +"\n  # annotations :="
              +"\n  [ NH[(1)] ]     # forward call to annotation"
              +"\n  "
+            ),
+            Attribute.normalizeLayoutString
+             (""
              +"\n  # annotation :="
              +"\n  [RSH"
              +"\n    NH[RUH (1)]   # forward call to value"
@@ -259,24 +263,67 @@
              +"\n    ()[] ]"
              )
         };
+        /*
+         * RuntimeVisibleTypeAnnotation and RuntimeInvisibleTypeAnnotatation are
+         * similar to RuntimeVisibleAnnotation and RuntimeInvisibleAnnotation,
+         * a type-annotation union  and a type-path structure precedes the
+         * annotation structure
+         */
+        String typeLayouts[] = {
+            Attribute.normalizeLayoutString
+            (""
+             +"\n # type-annotations :="
+             +"\n  [ NH[(1)(2)(3)] ]     # forward call to type-annotations"
+            ),
+            Attribute.normalizeLayoutString
+            ( ""
+             +"\n  # type-annotation :="
+             +"\n  [TB"
+             +"\n    (0-1) [B] # {CLASS, METHOD}_TYPE_PARAMETER"
+             +"\n    (16) [FH] # CLASS_EXTENDS"
+             +"\n    (17-18) [BB] # {CLASS, METHOD}_TYPE_PARAMETER_BOUND"
+             +"\n    (19-21) [] # FIELD, METHOD_RETURN, METHOD_RECEIVER"
+             +"\n    (22) [B] # METHOD_FORMAL_PARAMETER"
+             +"\n    (23) [H] # THROWS"
+             +"\n    (64-65) [NH[PHOHH]] # LOCAL_VARIABLE, RESOURCE_VARIABLE"
+             +"\n    (66) [H] # EXCEPTION_PARAMETER"
+             +"\n    (67-70) [PH] # INSTANCEOF, NEW, {CONSTRUCTOR, METHOD}_REFERENCE_RECEIVER"
+             +"\n    (71-75) [PHB] # CAST, {CONSTRUCTOR,METHOD}_INVOCATION_TYPE_ARGUMENT, {CONSTRUCTOR, METHOD}_REFERENCE_TYPE_ARGUMENT"
+             +"\n    ()[] ]"
+            ),
+            Attribute.normalizeLayoutString
+            (""
+             +"\n # type-path"
+             +"\n [ NB[BB] ]"
+            )
+        };
         Map<Layout, Attribute> sd = standardDefs;
-        String defaultLayout     = mdLayouts[2];
-        String annotationsLayout = mdLayouts[1] + mdLayouts[2];
+        String defaultLayout     = mdLayouts[3];
+        String annotationsLayout = mdLayouts[1] + mdLayouts[2] + mdLayouts[3];
         String paramsLayout      = mdLayouts[0] + annotationsLayout;
+        String typesLayout       = typeLayouts[0] + typeLayouts[1] +
+                                   typeLayouts[2] + mdLayouts[2] + mdLayouts[3];
+
         for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
-            if (ctype == ATTR_CONTEXT_CODE)  continue;
-            define(sd, ctype,
-                   "RuntimeVisibleAnnotations",   annotationsLayout);
-            define(sd, ctype,
-                   "RuntimeInvisibleAnnotations", annotationsLayout);
-            if (ctype == ATTR_CONTEXT_METHOD) {
+            if (ctype != ATTR_CONTEXT_CODE) {
                 define(sd, ctype,
-                       "RuntimeVisibleParameterAnnotations",   paramsLayout);
+                       "RuntimeVisibleAnnotations",   annotationsLayout);
                 define(sd, ctype,
-                       "RuntimeInvisibleParameterAnnotations", paramsLayout);
-                define(sd, ctype,
-                       "AnnotationDefault", defaultLayout);
+                       "RuntimeInvisibleAnnotations",  annotationsLayout);
+
+                if (ctype == ATTR_CONTEXT_METHOD) {
+                    define(sd, ctype,
+                           "RuntimeVisibleParameterAnnotations",   paramsLayout);
+                    define(sd, ctype,
+                           "RuntimeInvisibleParameterAnnotations", paramsLayout);
+                    define(sd, ctype,
+                           "AnnotationDefault", defaultLayout);
+                }
             }
+            define(sd, ctype,
+                   "RuntimeVisibleTypeAnnotations", typesLayout);
+            define(sd, ctype,
+                   "RuntimeInvisibleTypeAnnotations", typesLayout);
         }
     }
 
@@ -529,6 +576,7 @@
             return canon.addContent(bytes, null);
         }
 
+        @Override
         public boolean equals(Object x) {
             return ( x != null) && ( x.getClass() == Layout.class ) &&
                     equals((Layout)x);
@@ -538,11 +586,13 @@
                 && this.layout.equals(that.layout)
                 && this.ctype == that.ctype;
         }
+        @Override
         public int hashCode() {
             return (((17 + name.hashCode())
                     * 37 + layout.hashCode())
                     * 37 + ctype);
         }
+        @Override
         public int compareTo(Layout that) {
             int r;
             r = this.name.compareTo(that.name);
@@ -551,6 +601,7 @@
             if (r != 0)  return r;
             return this.ctype - that.ctype;
         }
+        @Override
         public String toString() {
             String str = contextName(ctype)+"."+name+"["+layout+"]";
             // If -ea, print out more informative strings!
@@ -698,11 +749,14 @@
         // References (to a local cpMap) are embedded in the bytes.
         def.parse(holder, bytes, 0, bytes.length,
             new ValueStream() {
+                @Override
                 public void putInt(int bandIndex, int value) {
                 }
+                @Override
                 public void putRef(int bandIndex, Entry ref) {
                     refs.add(ref);
                 }
+                @Override
                 public int encodeBCI(int bci) {
                     return bci;
                 }
@@ -716,6 +770,7 @@
         return def.unparse(in, out);
     }
 
+    @Override
     public String toString() {
         return def
             +"{"+(bytes == null ? -1 : size())+"}"
@@ -1309,7 +1364,7 @@
                 }
                 out.putRef(bandIndex, globalRef);
                 break;
-            default: assert(false); continue;
+            default: assert(false);
             }
         }
         return pos;
@@ -1416,8 +1471,7 @@
                 int localRef;
                 if (globalRef != null) {
                     // It's a one-element array, really an lvalue.
-                    fixups[0] = Fixups.add(fixups[0], null, out.size(),
-                                           Fixups.U2_FORMAT, globalRef);
+                    fixups[0] = Fixups.addRefWithLoc(fixups[0], out.size(), globalRef);
                     localRef = 0; // placeholder for fixups
                 } else {
                     localRef = 0; // fixed null value
diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java
index 322e2c3..1152aa7 100644
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java
@@ -48,6 +48,7 @@
 import java.util.Map;
 import java.util.jar.Pack200;
 import static com.sun.java.util.jar.pack.Constants.*;
+import java.util.LinkedList;
 
 /**
  * Define the structure and ordering of "bands" in a packed file.
@@ -495,6 +496,7 @@
         }
 
         protected int lengthForDebug = -1;  // DEBUG ONLY
+        @Override
         public String toString() {  // DEBUG ONLY
             int length = (lengthForDebug != -1 ? lengthForDebug : length());
             String str = name;
@@ -518,20 +520,24 @@
             super(name, regularCoding);
         }
 
+        @Override
         public int capacity() {
             return values == null ? -1 : values.length;
         }
 
         /** Declare predicted or needed capacity. */
+        @Override
         protected void setCapacity(int cap) {
             assert(length <= cap);
             if (cap == -1) { values = null; return; }
             values = realloc(values, cap);
         }
 
+        @Override
         public int length() {
             return length;
         }
+        @Override
         protected int valuesRemainingForDebug() {
             return length - valuesDisbursed;
         }
@@ -583,6 +589,7 @@
             return true;
         }
 
+        @Override
         protected void chooseBandCodings() throws IOException {
             boolean canVary = canVaryCoding();
             if (!canVary || !shouldVaryCoding()) {
@@ -653,6 +660,7 @@
             }
         }
 
+        @Override
         protected long computeOutputSize() {
             outputSize = getCodingChooser().computeByteSize(bandCoding,
                                                             values, 0, length);
@@ -668,6 +676,7 @@
             return regularCoding.setD(0).getLength(X);
         }
 
+        @Override
         protected void writeDataTo(OutputStream out) throws IOException {
             if (length == 0)  return;  // nothing to write
             long len0 = 0;
@@ -691,6 +700,7 @@
             if (optDumpBands)  dumpBand();
         }
 
+        @Override
         protected void readDataFrom(InputStream in) throws IOException {
             length = valuesExpected();
             if (length == 0)  return;  // nothing to read
@@ -707,7 +717,6 @@
                 if (XB < 0) {
                     // Do not consume this value.  No alternate coding.
                     in.reset();
-                    XB = _meta_default;
                     bandCoding = regularCoding;
                     metaCoding = noMetaCoding;
                 } else if (XB == _meta_default) {
@@ -733,6 +742,7 @@
             if (optDumpBands)  dumpBand();
         }
 
+        @Override
         public void doneDisbursing() {
             super.doneDisbursing();
             values = null;  // for GC
@@ -763,7 +773,10 @@
         /** Disburse one value. */
         protected int getValue() {
             assert(phase() == DISBURSE_PHASE);
-            assert(valuesDisbursed < length);
+            // when debugging return a zero if lengths are zero
+            if (optDebugBands && length == 0 && valuesDisbursed == length)
+                return 0;
+            assert(valuesDisbursed <= length);
             return values[valuesDisbursed++];
         }
 
@@ -784,9 +797,11 @@
             super(name, BYTE1);
         }
 
+        @Override
         public int capacity() {
             return bytes == null ? -1 : Integer.MAX_VALUE;
         }
+        @Override
         protected void setCapacity(int cap) {
             assert(bytes == null);  // do this just once
             bytes = new ByteArrayOutputStream(cap);
@@ -796,27 +811,32 @@
             bytes = null;
         }
 
+        @Override
         public int length() {
             return bytes == null ? -1 : bytes.size();
         }
         public void reset() {
             bytes.reset();
         }
+        @Override
         protected int valuesRemainingForDebug() {
             return (bytes == null) ? -1 : ((ByteArrayInputStream)in).available();
         }
 
+        @Override
         protected void chooseBandCodings() throws IOException {
             // No-op.
             assert(decodeEscapeValue(regularCoding.min(), regularCoding) < 0);
             assert(decodeEscapeValue(regularCoding.max(), regularCoding) < 0);
         }
 
+        @Override
         protected long computeOutputSize() {
             // do not cache
             return bytes.size();
         }
 
+        @Override
         public void writeDataTo(OutputStream out) throws IOException {
             if (length() == 0)  return;
             bytes.writeTo(out);
@@ -834,6 +854,7 @@
             }
         }
 
+        @Override
         public void readDataFrom(InputStream in) throws IOException {
             int vex = valuesExpected();
             if (vex == 0)  return;
@@ -852,11 +873,13 @@
             if (optDumpBands)  dumpBand();
         }
 
+        @Override
         public void readyToDisburse() {
             in = new ByteArrayInputStream(bytes.toByteArray());
             super.readyToDisburse();
         }
 
+        @Override
         public void doneDisbursing() {
             super.doneDisbursing();
             if (optDumpBands
@@ -882,11 +905,13 @@
                 // Tap the stream.
                 bytesForDump = new ByteArrayOutputStream();
                 this.in = new FilterInputStream(in) {
+                    @Override
                     public int read() throws IOException {
                         int ch = in.read();
                         if (ch >= 0)  bytesForDump.write(ch);
                         return ch;
                     }
+                    @Override
                     public int read(byte b[], int off, int len) throws IOException {
                         int nr = in.read(b, off, len);
                         if (nr >= 0)  bytesForDump.write(b, off, nr);
@@ -917,6 +942,7 @@
             assert(b == (b & 0xFF));
             collectorStream().write(b);
         }
+        @Override
         public String toString() {
             return "byte "+super.toString();
         }
@@ -1184,6 +1210,7 @@
             super(name, regularCoding);
         }
 
+        @Override
         public Band init() {
             super.init();
             // This is all just to keep the asserts happy:
@@ -1259,12 +1286,17 @@
         int bandCount() { return bandCount; }
 
         private int cap = -1;
+        @Override
         public int capacity() { return cap; }
+        @Override
         public void setCapacity(int cap) { this.cap = cap; }
 
+        @Override
         public int length() { return 0; }
+        @Override
         public int valuesRemainingForDebug() { return 0; }
 
+        @Override
         protected void chooseBandCodings() throws IOException {
             // coding decision pass
             for (int i = 0; i < bandCount; i++) {
@@ -1273,6 +1305,7 @@
             }
         }
 
+        @Override
         protected long computeOutputSize() {
             // coding decision pass
             long sum = 0;
@@ -1286,6 +1319,7 @@
             return sum;
         }
 
+        @Override
         protected void writeDataTo(OutputStream out) throws IOException {
             long preCount = 0;
             if (outputCounter != null)  preCount = outputCounter.getCount();
@@ -1303,6 +1337,7 @@
             }
         }
 
+        @Override
         protected void readDataFrom(InputStream in) throws IOException {
             assert(false);  // not called?
             for (int i = 0; i < bandCount; i++) {
@@ -1314,6 +1349,7 @@
             }
         }
 
+        @Override
         public String toString() {
             return "{"+bandCount()+" bands: "+super.toString()+"}";
         }
@@ -1335,14 +1371,17 @@
         public long getCount() { return count; }
         public void setCount(long c) { count = c; }
 
+        @Override
         public void write(int b) throws IOException {
             count++;
             if (out != null)  out.write(b);
         }
+        @Override
         public void write(byte b[], int off, int len) throws IOException {
             count += len;
             if (out != null)  out.write(b, off, len);
         }
+        @Override
         public String toString() {
             return String.valueOf(getCount());
         }
@@ -1490,6 +1529,7 @@
     CPRefBand field_ConstantValue_KQ = field_attr_bands.newCPRefBand("field_ConstantValue_KQ", CONSTANT_FieldSpecific);
     CPRefBand field_Signature_RS = field_attr_bands.newCPRefBand("field_Signature_RS", CONSTANT_Signature);
     MultiBand field_metadata_bands = field_attr_bands.newMultiBand("(field_metadata_bands)", UNSIGNED5);
+    MultiBand field_type_metadata_bands = field_attr_bands.newMultiBand("(field_type_metadata_bands)", UNSIGNED5);
 
     CPRefBand method_descr = class_bands.newCPRefBand("method_descr", MDELTA5, CONSTANT_NameandType);
     MultiBand method_attr_bands = class_bands.newMultiBand("(method_attr_bands)", UNSIGNED5);
@@ -1507,6 +1547,7 @@
     IntBand  method_MethodParameters_NB = method_attr_bands.newIntBand("method_MethodParameters_NB", BYTE1);
     CPRefBand method_MethodParameters_name_RUN = method_attr_bands.newCPRefBand("method_MethodParameters_name_RUN", UNSIGNED5, CONSTANT_Utf8, NULL_IS_OK);
     IntBand   method_MethodParameters_flag_FH = method_attr_bands.newIntBand("method_MethodParameters_flag_FH");
+    MultiBand method_type_metadata_bands = method_attr_bands.newMultiBand("(method_type_metadata_bands)", UNSIGNED5);
 
     MultiBand class_attr_bands = class_bands.newMultiBand("(class_attr_bands)", UNSIGNED5);
     IntBand class_flags_hi = class_attr_bands.newIntBand("class_flags_hi");
@@ -1527,6 +1568,7 @@
     CPRefBand class_InnerClasses_name_RUN = class_attr_bands.newCPRefBand("class_InnerClasses_name_RUN", UNSIGNED5, CONSTANT_Utf8, NULL_IS_OK);
     IntBand class_ClassFile_version_minor_H = class_attr_bands.newIntBand("class_ClassFile_version_minor_H");
     IntBand class_ClassFile_version_major_H = class_attr_bands.newIntBand("class_ClassFile_version_major_H");
+    MultiBand class_type_metadata_bands = class_attr_bands.newMultiBand("(class_type_metadata_bands)", UNSIGNED5);
 
     MultiBand code_bands = class_bands.newMultiBand("(code_bands)", UNSIGNED5);
     ByteBand  code_headers = code_bands.newByteBand("code_headers"); //BYTE1
@@ -1545,7 +1587,7 @@
     IntBand   code_attr_indexes = code_attr_bands.newIntBand("code_attr_indexes");
     IntBand   code_attr_calls = code_attr_bands.newIntBand("code_attr_calls");
 
-    MultiBand stackmap_bands = code_attr_bands.newMultiBand("StackMapTable_bands", UNSIGNED5);
+    MultiBand stackmap_bands = code_attr_bands.newMultiBand("(StackMapTable_bands)", UNSIGNED5);
     IntBand   code_StackMapTable_N = stackmap_bands.newIntBand("code_StackMapTable_N");
     IntBand   code_StackMapTable_frame_T = stackmap_bands.newIntBand("code_StackMapTable_frame_T",BYTE1);
     IntBand   code_StackMapTable_local_N = stackmap_bands.newIntBand("code_StackMapTable_local_N");
@@ -1573,6 +1615,7 @@
     CPRefBand code_LocalVariableTypeTable_name_RU = code_attr_bands.newCPRefBand("code_LocalVariableTypeTable_name_RU", CONSTANT_Utf8);
     CPRefBand code_LocalVariableTypeTable_type_RS = code_attr_bands.newCPRefBand("code_LocalVariableTypeTable_type_RS", CONSTANT_Signature);
     IntBand   code_LocalVariableTypeTable_slot = code_attr_bands.newIntBand("code_LocalVariableTypeTable_slot");
+    MultiBand code_type_metadata_bands = code_attr_bands.newMultiBand("(code_type_metadata_bands)", UNSIGNED5);
 
     // bands for bytecodes
     MultiBand bc_bands = all_bands.newMultiBand("(byte_codes)", UNSIGNED5);
@@ -1678,6 +1721,14 @@
         metadataBands[ATTR_CONTEXT_FIELD] = field_metadata_bands;
         metadataBands[ATTR_CONTEXT_METHOD] = method_metadata_bands;
     }
+    // Table of bands which contains type_metadata (TypeAnnotations)
+    protected MultiBand[] typeMetadataBands = new MultiBand[ATTR_CONTEXT_LIMIT];
+    {
+        typeMetadataBands[ATTR_CONTEXT_CLASS] = class_type_metadata_bands;
+        typeMetadataBands[ATTR_CONTEXT_FIELD] = field_type_metadata_bands;
+        typeMetadataBands[ATTR_CONTEXT_METHOD] = method_type_metadata_bands;
+        typeMetadataBands[ATTR_CONTEXT_CODE]   = code_type_metadata_bands;
+    }
 
     // Attribute layouts.
     public static final int ADH_CONTEXT_MASK   = 0x3;  // (ad_hdr & ADH_CONTEXT_MASK)
@@ -1793,36 +1844,47 @@
 
         for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
             MultiBand xxx_metadata_bands = metadataBands[ctype];
-            if (xxx_metadata_bands == null)
-                continue;  // no code attrs
+            if (ctype != ATTR_CONTEXT_CODE) {
+                // These arguments cause the bands to be built
+                // automatically for this complicated layout:
+                predefineAttribute(X_ATTR_RuntimeVisibleAnnotations,
+                                   ATTR_CONTEXT_NAME[ctype]+"_RVA_",
+                                   xxx_metadata_bands,
+                                   Attribute.lookup(null, ctype,
+                                                    "RuntimeVisibleAnnotations"));
+                predefineAttribute(X_ATTR_RuntimeInvisibleAnnotations,
+                                   ATTR_CONTEXT_NAME[ctype]+"_RIA_",
+                                   xxx_metadata_bands,
+                                   Attribute.lookup(null, ctype,
+                                                    "RuntimeInvisibleAnnotations"));
 
-            // These arguments cause the bands to be built
-            // automatically for this complicated layout:
-            predefineAttribute(X_ATTR_RuntimeVisibleAnnotations,
-                               ATTR_CONTEXT_NAME[ctype]+"_RVA_",
-                               xxx_metadata_bands,
-                               Attribute.lookup(null, ctype,
-                                                "RuntimeVisibleAnnotations"));
-            predefineAttribute(X_ATTR_RuntimeInvisibleAnnotations,
-                               ATTR_CONTEXT_NAME[ctype]+"_RIA_",
-                               xxx_metadata_bands,
-                               Attribute.lookup(null, ctype,
-                                                "RuntimeInvisibleAnnotations"));
-            if (ctype != ATTR_CONTEXT_METHOD)
-                continue;
-
-            predefineAttribute(METHOD_ATTR_RuntimeVisibleParameterAnnotations,
-                               "method_RVPA_", xxx_metadata_bands,
-                               Attribute.lookup(null, ctype,
-                                                "RuntimeVisibleParameterAnnotations"));
-            predefineAttribute(METHOD_ATTR_RuntimeInvisibleParameterAnnotations,
-                               "method_RIPA_", xxx_metadata_bands,
-                               Attribute.lookup(null, ctype,
-                                                "RuntimeInvisibleParameterAnnotations"));
-            predefineAttribute(METHOD_ATTR_AnnotationDefault,
-                               "method_AD_", xxx_metadata_bands,
-                               Attribute.lookup(null, ctype,
-                                                "AnnotationDefault"));
+                if (ctype == ATTR_CONTEXT_METHOD) {
+                    predefineAttribute(METHOD_ATTR_RuntimeVisibleParameterAnnotations,
+                                       "method_RVPA_", xxx_metadata_bands,
+                                       Attribute.lookup(null, ctype,
+                                       "RuntimeVisibleParameterAnnotations"));
+                    predefineAttribute(METHOD_ATTR_RuntimeInvisibleParameterAnnotations,
+                                       "method_RIPA_", xxx_metadata_bands,
+                                       Attribute.lookup(null, ctype,
+                                       "RuntimeInvisibleParameterAnnotations"));
+                    predefineAttribute(METHOD_ATTR_AnnotationDefault,
+                                       "method_AD_", xxx_metadata_bands,
+                                       Attribute.lookup(null, ctype,
+                                       "AnnotationDefault"));
+                }
+            }
+            // All contexts have these
+            MultiBand xxx_type_metadata_bands = typeMetadataBands[ctype];
+            predefineAttribute(X_ATTR_RuntimeVisibleTypeAnnotations,
+                    ATTR_CONTEXT_NAME[ctype] + "_RVTA_",
+                    xxx_type_metadata_bands,
+                    Attribute.lookup(null, ctype,
+                    "RuntimeVisibleTypeAnnotations"));
+            predefineAttribute(X_ATTR_RuntimeInvisibleTypeAnnotations,
+                    ATTR_CONTEXT_NAME[ctype] + "_RITA_",
+                    xxx_type_metadata_bands,
+                    Attribute.lookup(null, ctype,
+                    "RuntimeInvisibleTypeAnnotations"));
         }
 
 
@@ -2053,8 +2115,7 @@
         Attribute.Layout def = attr.layout();
         int ctype = def.ctype();
         return predefineAttribute(index, ctype,
-                                  makeNewAttributeBands(bandPrefix, def,
-                                                        addHere),
+                                  makeNewAttributeBands(bandPrefix, def, addHere),
                                   def.name(), def.layout());
     }
 
@@ -2539,7 +2600,7 @@
         return true;
     }
 
-    // DEBUG ONLY:  Validate next input band.
+    // DEBUG ONLY:  Validate next input band, ensure bands are read in sequence
     private boolean assertReadyToReadFrom(Band b, InputStream in) throws IOException {
         Band p = prevForAssertMap.get(b);
         // Any previous band must be done reading before this one starts.
@@ -2547,30 +2608,19 @@
             Utils.log.warning("Previous band not done reading.");
             Utils.log.info("    Previous band: "+p);
             Utils.log.info("        Next band: "+b);
-            Thread.dumpStack();
             assert(verbose > 0);  // die unless verbose is true
         }
         String name = b.name;
         if (optDebugBands && !name.startsWith("(")) {
+            assert(bandSequenceList != null);
             // Verify synchronization between reader & writer:
-            StringBuilder buf = new StringBuilder();
-            int ch;
-            while ((ch = in.read()) > 0)
-                buf.append((char)ch);
-            String inName = buf.toString();
+            String inName = bandSequenceList.removeFirst();
+            // System.out.println("Reading: " + name);
             if (!inName.equals(name)) {
-                StringBuilder sb = new StringBuilder();
-                sb.append("Expected "+name+" but read: ");
-                inName += (char)ch;
-                while (inName.length() < 10) {
-                    inName += (char) in.read();
-                }
-                for (int i = 0; i < inName.length(); i++) {
-                    sb.append(inName.charAt(i));
-                }
-                Utils.log.warning(sb.toString());
+                Utils.log.warning("Expected " + name + " but read: " + inName);
                 return false;
             }
+            Utils.log.info("Read band in sequence: " + name);
         }
         return true;
     }
@@ -2590,7 +2640,12 @@
         return true;
     }
 
-    // DEBUG ONLY:  Maybe write a debugging cookie to next output band.
+    /*
+     * DEBUG ONLY:  write the bands to a list and read back the list in order,
+     * this works perfectly if we use the java packer and unpacker, typically
+     * this will work with --repack or if they are in the same jvm instance.
+     */
+    static LinkedList<String> bandSequenceList = null;
     private boolean assertReadyToWriteTo(Band b, OutputStream out) throws IOException {
         Band p = prevForAssertMap.get(b);
         // Any previous band must be done writing before this one starts.
@@ -2598,16 +2653,15 @@
             Utils.log.warning("Previous band not done writing.");
             Utils.log.info("    Previous band: "+p);
             Utils.log.info("        Next band: "+b);
-            Thread.dumpStack();
             assert(verbose > 0);  // die unless verbose is true
         }
         String name = b.name;
         if (optDebugBands && !name.startsWith("(")) {
+            if (bandSequenceList == null)
+                bandSequenceList = new LinkedList<>();
             // Verify synchronization between reader & writer:
-            for (int j = 0; j < name.length(); j++) {
-                out.write((byte)name.charAt(j));
-            }
-            out.write((byte)0);
+            bandSequenceList.add(name);
+            // System.out.println("Writing: " + b);
         }
         return true;
     }
@@ -2664,7 +2718,7 @@
                     buf.append("\\r");
                 } else {
                     String str = "000"+Integer.toHexString(ch);
-                    buf.append("\\u"+str.substring(str.length()-4));
+                    buf.append("\\u").append(str.substring(str.length()-4));
                 }
             }
             ps.println(buf);
diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Code.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Code.java
index e84cdaa..423b0d7 100644
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Code.java
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Code.java
@@ -146,7 +146,6 @@
         int verbose = getPackage().verbose;
         if (verbose > 2)
             System.out.println("Reference scan "+this);
-        Class cls = thisClass();
         refs.addAll(Arrays.asList(handler_class));
         if (fixups != null) {
             fixups.visitRefs(refs);
diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java
index 1ede291..4f64ef4 100644
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java
@@ -785,53 +785,55 @@
         return new String(sig);
     }
 
-    static private int skipClassNameChars(String sig, int i) {
-        int len = sig.length();
-        for (; i < len; i++) {
-            char ch = sig.charAt(i);
-            if (ch <= ' ')  break;
-            if (ch >= ';' && ch <= '@')  break;
-        }
-        return i;
+    static private int skipTo(char semi, String sig, int i) {
+        i = sig.indexOf(semi, i);
+        return (i >= 0) ? i : sig.length();
     }
 
     static String[] structureSignature(String sig) {
-        sig = sig.intern();
-
-        int formLen = 0;
-        int nparts = 1;
-        for (int i = 0; i < sig.length(); i++) {
-            char ch = sig.charAt(i);
-            formLen++;
-            if (ch == 'L') {
-                nparts++;
-                int i2 = skipClassNameChars(sig, i+1);
-                i = i2-1;  // keep the semicolon in the form
-                int i3 = sig.indexOf('<', i+1);
-                if (i3 > 0 && i3 < i2)
-                    i = i3-1;
-            }
-        }
-        char[] form = new char[formLen];
-        if (nparts == 1) {
+        int firstl = sig.indexOf('L');
+        if (firstl < 0) {
             String[] parts = { sig };
             return parts;
         }
-        String[] parts = new String[nparts];
-        int j = 0;
-        int k = 1;
-        for (int i = 0; i < sig.length(); i++) {
-            char ch = sig.charAt(i);
-            form[j++] = ch;
-            if (ch == 'L') {
-                int i2 = skipClassNameChars(sig, i+1);
-                parts[k++] = sig.substring(i+1, i2);
-                i = i2;
-                --i;  // keep the semicolon in the form
+        // Segment the string like sig.split("L\\([^;<]*\\)").
+        // N.B.: Previous version of this code did a more complex match,
+        // to next ch < ' ' or ch in [';'..'@'].  The only important
+        // characters are ';' and '<', since they are part of the
+        // signature syntax.
+        // Examples:
+        //   "(Ljava/lang/Object;IJLLoo;)V" => {"(L;IJL;)V", "java/lang/Object", "Loo"}
+        //   "Ljava/util/List<Ljava/lang/String;>;" => {"L<L;>;", "java/util/List", "java/lang/String"}
+        char[] form = null;
+        String[] parts = null;
+        for (int pass = 0; pass <= 1; pass++) {
+            // pass 0 is a sizing pass, pass 1 packs the arrays
+            int formPtr = 0;
+            int partPtr = 1;
+            int nextsemi = 0, nextangl = 0;  // next ';' or '<', or zero, or sigLen
+            int lastj = 0;
+            for (int i = firstl + 1, j; i > 0; i = sig.indexOf('L', j) + 1) {
+                // sig[i-1] is 'L', while sig[j] will be the first ';' or '<' after it
+                // each part is in sig[i .. j-1]
+                if (nextsemi < i)  nextsemi = skipTo(';', sig, i);
+                if (nextangl < i)  nextangl = skipTo('<', sig, i);
+                j = (nextsemi < nextangl ? nextsemi : nextangl);
+                if (pass != 0) {
+                    sig.getChars(lastj, i, form, formPtr);
+                    parts[partPtr] = sig.substring(i, j);
+                }
+                formPtr += (i - lastj);
+                partPtr += 1;
+                lastj = j;
             }
+            if (pass != 0) {
+                sig.getChars(lastj, sig.length(), form, formPtr);
+                break;
+            }
+            formPtr += (sig.length() - lastj);
+            form = new char[formPtr];
+            parts = new String[partPtr];
         }
-        assert(j == formLen);
-        assert(k == parts.length);
         parts[0] = new String(form);
         //assert(flattenSignature(parts).equals(sig));
         return parts;
diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java
index 5059bc0..1599170 100644
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java
@@ -45,6 +45,7 @@
         1.5 to 1.5.X 49,0
         1.6 to 1.5.x 50,0
         1.7 to 1.6.x 51,0
+        1.8 to 1.7.x 52,0
     */
 
     public final static Package.Version JAVA_MIN_CLASS_VERSION =
@@ -161,7 +162,9 @@
         METHOD_ATTR_RuntimeInvisibleParameterAnnotations = 24,
         CLASS_ATTR_ClassFile_version = 24,
         METHOD_ATTR_AnnotationDefault = 25,
-        METHOD_ATTR_MethodParameters = 26,
+        METHOD_ATTR_MethodParameters = 26,           // JDK8
+        X_ATTR_RuntimeVisibleTypeAnnotations = 27,   // JDK8
+        X_ATTR_RuntimeInvisibleTypeAnnotations = 28, // JDK8
         CODE_ATTR_StackMapTable = 0,  // new in Java 6
         CODE_ATTR_LineNumberTable = 1,
         CODE_ATTR_LocalVariableTable = 2,
diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Fixups.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Fixups.java
index 0c99351..647d1db 100644
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Fixups.java
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Fixups.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.Objects;
 
 /**
  * Collection of relocatable constant pool references.
@@ -77,8 +78,9 @@
 
     private static final int MINBIGSIZE = 1;
     // cleverly share empty bigDescs:
-    private static int[] noBigDescs = {MINBIGSIZE};
+    private static final int[] noBigDescs = {MINBIGSIZE};
 
+    @Override
     public int size() {
         return size;
     }
@@ -105,6 +107,7 @@
         }
     }
 
+    @Override
     public void clear() {
         if (bytes != null) {
             // Clean the bytes:
@@ -141,16 +144,16 @@
         assert(old.equals(new ArrayList<>(this)));
     }
 
-    static final int LOC_SHIFT = 1;
-    static final int FMT_MASK = 0x1;
-    static final byte UNUSED_BYTE = 0;
-    static final byte OVERFLOW_BYTE = -1;
+    private static final int LOC_SHIFT = 1;
+    private static final int FMT_MASK = 0x1;
+    private static final byte UNUSED_BYTE = 0;
+    private static final byte OVERFLOW_BYTE = -1;
     // fill pointer of bigDescs array is in element [0]
-    static final int BIGSIZE = 0;
+    private static final int BIGSIZE = 0;
 
     // Format values:
-    public static final int U2_FORMAT = 0;
-    public static final int U1_FORMAT = 1;
+    private static final int U2_FORMAT = 0;
+    private static final int U1_FORMAT = 1;
 
     // Special values for the static methods.
     private static final int SPECIAL_LOC = 0;
@@ -232,6 +235,14 @@
         }
     }
 
+    void addU1(int pc, Entry ref) {
+        add(pc, U1_FORMAT, ref);
+    }
+
+    void addU2(int pc, Entry ref) {
+        add(pc, U2_FORMAT, ref);
+    }
+
     /** Simple and necessary tuple to present each fixup. */
     public static
     class Fixup implements Comparable<Fixup> {
@@ -248,15 +259,25 @@
         public int location() { return descLoc(desc); }
         public int format() { return descFmt(desc); }
         public Entry entry() { return entry; }
+        @Override
         public int compareTo(Fixup that) {
             // Ordering depends only on location.
             return this.location() - that.location();
         }
+        @Override
         public boolean equals(Object x) {
             if (!(x instanceof Fixup))  return false;
             Fixup that = (Fixup) x;
             return this.desc == that.desc && this.entry == that.entry;
         }
+        @Override
+        public int hashCode() {
+            int hash = 7;
+            hash = 59 * hash + this.desc;
+            hash = 59 * hash + Objects.hashCode(this.entry);
+            return hash;
+        }
+        @Override
         public String toString() {
             return "@"+location()+(format()==U1_FORMAT?".1":"")+"="+entry;
         }
@@ -267,8 +288,11 @@
         int index = 0;               // index into entries
         int bigIndex = BIGSIZE+1;    // index into bigDescs
         int next = head;             // desc pointing to next fixup
+        @Override
         public boolean hasNext() { return index < size; }
+        @Override
         public void remove() { throw new UnsupportedOperationException(); }
+        @Override
         public Fixup next() {
             int thisIndex = index;
             return new Fixup(nextDesc(), entries[thisIndex]);
@@ -293,17 +317,20 @@
         }
     }
 
+    @Override
     public Iterator<Fixup> iterator() {
         return new Itr();
     }
     public void add(int location, int format, Entry entry) {
         addDesc(makeDesc(location, format), entry);
     }
+    @Override
     public boolean add(Fixup f) {
         addDesc(f.desc, f.entry);
         return true;
     }
 
+    @Override
     public boolean addAll(Collection<? extends Fixup> c) {
         if (c instanceof Fixups) {
             // Use knowledge of Itr structure to avoid building little structs.
@@ -367,7 +394,13 @@
     }
 
     /// Static methods that optimize the use of this class.
-    public static
+    static Object addRefWithBytes(Object f, byte[] bytes, Entry e) {
+        return add(f, bytes, 0, U2_FORMAT, e);
+    }
+    static Object addRefWithLoc(Object f, int loc, Entry entry) {
+        return add(f, null, loc, U2_FORMAT, entry);
+    }
+    private static
     Object add(Object prevFixups,
                byte[] bytes, int loc, int fmt,
                Entry e) {
diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java
index 64f9db5..af78754 100644
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -259,7 +259,7 @@
                     byte[] bytes = new byte[2];
                     sfName = getRefString(obvious);
                     Object f = null;
-                    f = Fixups.add(f, bytes, 0, Fixups.U2_FORMAT, sfName);
+                    f = Fixups.addRefWithBytes(f, bytes, sfName);
                     a = attrSourceFileSpecial.addContent(bytes, f);
                 }
             } else if (obvious.equals(sfName.stringValue())) {
diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java
index b42dda3..000a643 100644
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java
@@ -116,7 +116,7 @@
             int nr = super.read(b, off, len);
             servedPos = pos;
             if (nr >= 0)  served += nr;
-            assert(served <= limit || limit == -1);
+            //assert(served <= limit || limit == -1);
             return nr;
         }
         public long skip(long n) throws IOException {
@@ -1500,6 +1500,7 @@
         //        ic_local_bands
         //        *class_ClassFile_version_minor_H :UNSIGNED5
         //        *class_ClassFile_version_major_H :UNSIGNED5
+        //        class_type_metadata_bands
         //
         //  field_attr_bands:
         //        *field_flags :UNSIGNED5
@@ -1509,6 +1510,7 @@
         //        *field_Signature_RS :UNSIGNED5 (cp_Signature)
         //        field_metadata_bands
         //        *field_ConstantValue_KQ :UNSIGNED5 (cp_Int, etc.; see note)
+        //        field_type_metadata_bands
         //
         //  method_attr_bands:
         //        *method_flags :UNSIGNED5
@@ -1522,6 +1524,7 @@
         //        *method_MethodParameters_NB: BYTE1
         //        *method_MethodParameters_RUN: UNSIGNED5 (cp_Utf8)
         //        *method_MethodParameters_FH:  UNSIGNED5 (flag)
+        //        method_type_metadata_bands
         //
         //  code_attr_bands:
         //        *code_flags :UNSIGNED5
@@ -1537,6 +1540,7 @@
         //        *code_LocalVariableTable_name_RU :UNSIGNED5 (cp_Utf8)
         //        *code_LocalVariableTable_type_RS :UNSIGNED5 (cp_Signature)
         //        *code_LocalVariableTable_slot :UNSIGNED5
+        //        code_type_metadata_bands
 
         countAttrs(ctype, holders);
         readAttrs(ctype, holders);
@@ -1703,8 +1707,9 @@
                     class_InnerClasses_outer_RCN.readFrom(in);
                     class_InnerClasses_name_RUN.expectLength(tupleCount);
                     class_InnerClasses_name_RUN.readFrom(in);
-                } else if (totalCount == 0) {
-                    // Expect no elements at all.  Skip quickly.
+                } else if (!optDebugBands && totalCount == 0) {
+                    // Expect no elements at all.  Skip quickly. however if we
+                    // are debugging bands, read all bands regardless
                     for (int j = 0; j < ab.length; j++) {
                         ab[j].doneWithUnusedBand();
                     }
@@ -1723,11 +1728,17 @@
                             assert(cbles[j].kind == Attribute.EK_CBLE);
                             int entryCount = forwardCounts[j];
                             forwardCounts[j] = -1;  // No more, please!
-                            if (cbles[j].flagTest(Attribute.EF_BACK))
+                            if (totalCount > 0 && cbles[j].flagTest(Attribute.EF_BACK))
                                 entryCount += xxx_attr_calls.getInt();
                             readAttrBands(cbles[j].body, entryCount, forwardCounts, ab);
                         }
                     }
+                    // mark them read,  to satisfy asserts
+                    if (optDebugBands && totalCount == 0) {
+                        for (int j = 0; j < ab.length; j++) {
+                            ab[j].doneDisbursing();
+                        }
+                    }
                 }
             }
             if (!predef)  break;
@@ -2154,11 +2165,10 @@
                         if (size == 1)  ldcRefSet.add(ref);
                         int fmt;
                         switch (size) {
-                        case 1: fmt = Fixups.U1_FORMAT; break;
-                        case 2: fmt = Fixups.U2_FORMAT; break;
+                        case 1: fixupBuf.addU1(pc, ref); break;
+                        case 2: fixupBuf.addU2(pc, ref); break;
                         default: assert(false); fmt = 0;
                         }
-                        fixupBuf.add(pc, fmt, ref);
                         buf[pc+0] = buf[pc+1] = 0;
                         pc += size;
                     }
@@ -2193,7 +2203,7 @@
                         int coding = bc_initref.getInt();
                         // Find the nth overloading of <init> in classRef.
                         MemberEntry ref = pkg.cp.getOverloadingForIndex(CONSTANT_Methodref, classRef, "<init>", coding);
-                        fixupBuf.add(pc, Fixups.U2_FORMAT, ref);
+                        fixupBuf.addU2(pc, ref);
                         buf[pc+0] = buf[pc+1] = 0;
                         pc += 2;
                         assert(Instruction.opLength(origBC) == (pc - curPC));
@@ -2226,7 +2236,7 @@
                             insnMap[numInsns++] = curPC;
                         }
                         buf[pc++] = (byte) origBC;
-                        fixupBuf.add(pc, Fixups.U2_FORMAT, ref);
+                        fixupBuf.addU2(pc, ref);
                         buf[pc+0] = buf[pc+1] = 0;
                         pc += 2;
                         assert(Instruction.opLength(origBC) == (pc - curPC));
@@ -2289,11 +2299,10 @@
                         buf[pc++] = (byte) origBC;
                         int fmt;
                         switch (size) {
-                        case 1: fmt = Fixups.U1_FORMAT; break;
-                        case 2: fmt = Fixups.U2_FORMAT; break;
+                        case 1: fixupBuf.addU1(pc, ref); break;
+                        case 2: fixupBuf.addU2(pc, ref); break;
                         default: assert(false); fmt = 0;
                         }
-                        fixupBuf.add(pc, fmt, ref);
                         buf[pc+0] = buf[pc+1] = 0;
                         pc += size;
                         if (origBC == _multianewarray) {
diff --git a/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java b/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java
index 24f7343..3c0b6a5 100644
--- a/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java
+++ b/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java
@@ -102,7 +102,7 @@
         this.domain = new DnsName(domain.endsWith(".")
                                   ? domain
                                   : domain + ".");
-        this.servers = servers;
+        this.servers = (servers == null) ? null : servers.clone();
         this.environment = (Hashtable<Object,Object>) environment.clone();
         envShared = false;
         parentIsDns = false;
@@ -129,11 +129,11 @@
      * no conflict.
      */
     private DnsContext(DnsContext ctx) {
-        environment = ctx.environment;
+        environment = ctx.environment;  // shared environment, copy-on-write
         envShared = ctx.envShared = true;
         parentIsDns = ctx.parentIsDns;
         domain = ctx.domain;
-        servers = ctx.servers;
+        servers = ctx.servers;          // shared servers, no write operation
         resolver = ctx.resolver;
         authoritative = ctx.authoritative;
         recursion = ctx.recursion;
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/BasicControl.java b/jdk/src/share/classes/com/sun/jndi/ldap/BasicControl.java
index d068704..007a40c 100644
--- a/jdk/src/share/classes/com/sun/jndi/ldap/BasicControl.java
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/BasicControl.java
@@ -81,7 +81,7 @@
         this.id = id;
         this.criticality = criticality;
         if (value != null) {
-            this.value = value;
+            this.value = value.clone();
         }
     }
 
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/BerDecoder.java b/jdk/src/share/classes/com/sun/jndi/ldap/BerDecoder.java
index 44b46f8..55b46d3 100644
--- a/jdk/src/share/classes/com/sun/jndi/ldap/BerDecoder.java
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/BerDecoder.java
@@ -42,7 +42,7 @@
      */
     public BerDecoder(byte buf[], int offset, int bufsize) {
 
-        this.buf = buf;
+        this.buf = buf;         // shared buffer, be careful to use this class
         this.bufsize = bufsize;
         this.origOffset = offset;
 
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/BerEncoder.java b/jdk/src/share/classes/com/sun/jndi/ldap/BerEncoder.java
index fc8566d..a641b0d 100644
--- a/jdk/src/share/classes/com/sun/jndi/ldap/BerEncoder.java
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/BerEncoder.java
@@ -99,7 +99,7 @@
         if (curSeqIndex != 0) {
             throw new IllegalStateException("BER encode error: Unbalanced SEQUENCEs.");
         }
-        return buf;
+        return buf;     // shared buffer, be careful to use this method.
     }
 
     /**
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/ext/StartTlsResponseImpl.java b/jdk/src/share/classes/com/sun/jndi/ldap/ext/StartTlsResponseImpl.java
index 7370361..28745bd 100644
--- a/jdk/src/share/classes/com/sun/jndi/ldap/ext/StartTlsResponseImpl.java
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/ext/StartTlsResponseImpl.java
@@ -134,7 +134,9 @@
      * @see #negotiate
      */
     public void setEnabledCipherSuites(String[] suites) {
-        this.suites = suites;
+        // The impl does accept null suites, although the spec requires
+        // a non-null list.
+        this.suites = suites == null ? null : suites.clone();
     }
 
     /**
diff --git a/jdk/src/share/classes/com/sun/script/javascript/ExternalScriptable.java b/jdk/src/share/classes/com/sun/script/javascript/ExternalScriptable.java
deleted file mode 100644
index 85656208..0000000
--- a/jdk/src/share/classes/com/sun/script/javascript/ExternalScriptable.java
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.script.javascript;
-import sun.org.mozilla.javascript.internal.*;
-import javax.script.*;
-import java.util.*;
-
-/**
- * ExternalScriptable is an implementation of Scriptable
- * backed by a JSR 223 ScriptContext instance.
- *
- * @author Mike Grogan
- * @author A. Sundararajan
- * @since 1.6
- */
-
-final class ExternalScriptable implements Scriptable {
-    /* Underlying ScriptContext that we use to store
-     * named variables of this scope.
-     */
-    private ScriptContext context;
-
-    /* JavaScript allows variables to be named as numbers (indexed
-     * properties). This way arrays, objects (scopes) are treated uniformly.
-     * Note that JSR 223 API supports only String named variables and
-     * so we can't store these in Bindings. Also, JavaScript allows name
-     * of the property name to be even empty String! Again, JSR 223 API
-     * does not support empty name. So, we use the following fallback map
-     * to store such variables of this scope. This map is not exposed to
-     * JSR 223 API. We can just script objects "as is" and need not convert.
-     */
-    private Map<Object, Object> indexedProps;
-
-    // my prototype
-    private Scriptable prototype;
-    // my parent scope, if any
-    private Scriptable parent;
-
-    ExternalScriptable(ScriptContext context) {
-        this(context, new HashMap<Object, Object>());
-    }
-
-    ExternalScriptable(ScriptContext context, Map<Object, Object> indexedProps) {
-        if (context == null) {
-            throw new NullPointerException("context is null");
-        }
-        this.context = context;
-        this.indexedProps = indexedProps;
-    }
-
-    ScriptContext getContext() {
-        return context;
-    }
-
-    private boolean isEmpty(String name) {
-        return name.equals("");
-    }
-
-    /**
-     * Return the name of the class.
-     */
-    public String getClassName() {
-        return "Global";
-    }
-
-    /**
-     * Returns the value of the named property or NOT_FOUND.
-     *
-     * If the property was created using defineProperty, the
-     * appropriate getter method is called.
-     *
-     * @param name the name of the property
-     * @param start the object in which the lookup began
-     * @return the value of the property (may be null), or NOT_FOUND
-     */
-    public synchronized Object get(String name, Scriptable start) {
-        if (isEmpty(name)) {
-            if (indexedProps.containsKey(name)) {
-                return indexedProps.get(name);
-            } else {
-                return NOT_FOUND;
-            }
-        } else {
-            synchronized (context) {
-                int scope = context.getAttributesScope(name);
-                if (scope != -1) {
-                    Object value = context.getAttribute(name, scope);
-                    return Context.javaToJS(value, this);
-                } else {
-                    return NOT_FOUND;
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns the value of the indexed property or NOT_FOUND.
-     *
-     * @param index the numeric index for the property
-     * @param start the object in which the lookup began
-     * @return the value of the property (may be null), or NOT_FOUND
-     */
-    public synchronized Object get(int index, Scriptable start) {
-        Integer key = new Integer(index);
-        if (indexedProps.containsKey(index)) {
-            return indexedProps.get(key);
-        } else {
-            return NOT_FOUND;
-        }
-    }
-
-    /**
-     * Returns true if the named property is defined.
-     *
-     * @param name the name of the property
-     * @param start the object in which the lookup began
-     * @return true if and only if the property was found in the object
-     */
-    public synchronized boolean has(String name, Scriptable start) {
-        if (isEmpty(name)) {
-            return indexedProps.containsKey(name);
-        } else {
-            synchronized (context) {
-                return context.getAttributesScope(name) != -1;
-            }
-        }
-    }
-
-    /**
-     * Returns true if the property index is defined.
-     *
-     * @param index the numeric index for the property
-     * @param start the object in which the lookup began
-     * @return true if and only if the property was found in the object
-     */
-    public synchronized boolean has(int index, Scriptable start) {
-        Integer key = new Integer(index);
-        return indexedProps.containsKey(key);
-    }
-
-    /**
-     * Sets the value of the named property, creating it if need be.
-     *
-     * @param name the name of the property
-     * @param start the object whose property is being set
-     * @param value value to set the property to
-     */
-    public void put(String name, Scriptable start, Object value) {
-        if (start == this) {
-            synchronized (this) {
-                if (isEmpty(name)) {
-                    indexedProps.put(name, value);
-                } else {
-                    synchronized (context) {
-                        int scope = context.getAttributesScope(name);
-                        if (scope == -1) {
-                            scope = ScriptContext.ENGINE_SCOPE;
-                        }
-                        context.setAttribute(name, jsToJava(value), scope);
-                    }
-                }
-            }
-        } else {
-            start.put(name, start, value);
-        }
-    }
-
-    /**
-     * Sets the value of the indexed property, creating it if need be.
-     *
-     * @param index the numeric index for the property
-     * @param start the object whose property is being set
-     * @param value value to set the property to
-     */
-    public void put(int index, Scriptable start, Object value) {
-        if (start == this) {
-            synchronized (this) {
-                indexedProps.put(new Integer(index), value);
-            }
-        } else {
-            start.put(index, start, value);
-        }
-    }
-
-    /**
-     * Removes a named property from the object.
-     *
-     * If the property is not found, no action is taken.
-     *
-     * @param name the name of the property
-     */
-    public synchronized void delete(String name) {
-        if (isEmpty(name)) {
-            indexedProps.remove(name);
-        } else {
-            synchronized (context) {
-                int scope = context.getAttributesScope(name);
-                if (scope != -1) {
-                    context.removeAttribute(name, scope);
-                }
-            }
-        }
-    }
-
-    /**
-     * Removes the indexed property from the object.
-     *
-     * If the property is not found, no action is taken.
-     *
-     * @param index the numeric index for the property
-     */
-    public void delete(int index) {
-        indexedProps.remove(new Integer(index));
-    }
-
-    /**
-     * Get the prototype of the object.
-     * @return the prototype
-     */
-    public Scriptable getPrototype() {
-        return prototype;
-    }
-
-    /**
-     * Set the prototype of the object.
-     * @param prototype the prototype to set
-     */
-    public void setPrototype(Scriptable prototype) {
-        this.prototype = prototype;
-    }
-
-    /**
-     * Get the parent scope of the object.
-     * @return the parent scope
-     */
-    public Scriptable getParentScope() {
-        return parent;
-    }
-
-    /**
-     * Set the parent scope of the object.
-     * @param parent the parent scope to set
-     */
-    public void setParentScope(Scriptable parent) {
-        this.parent = parent;
-    }
-
-     /**
-     * Get an array of property ids.
-     *
-     * Not all property ids need be returned. Those properties
-     * whose ids are not returned are considered non-enumerable.
-     *
-     * @return an array of Objects. Each entry in the array is either
-     *         a java.lang.String or a java.lang.Number
-     */
-    public synchronized Object[] getIds() {
-        String[] keys = getAllKeys();
-        int size = keys.length + indexedProps.size();
-        Object[] res = new Object[size];
-        System.arraycopy(keys, 0, res, 0, keys.length);
-        int i = keys.length;
-        // now add all indexed properties
-        for (Object index : indexedProps.keySet()) {
-            res[i++] = index;
-        }
-        return res;
-    }
-
-    /**
-     * Get the default value of the object with a given hint.
-     * The hints are String.class for type String, Number.class for type
-     * Number, Scriptable.class for type Object, and Boolean.class for
-     * type Boolean. <p>
-     *
-     * A <code>hint</code> of null means "no hint".
-     *
-     * See ECMA 8.6.2.6.
-     *
-     * @param hint the type hint
-     * @return the default value
-     */
-    public Object getDefaultValue(Class typeHint) {
-        for (int i=0; i < 2; i++) {
-            boolean tryToString;
-            if (typeHint == ScriptRuntime.StringClass) {
-                tryToString = (i == 0);
-            } else {
-                tryToString = (i == 1);
-            }
-
-            String methodName;
-            Object[] args;
-            if (tryToString) {
-                methodName = "toString";
-                args = ScriptRuntime.emptyArgs;
-            } else {
-                methodName = "valueOf";
-                args = new Object[1];
-                String hint;
-                if (typeHint == null) {
-                    hint = "undefined";
-                } else if (typeHint == ScriptRuntime.StringClass) {
-                    hint = "string";
-                } else if (typeHint == ScriptRuntime.ScriptableClass) {
-                    hint = "object";
-                } else if (typeHint == ScriptRuntime.FunctionClass) {
-                    hint = "function";
-                } else if (typeHint == ScriptRuntime.BooleanClass
-                           || typeHint == Boolean.TYPE)
-                {
-                    hint = "boolean";
-                } else if (typeHint == ScriptRuntime.NumberClass ||
-                         typeHint == ScriptRuntime.ByteClass ||
-                         typeHint == Byte.TYPE ||
-                         typeHint == ScriptRuntime.ShortClass ||
-                         typeHint == Short.TYPE ||
-                         typeHint == ScriptRuntime.IntegerClass ||
-                         typeHint == Integer.TYPE ||
-                         typeHint == ScriptRuntime.FloatClass ||
-                         typeHint == Float.TYPE ||
-                         typeHint == ScriptRuntime.DoubleClass ||
-                         typeHint == Double.TYPE)
-                {
-                    hint = "number";
-                } else {
-                    throw Context.reportRuntimeError(
-                        "Invalid JavaScript value of type " +
-                        typeHint.toString());
-                }
-                args[0] = hint;
-            }
-            Object v = ScriptableObject.getProperty(this, methodName);
-            if (!(v instanceof Function))
-                continue;
-            Function fun = (Function) v;
-            Context cx = RhinoScriptEngine.enterContext();
-            try {
-                v = fun.call(cx, fun.getParentScope(), this, args);
-            } finally {
-                cx.exit();
-            }
-            if (v != null) {
-                if (!(v instanceof Scriptable)) {
-                    return v;
-                }
-                if (typeHint == ScriptRuntime.ScriptableClass
-                    || typeHint == ScriptRuntime.FunctionClass)
-                {
-                    return v;
-                }
-                if (tryToString && v instanceof Wrapper) {
-                    // Let a wrapped java.lang.String pass for a primitive
-                    // string.
-                    Object u = ((Wrapper)v).unwrap();
-                    if (u instanceof String)
-                        return u;
-                }
-            }
-        }
-        // fall through to error
-        String arg = (typeHint == null) ? "undefined" : typeHint.getName();
-        throw Context.reportRuntimeError(
-                  "Cannot find default value for object " + arg);
-    }
-
-    /**
-     * Implements the instanceof operator.
-     *
-     * @param instance The value that appeared on the LHS of the instanceof
-     *              operator
-     * @return true if "this" appears in value's prototype chain
-     *
-     */
-    public boolean hasInstance(Scriptable instance) {
-        // Default for JS objects (other than Function) is to do prototype
-        // chasing.
-        Scriptable proto = instance.getPrototype();
-        while (proto != null) {
-            if (proto.equals(this)) return true;
-            proto = proto.getPrototype();
-        }
-        return false;
-    }
-
-    private String[] getAllKeys() {
-        ArrayList<String> list = new ArrayList<String>();
-        synchronized (context) {
-            for (int scope : context.getScopes()) {
-                Bindings bindings = context.getBindings(scope);
-                if (bindings != null) {
-                    list.ensureCapacity(bindings.size());
-                    for (String key : bindings.keySet()) {
-                        list.add(key);
-                    }
-                }
-            }
-        }
-        String[] res = new String[list.size()];
-        list.toArray(res);
-        return res;
-    }
-
-   /**
-    * We convert script values to the nearest Java value.
-    * We unwrap wrapped Java objects so that access from
-    * Bindings.get() would return "workable" value for Java.
-    * But, at the same time, we need to make few special cases
-    * and hence the following function is used.
-    */
-    private Object jsToJava(Object jsObj) {
-        if (jsObj instanceof Wrapper) {
-            Wrapper njb = (Wrapper) jsObj;
-            /* importClass feature of ImporterTopLevel puts
-             * NativeJavaClass in global scope. If we unwrap
-             * it, importClass won't work.
-             */
-            if (njb instanceof NativeJavaClass) {
-                return njb;
-            }
-
-            /* script may use Java primitive wrapper type objects
-             * (such as java.lang.Integer, java.lang.Boolean etc)
-             * explicitly. If we unwrap, then these script objects
-             * will become script primitive types. For example,
-             *
-             *    var x = new java.lang.Double(3.0); print(typeof x);
-             *
-             * will print 'number'. We don't want that to happen.
-             */
-            Object obj = njb.unwrap();
-            if (obj instanceof Number || obj instanceof String ||
-                obj instanceof Boolean || obj instanceof Character) {
-                // special type wrapped -- we just leave it as is.
-                return njb;
-            } else {
-                // return unwrapped object for any other object.
-                return obj;
-            }
-        } else { // not-a-Java-wrapper
-            return jsObj;
-        }
-    }
-}
diff --git a/jdk/src/share/classes/com/sun/script/javascript/JSAdapter.java b/jdk/src/share/classes/com/sun/script/javascript/JSAdapter.java
deleted file mode 100644
index 53497e9..0000000
--- a/jdk/src/share/classes/com/sun/script/javascript/JSAdapter.java
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.script.javascript;
-
-import sun.org.mozilla.javascript.internal.*;
-import java.util.*;
-
-/**
- * JSAdapter is java.lang.reflect.Proxy equivalent for JavaScript. JSAdapter
- * calls specially named JavaScript methods on an adaptee object when property
- * access is attempted on it.
- *
- * Example:
- *
- *    var y = {
- *                __get__    : function (name) { ... }
- *                __has__    : function (name) { ... }
- *                __put__    : function (name, value) {...}
- *                __delete__ : function (name) { ... }
- *                __getIds__ : function () { ... }
- *            };
- *
- *    var x = new JSAdapter(y);
- *
- *    x.i;                        // calls y.__get__
- *    i in x;                     // calls y.__has__
- *    x.p = 10;                   // calls y.__put__
- *    delete x.p;                 // calls y.__delete__
- *    for (i in x) { print(i); }  // calls y.__getIds__
- *
- * If a special JavaScript method is not found in the adaptee, then JSAdapter
- * forwards the property access to the adaptee itself.
- *
- * JavaScript caller of adapter object is isolated from the fact that
- * the property access/mutation/deletion are really calls to
- * JavaScript methods on adaptee.  Use cases include 'smart'
- * properties, property access tracing/debugging, encaptulation with
- * easy client access - in short JavaScript becomes more "Self" like.
- *
- * Note that Rhino already supports special properties like __proto__
- * (to set, get prototype), __parent__ (to set, get parent scope). We
- * follow the same double underscore nameing convention here. Similarly
- * the name JSAdapter is derived from JavaAdapter -- which is a facility
- * to extend, implement Java classes/interfaces by JavaScript.
- *
- * @author A. Sundararajan
- * @since 1.6
- */
-public final class JSAdapter implements Scriptable, Function {
-    private JSAdapter(Scriptable obj) {
-        setAdaptee(obj);
-    }
-
-    // initializer to setup JSAdapter prototype in the given scope
-    public static void init(Context cx, Scriptable scope, boolean sealed)
-    throws RhinoException {
-        JSAdapter obj = new JSAdapter(cx.newObject(scope));
-        obj.setParentScope(scope);
-        obj.setPrototype(getFunctionPrototype(scope));
-        obj.isPrototype = true;
-        ScriptableObject.defineProperty(scope, "JSAdapter",  obj,
-                ScriptableObject.DONTENUM);
-    }
-
-    public String getClassName() {
-        return "JSAdapter";
-    }
-
-    public Object get(String name, Scriptable start) {
-        Function func = getAdapteeFunction(GET_PROP);
-        if (func != null) {
-            return call(func, new Object[] { name });
-        } else {
-            start = getAdaptee();
-            return start.get(name, start);
-        }
-    }
-
-    public Object get(int index, Scriptable start) {
-        Function func = getAdapteeFunction(GET_PROP);
-        if (func != null) {
-            return call(func, new Object[] { new Integer(index) });
-        } else {
-            start = getAdaptee();
-            return start.get(index, start);
-        }
-    }
-
-    public boolean has(String name, Scriptable start) {
-        Function func = getAdapteeFunction(HAS_PROP);
-        if (func != null) {
-            Object res = call(func, new Object[] { name });
-            return Context.toBoolean(res);
-        } else {
-            start = getAdaptee();
-            return start.has(name, start);
-        }
-    }
-
-    public boolean has(int index, Scriptable start) {
-        Function func = getAdapteeFunction(HAS_PROP);
-        if (func != null) {
-            Object res = call(func, new Object[] { new Integer(index) });
-            return Context.toBoolean(res);
-        } else {
-            start = getAdaptee();
-            return start.has(index, start);
-        }
-    }
-
-    public void put(String name, Scriptable start, Object value) {
-        if (start == this) {
-            Function func = getAdapteeFunction(PUT_PROP);
-            if (func != null) {
-                call(func, new Object[] { name, value });
-            } else {
-                start = getAdaptee();
-                start.put(name, start, value);
-            }
-        } else {
-            start.put(name, start, value);
-        }
-    }
-
-    public void put(int index, Scriptable start, Object value) {
-        if (start == this) {
-            Function func = getAdapteeFunction(PUT_PROP);
-            if( func != null) {
-                call(func, new Object[] { new Integer(index), value });
-            } else {
-                start = getAdaptee();
-                start.put(index, start, value);
-            }
-        } else {
-            start.put(index, start, value);
-        }
-    }
-
-    public void delete(String name) {
-        Function func = getAdapteeFunction(DEL_PROP);
-        if (func != null) {
-            call(func, new Object[] { name });
-        } else {
-            getAdaptee().delete(name);
-        }
-    }
-
-    public void delete(int index) {
-        Function func = getAdapteeFunction(DEL_PROP);
-        if (func != null) {
-            call(func, new Object[] { new Integer(index) });
-        } else {
-            getAdaptee().delete(index);
-        }
-    }
-
-    public Scriptable getPrototype() {
-        return prototype;
-    }
-
-    public void setPrototype(Scriptable prototype) {
-        this.prototype = prototype;
-    }
-
-    public Scriptable getParentScope() {
-        return parent;
-    }
-
-    public void setParentScope(Scriptable parent) {
-        this.parent = parent;
-    }
-
-    public Object[] getIds() {
-        Function func = getAdapteeFunction(GET_PROPIDS);
-        if (func != null) {
-            Object val = call(func, new Object[0]);
-            // in most cases, adaptee would return native JS array
-            if (val instanceof NativeArray) {
-                NativeArray array = (NativeArray) val;
-                Object[] res = new Object[(int)array.getLength()];
-                for (int index = 0; index < res.length; index++) {
-                    res[index] = mapToId(array.get(index, array));
-                }
-                return res;
-            } else if (val instanceof NativeJavaArray) {
-                // may be attempt wrapped Java array
-                Object tmp = ((NativeJavaArray)val).unwrap();
-                Object[] res;
-                if (tmp.getClass() == Object[].class) {
-                    Object[]  array = (Object[]) tmp;
-                    res = new Object[array.length];
-                    for (int index = 0; index < array.length; index++) {
-                        res[index] = mapToId(array[index]);
-                    }
-                } else {
-                    // just return an empty array
-                    res = Context.emptyArgs;
-                }
-                return res;
-            } else {
-                // some other return type, just return empty array
-                return Context.emptyArgs;
-            }
-        } else {
-            return getAdaptee().getIds();
-        }
-    }
-
-    public boolean hasInstance(Scriptable scriptable) {
-        if (scriptable instanceof JSAdapter) {
-            return true;
-        } else {
-            Scriptable proto = scriptable.getPrototype();
-            while (proto != null) {
-                if (proto.equals(this)) return true;
-                proto = proto.getPrototype();
-            }
-            return false;
-        }
-    }
-
-    public Object getDefaultValue(Class hint) {
-        return getAdaptee().getDefaultValue(hint);
-    }
-
-    public Object call(Context cx, Scriptable scope, Scriptable thisObj,
-            Object[] args)
-            throws RhinoException {
-        if (isPrototype) {
-            return construct(cx, scope, args);
-        } else {
-            Scriptable tmp = getAdaptee();
-            if (tmp instanceof Function) {
-                return ((Function)tmp).call(cx, scope, tmp, args);
-            } else {
-                throw Context.reportRuntimeError("TypeError: not a function");
-            }
-        }
-    }
-
-    public Scriptable construct(Context cx, Scriptable scope, Object[] args)
-    throws RhinoException {
-        if (isPrototype) {
-            Scriptable topLevel = ScriptableObject.getTopLevelScope(scope);
-            JSAdapter newObj;
-            if (args.length > 0) {
-                newObj = new JSAdapter(Context.toObject(args[0], topLevel));
-            } else {
-                throw Context.reportRuntimeError("JSAdapter requires adaptee");
-            }
-            return newObj;
-        } else {
-            Scriptable tmp = getAdaptee();
-            if (tmp instanceof Function) {
-                return ((Function)tmp).construct(cx, scope, args);
-            } else {
-                throw Context.reportRuntimeError("TypeError: not a constructor");
-            }
-        }
-    }
-
-    public Scriptable getAdaptee() {
-        return adaptee;
-    }
-
-    public void setAdaptee(Scriptable adaptee) {
-        if (adaptee == null) {
-            throw new NullPointerException("adaptee can not be null");
-        }
-        this.adaptee = adaptee;
-    }
-
-    //-- internals only below this point
-
-    // map a property id. Property id can only be an Integer or String
-    private Object mapToId(Object tmp) {
-        if (tmp instanceof Double) {
-            return new Integer(((Double)tmp).intValue());
-        } else {
-            return Context.toString(tmp);
-        }
-    }
-
-    private static Scriptable getFunctionPrototype(Scriptable scope) {
-        return ScriptableObject.getFunctionPrototype(scope);
-    }
-
-    private Function getAdapteeFunction(String name) {
-        Object o = ScriptableObject.getProperty(getAdaptee(), name);
-        return (o instanceof Function)? (Function)o : null;
-    }
-
-    private Object call(Function func, Object[] args) {
-        Context cx = Context.getCurrentContext();
-        Scriptable thisObj = getAdaptee();
-        Scriptable scope = func.getParentScope();
-        try {
-            return func.call(cx, scope, thisObj, args);
-        } catch (RhinoException re) {
-            throw Context.reportRuntimeError(re.getMessage());
-        }
-    }
-
-    private Scriptable prototype;
-    private Scriptable parent;
-    private Scriptable adaptee;
-    private boolean isPrototype;
-
-    // names of adaptee JavaScript functions
-    private static final String GET_PROP = "__get__";
-    private static final String HAS_PROP = "__has__";
-    private static final String PUT_PROP = "__put__";
-    private static final String DEL_PROP = "__delete__";
-    private static final String GET_PROPIDS = "__getIds__";
-}
diff --git a/jdk/src/share/classes/com/sun/script/javascript/JavaAdapter.java b/jdk/src/share/classes/com/sun/script/javascript/JavaAdapter.java
deleted file mode 100644
index 4e67006..0000000
--- a/jdk/src/share/classes/com/sun/script/javascript/JavaAdapter.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.script.javascript;
-
-import javax.script.Invocable;
-import sun.org.mozilla.javascript.internal.*;
-
-/**
- * This class implements Rhino-like JavaAdapter to help implement a Java
- * interface in JavaScript. We support this using Invocable.getInterface.
- * Using this JavaAdapter, script author could write:
- *
- *    var r = new java.lang.Runnable() {
- *                run: function() { script... }
- *            };
- *
- *    r.run();
- *    new java.lang.Thread(r).start();
- *
- * Note that Rhino's JavaAdapter support allows extending a Java class and/or
- * implementing one or more interfaces. This JavaAdapter implementation does
- * not support these.
- *
- * @author A. Sundararajan
- * @since 1.6
- */
-final class JavaAdapter extends ScriptableObject implements Function {
-    private JavaAdapter(Invocable engine) {
-        this.engine = engine;
-    }
-
-    static void init(Context cx, Scriptable scope, boolean sealed)
-    throws RhinoException {
-        RhinoTopLevel topLevel = (RhinoTopLevel) scope;
-        Invocable engine = topLevel.getScriptEngine();
-        JavaAdapter obj = new JavaAdapter(engine);
-        obj.setParentScope(scope);
-        obj.setPrototype(getFunctionPrototype(scope));
-        /*
-         * Note that we can't use defineProperty. A property of this
-         * name is already defined in Context.initStandardObjects. We
-         * simply overwrite the property value!
-         */
-        ScriptableObject.putProperty(topLevel, "JavaAdapter", obj);
-    }
-
-    public String getClassName() {
-        return "JavaAdapter";
-    }
-
-    public Object call(Context cx, Scriptable scope, Scriptable thisObj,
-            Object[] args) throws RhinoException {
-        return construct(cx, scope, args);
-    }
-
-    public Scriptable construct(Context cx, Scriptable scope, Object[] args)
-    throws RhinoException {
-        if (args.length == 2) {
-            Class<?> clazz = null;
-            Object obj1 = args[0];
-            if (obj1 instanceof Wrapper) {
-                Object o = ((Wrapper)obj1).unwrap();
-                if (o instanceof Class && ((Class)o).isInterface()) {
-                    clazz = (Class) o;
-                }
-            } else if (obj1 instanceof Class) {
-                if (((Class)obj1).isInterface()) {
-                    clazz = (Class) obj1;
-                }
-            }
-            if (clazz == null) {
-                throw Context.reportRuntimeError("JavaAdapter: first arg should be interface Class");
-            }
-
-            Scriptable topLevel = ScriptableObject.getTopLevelScope(scope);
-            return cx.toObject(engine.getInterface(args[1],  clazz), topLevel);
-        } else {
-            throw Context.reportRuntimeError("JavaAdapter requires two arguments");
-        }
-    }
-
-    private Invocable engine;
-}
diff --git a/jdk/src/share/classes/com/sun/script/javascript/META-INF/services/javax.script.ScriptEngineFactory b/jdk/src/share/classes/com/sun/script/javascript/META-INF/services/javax.script.ScriptEngineFactory
deleted file mode 100644
index de576fb..0000000
--- a/jdk/src/share/classes/com/sun/script/javascript/META-INF/services/javax.script.ScriptEngineFactory
+++ /dev/null
@@ -1,5 +0,0 @@
-
-#script engines supported
-
-com.sun.script.javascript.RhinoScriptEngineFactory #javascript
-
diff --git a/jdk/src/share/classes/com/sun/script/javascript/RhinoClassShutter.java b/jdk/src/share/classes/com/sun/script/javascript/RhinoClassShutter.java
deleted file mode 100644
index ea376e8..0000000
--- a/jdk/src/share/classes/com/sun/script/javascript/RhinoClassShutter.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.script.javascript;
-
-import java.util.*;
-import sun.org.mozilla.javascript.internal.*;
-
-/**
- * This class prevents script access to certain sensitive classes.
- * Note that this class checks over and above SecurityManager. i.e., although
- * a SecurityManager would pass, class shutter may still prevent access.
- *
- * @author A. Sundararajan
- * @since 1.6
- */
-final class RhinoClassShutter implements ClassShutter {
-    private static Map<String, Boolean> protectedClasses;
-    private static RhinoClassShutter theInstance;
-
-    private RhinoClassShutter() {
-    }
-
-    static synchronized ClassShutter getInstance() {
-        if (theInstance == null) {
-            theInstance = new RhinoClassShutter();
-            protectedClasses = new HashMap<String, Boolean>();
-
-            // For now, we just have AccessController. Allowing scripts
-            // to this class will allow it to execute doPrivileged in
-            // bootstrap context. We can add more classes for other reasons.
-            protectedClasses.put("java.security.AccessController", Boolean.TRUE);
-        }
-        return theInstance;
-    }
-
-    public boolean visibleToScripts(String fullClassName) {
-        // first do the security check.
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            int i = fullClassName.lastIndexOf(".");
-            if (i != -1) {
-                try {
-                    sm.checkPackageAccess(fullClassName.substring(0, i));
-                } catch (SecurityException se) {
-                    return false;
-                }
-            }
-        }
-        // now, check is it a protected class.
-        return protectedClasses.get(fullClassName) == null;
-    }
-}
diff --git a/jdk/src/share/classes/com/sun/script/javascript/RhinoCompiledScript.java b/jdk/src/share/classes/com/sun/script/javascript/RhinoCompiledScript.java
deleted file mode 100644
index 4c6a824..0000000
--- a/jdk/src/share/classes/com/sun/script/javascript/RhinoCompiledScript.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.script.javascript;
-import javax.script.*;
-import sun.org.mozilla.javascript.internal.*;
-
-/**
- * Represents compiled JavaScript code.
- *
- * @author Mike Grogan
- * @since 1.6
- */
-final class RhinoCompiledScript extends CompiledScript {
-
-    private RhinoScriptEngine engine;
-    private Script script;
-
-
-    RhinoCompiledScript(RhinoScriptEngine engine, Script script) {
-        this.engine = engine;
-        this.script = script;
-    }
-
-    public Object eval(ScriptContext context) throws ScriptException {
-
-        Object result = null;
-        Context cx = RhinoScriptEngine.enterContext();
-        try {
-
-            Scriptable scope = engine.getRuntimeScope(context);
-            Object ret = script.exec(cx, scope);
-            result = engine.unwrapReturnValue(ret);
-        } catch (RhinoException re) {
-            int line = (line = re.lineNumber()) == 0 ? -1 : line;
-            String msg;
-            if (re instanceof JavaScriptException) {
-                msg = String.valueOf(((JavaScriptException)re).getValue());
-            } else {
-                msg = re.toString();
-            }
-            ScriptException se = new ScriptException(msg, re.sourceName(), line);
-            se.initCause(re);
-            throw se;
-        } finally {
-            Context.exit();
-        }
-
-        return result;
-    }
-
-    public ScriptEngine getEngine() {
-        return engine;
-    }
-
-}
diff --git a/jdk/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java b/jdk/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java
deleted file mode 100644
index d168a76..0000000
--- a/jdk/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * Copyright (c) 2005, 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 com.sun.script.javascript;
-import com.sun.script.util.*;
-import javax.script.*;
-import sun.org.mozilla.javascript.internal.*;
-import java.lang.reflect.Method;
-import java.io.*;
-import java.util.*;
-
-
-/**
- * Implementation of <code>ScriptEngine</code> using the Mozilla Rhino
- * interpreter.
- *
- * @author Mike Grogan
- * @author A. Sundararajan
- * @since 1.6
- */
-public final class RhinoScriptEngine extends AbstractScriptEngine
-        implements  Invocable, Compilable {
-
-    private static final boolean DEBUG = false;
-
-    /* Scope where standard JavaScript objects and our
-     * extensions to it are stored. Note that these are not
-     * user defined engine level global variables. These are
-     * variables have to be there on all compliant ECMAScript
-     * scopes. We put these standard objects in this top level.
-     */
-    private RhinoTopLevel topLevel;
-
-    /* map used to store indexed properties in engine scope
-     * refer to comment on 'indexedProps' in ExternalScriptable.java.
-     */
-    private Map<Object, Object> indexedProps;
-
-    private ScriptEngineFactory factory;
-    private InterfaceImplementor implementor;
-
-    private static final int languageVersion = getLanguageVersion();
-    private static final int optimizationLevel = getOptimizationLevel();
-    static {
-        ContextFactory.initGlobal(new ContextFactory() {
-            protected Context makeContext() {
-                Context cx = super.makeContext();
-                cx.setLanguageVersion(languageVersion);
-                cx.setOptimizationLevel(optimizationLevel);
-                cx.setClassShutter(RhinoClassShutter.getInstance());
-                cx.setWrapFactory(RhinoWrapFactory.getInstance());
-                return cx;
-            }
-        });
-    }
-
-    private static final String RHINO_JS_VERSION = "rhino.js.version";
-    private static int getLanguageVersion() {
-        int version;
-        String tmp = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction(RHINO_JS_VERSION));
-        if (tmp != null) {
-            version = Integer.parseInt((String)tmp);
-        } else {
-            version = Context.VERSION_1_8;
-        }
-        return version;
-    }
-
-    private static final String RHINO_OPT_LEVEL = "rhino.opt.level";
-    private static int getOptimizationLevel() {
-        int optLevel = -1;
-        // disable optimizer under security manager, for now.
-        if (System.getSecurityManager() == null) {
-            optLevel = Integer.getInteger(RHINO_OPT_LEVEL, -1);
-        }
-        return optLevel;
-    }
-
-    /**
-     * Creates a new instance of RhinoScriptEngine
-     */
-    public RhinoScriptEngine() {
-
-        Context cx = enterContext();
-        try {
-            topLevel = new RhinoTopLevel(cx, this);
-        } finally {
-            cx.exit();
-        }
-
-        indexedProps = new HashMap<Object, Object>();
-
-        //construct object used to implement getInterface
-        implementor = new InterfaceImplementor(this) {
-                protected boolean isImplemented(Object thiz, Class<?> iface) {
-                    Context cx = enterContext();
-                    try {
-                        if (thiz != null && !(thiz instanceof Scriptable)) {
-                            thiz = cx.toObject(thiz, topLevel);
-                        }
-                        Scriptable engineScope = getRuntimeScope(context);
-                        Scriptable localScope = (thiz != null)? (Scriptable) thiz :
-                                                    engineScope;
-                        for (Method method : iface.getMethods()) {
-                            // ignore methods of java.lang.Object class
-                            if (method.getDeclaringClass() == Object.class) {
-                                continue;
-                            }
-                            Object obj = ScriptableObject.getProperty(localScope, method.getName());
-                            if (! (obj instanceof Function)) {
-                                return false;
-                            }
-                        }
-                        return true;
-                    } finally {
-                        cx.exit();
-                    }
-                }
-
-                protected Object convertResult(Method method, Object res)
-                                            throws ScriptException {
-                    Class desiredType = method.getReturnType();
-                    if (desiredType == Void.TYPE) {
-                        return null;
-                    } else {
-                        return Context.jsToJava(res, desiredType);
-                    }
-                }
-            };
-    }
-
-    public Object eval(Reader reader, ScriptContext ctxt)
-    throws ScriptException {
-        Object ret;
-
-        Context cx = enterContext();
-        try {
-            Scriptable scope = getRuntimeScope(ctxt);
-            String filename = (String) get(ScriptEngine.FILENAME);
-            filename = filename == null ? "<Unknown source>" : filename;
-
-            ret = cx.evaluateReader(scope, reader, filename , 1,  null);
-        } catch (RhinoException re) {
-            if (DEBUG) re.printStackTrace();
-            int line = (line = re.lineNumber()) == 0 ? -1 : line;
-            String msg;
-            if (re instanceof JavaScriptException) {
-                msg = String.valueOf(((JavaScriptException)re).getValue());
-            } else {
-                msg = re.toString();
-            }
-            ScriptException se = new ScriptException(msg, re.sourceName(), line);
-            se.initCause(re);
-            throw se;
-        } catch (IOException ee) {
-            throw new ScriptException(ee);
-        } finally {
-            cx.exit();
-        }
-
-        return unwrapReturnValue(ret);
-    }
-
-    public Object eval(String script, ScriptContext ctxt) throws ScriptException {
-        if (script == null) {
-            throw new NullPointerException("null script");
-        }
-        return eval(new StringReader(script) , ctxt);
-    }
-
-    public ScriptEngineFactory getFactory() {
-        if (factory != null) {
-            return factory;
-        } else {
-            return new RhinoScriptEngineFactory();
-        }
-    }
-
-    public Bindings createBindings() {
-        return new SimpleBindings();
-    }
-
-    //Invocable methods
-    public Object invokeFunction(String name, Object... args)
-    throws ScriptException, NoSuchMethodException {
-        return invoke(null, name, args);
-    }
-
-    public Object invokeMethod(Object thiz, String name, Object... args)
-    throws ScriptException, NoSuchMethodException {
-        if (thiz == null) {
-            throw new IllegalArgumentException("script object can not be null");
-        }
-        return invoke(thiz, name, args);
-    }
-
-    private Object invoke(Object thiz, String name, Object... args)
-    throws ScriptException, NoSuchMethodException {
-        Context cx = enterContext();
-        try {
-            if (name == null) {
-                throw new NullPointerException("method name is null");
-            }
-
-            if (thiz != null && !(thiz instanceof Scriptable)) {
-                thiz = cx.toObject(thiz, topLevel);
-            }
-
-            Scriptable engineScope = getRuntimeScope(context);
-            Scriptable localScope = (thiz != null)? (Scriptable) thiz :
-                                                    engineScope;
-            Object obj = ScriptableObject.getProperty(localScope, name);
-            if (! (obj instanceof Function)) {
-                throw new NoSuchMethodException("no such method: " + name);
-            }
-
-            Function func = (Function) obj;
-            Scriptable scope = func.getParentScope();
-            if (scope == null) {
-                scope = engineScope;
-            }
-            Object result = func.call(cx, scope, localScope,
-                                      wrapArguments(args));
-            return unwrapReturnValue(result);
-        } catch (RhinoException re) {
-            if (DEBUG) re.printStackTrace();
-            int line = (line = re.lineNumber()) == 0 ? -1 : line;
-            ScriptException se = new ScriptException(re.toString(), re.sourceName(), line);
-            se.initCause(re);
-            throw se;
-        } finally {
-            cx.exit();
-        }
-    }
-
-    public <T> T getInterface(Class<T> clasz) {
-        try {
-            return implementor.getInterface(null, clasz);
-        } catch (ScriptException e) {
-            return null;
-        }
-    }
-
-    public <T> T getInterface(Object thiz, Class<T> clasz) {
-        if (thiz == null) {
-            throw new IllegalArgumentException("script object can not be null");
-        }
-
-        try {
-            return implementor.getInterface(thiz, clasz);
-        } catch (ScriptException e) {
-            return null;
-        }
-    }
-
-    private static final String printSource =
-            "function print(str, newline) {                \n" +
-            "    if (typeof(str) == 'undefined') {         \n" +
-            "        str = 'undefined';                    \n" +
-            "    } else if (str == null) {                 \n" +
-            "        str = 'null';                         \n" +
-            "    }                                         \n" +
-            "    var out = context.getWriter();            \n" +
-            "    if (!(out instanceof java.io.PrintWriter))\n" +
-            "        out = new java.io.PrintWriter(out);   \n" +
-            "    out.print(String(str));                   \n" +
-            "    if (newline) out.print('\\n');            \n" +
-            "    out.flush();                              \n" +
-            "}\n" +
-            "function println(str) {                       \n" +
-            "    print(str, true);                         \n" +
-            "}";
-
-    Scriptable getRuntimeScope(ScriptContext ctxt) {
-        if (ctxt == null) {
-            throw new NullPointerException("null script context");
-        }
-
-        // we create a scope for the given ScriptContext
-        Scriptable newScope = new ExternalScriptable(ctxt, indexedProps);
-
-        // Set the prototype of newScope to be 'topLevel' so that
-        // JavaScript standard objects are visible from the scope.
-        newScope.setPrototype(topLevel);
-
-        // define "context" variable in the new scope
-        newScope.put("context", newScope, ctxt);
-
-        // define "print", "println" functions in the new scope
-        Context cx = enterContext();
-        try {
-            cx.evaluateString(newScope, printSource, "print", 1, null);
-        } finally {
-            cx.exit();
-        }
-        return newScope;
-    }
-
-
-    //Compilable methods
-    public CompiledScript compile(String script) throws ScriptException {
-        return compile(new StringReader(script));
-    }
-
-    public CompiledScript compile(java.io.Reader script) throws ScriptException {
-        CompiledScript ret = null;
-        Context cx = enterContext();
-
-        try {
-            String fileName = (String) get(ScriptEngine.FILENAME);
-            if (fileName == null) {
-                fileName = "<Unknown Source>";
-            }
-
-            Scriptable scope = getRuntimeScope(context);
-            Script scr = cx.compileReader(scope, script, fileName, 1, null);
-            ret = new RhinoCompiledScript(this, scr);
-        } catch (Exception e) {
-            if (DEBUG) e.printStackTrace();
-            throw new ScriptException(e);
-        } finally {
-            cx.exit();
-        }
-        return ret;
-    }
-
-
-    //package-private helpers
-
-    static Context enterContext() {
-        // call this always so that initializer of this class runs
-        // and initializes custom wrap factory and class shutter.
-        return Context.enter();
-    }
-
-    void setEngineFactory(ScriptEngineFactory fac) {
-        factory = fac;
-    }
-
-    Object[] wrapArguments(Object[] args) {
-        if (args == null) {
-            return Context.emptyArgs;
-        }
-        Object[] res = new Object[args.length];
-        for (int i = 0; i < res.length; i++) {
-            res[i] = Context.javaToJS(args[i], topLevel);
-        }
-        return res;
-    }
-
-    Object unwrapReturnValue(Object result) {
-        if (result instanceof Wrapper) {
-            result = ( (Wrapper) result).unwrap();
-        }
-
-        return result instanceof Undefined ? null : result;
-    }
-
-    /*
-    public static void main(String[] args) throws Exception {
-        if (args.length == 0) {
-            System.out.println("No file specified");
-            return;
-        }
-
-        InputStreamReader r = new InputStreamReader(new FileInputStream(args[0]));
-        ScriptEngine engine = new RhinoScriptEngine();
-
-        engine.put("x", "y");
-        engine.put(ScriptEngine.FILENAME, args[0]);
-        engine.eval(r);
-        System.out.println(engine.get("x"));
-    }
-    */
-}
diff --git a/jdk/src/share/classes/com/sun/script/javascript/RhinoScriptEngineFactory.java b/jdk/src/share/classes/com/sun/script/javascript/RhinoScriptEngineFactory.java
deleted file mode 100644
index c81ac79..0000000
--- a/jdk/src/share/classes/com/sun/script/javascript/RhinoScriptEngineFactory.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.script.javascript;
-import javax.script.*;
-import java.util.*;
-import sun.org.mozilla.javascript.internal.*;
-import com.sun.script.util.*;
-
-/**
- * Factory to create RhinoScriptEngine
- *
- * @author Mike Grogan
- * @since 1.6
- */
-public class RhinoScriptEngineFactory extends ScriptEngineFactoryBase {
-
-    public RhinoScriptEngineFactory() {
-    }
-
-    public List<String> getExtensions() {
-        return extensions;
-    }
-
-    public List<String> getMimeTypes() {
-        return mimeTypes;
-    }
-
-    public List<String> getNames() {
-        return names;
-    }
-
-    public Object getParameter(String key) {
-        if (key.equals(ScriptEngine.NAME)) {
-            return "javascript";
-        } else if (key.equals(ScriptEngine.ENGINE)) {
-            return "Mozilla Rhino";
-        } else if (key.equals(ScriptEngine.ENGINE_VERSION)) {
-            return "1.7 release 3 PRERELEASE";
-        } else if (key.equals(ScriptEngine.LANGUAGE)) {
-            return "ECMAScript";
-        } else if (key.equals(ScriptEngine.LANGUAGE_VERSION)) {
-            return "1.8";
-        } else if (key.equals("THREADING")) {
-            return "MULTITHREADED";
-        } else {
-            throw new IllegalArgumentException("Invalid key");
-        }
-    }
-
-    public ScriptEngine getScriptEngine() {
-        RhinoScriptEngine ret = new RhinoScriptEngine();
-        ret.setEngineFactory(this);
-        return ret;
-    }
-
-    public String getMethodCallSyntax(String obj, String method, String... args) {
-
-        String ret = obj + "." + method + "(";
-        int len = args.length;
-        if (len == 0) {
-            ret += ")";
-            return ret;
-        }
-
-        for (int i = 0; i < len; i++) {
-            ret += args[i];
-            if (i != len - 1) {
-                ret += ",";
-            } else {
-                ret += ")";
-            }
-        }
-        return ret;
-    }
-
-    public String getOutputStatement(String toDisplay) {
-        StringBuffer buf = new StringBuffer();
-        int len = toDisplay.length();
-        buf.append("print(\"");
-        for (int i = 0; i < len; i++) {
-            char ch = toDisplay.charAt(i);
-            switch (ch) {
-            case '"':
-                buf.append("\\\"");
-                break;
-            case '\\':
-                buf.append("\\\\");
-                break;
-            default:
-                buf.append(ch);
-                break;
-            }
-        }
-        buf.append("\")");
-        return buf.toString();
-    }
-
-    public String getProgram(String... statements) {
-        int len = statements.length;
-        String ret = "";
-        for (int i = 0; i < len; i++) {
-            ret += statements[i] + ";";
-        }
-
-        return ret;
-    }
-
-    /*
-    public static void main(String[] args) {
-        RhinoScriptEngineFactory fact = new RhinoScriptEngineFactory();
-        System.out.println(fact.getParameter(ScriptEngine.ENGINE_VERSION));
-    }
-    */
-
-    private static List<String> names;
-    private static List<String> mimeTypes;
-    private static List<String> extensions;
-
-    static {
-        names = new ArrayList<String>(6);
-        names.add("js");
-        names.add("rhino");
-        names.add("JavaScript");
-        names.add("javascript");
-        names.add("ECMAScript");
-        names.add("ecmascript");
-        names = Collections.unmodifiableList(names);
-
-        mimeTypes = new ArrayList<String>(4);
-        mimeTypes.add("application/javascript");
-        mimeTypes.add("application/ecmascript");
-        mimeTypes.add("text/javascript");
-        mimeTypes.add("text/ecmascript");
-        mimeTypes = Collections.unmodifiableList(mimeTypes);
-
-        extensions = new ArrayList<String>(1);
-        extensions.add("js");
-        extensions = Collections.unmodifiableList(extensions);
-    }
-}
diff --git a/jdk/src/share/classes/com/sun/script/javascript/RhinoTopLevel.java b/jdk/src/share/classes/com/sun/script/javascript/RhinoTopLevel.java
deleted file mode 100644
index 45295bb..0000000
--- a/jdk/src/share/classes/com/sun/script/javascript/RhinoTopLevel.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.script.javascript;
-
-import sun.org.mozilla.javascript.internal.*;
-import javax.script.*;
-
-/**
- * This class serves as top level scope for Rhino. This class adds
- * 3 top level functions (bindings, scope, sync) and two constructors
- * (JSAdapter, JavaAdapter).
- *
- * @author A. Sundararajan
- * @since 1.6
- */
-public final class RhinoTopLevel extends ImporterTopLevel {
-    RhinoTopLevel(Context cx, RhinoScriptEngine engine) {
-        super(cx);
-        this.engine = engine;
-
-
-        // initialize JSAdapter lazily. Reduces footprint & startup time.
-        new LazilyLoadedCtor(this, "JSAdapter",
-                "com.sun.script.javascript.JSAdapter",
-                false);
-
-        /*
-         * initialize JavaAdapter. We can't lazy initialize this because
-         * lazy initializer attempts to define a new property. But, JavaAdapter
-         * is an exisiting property that we overwrite.
-         */
-        JavaAdapter.init(cx, this, false);
-
-        // add top level functions
-        String names[] = { "bindings", "scope", "sync"  };
-        defineFunctionProperties(names, RhinoTopLevel.class,
-                ScriptableObject.DONTENUM);
-    }
-
-    /**
-     * The bindings function takes a JavaScript scope object
-     * of type ExternalScriptable and returns the underlying Bindings
-     * instance.
-     *
-     *    var page = scope(pageBindings);
-     *    with (page) {
-     *       // code that uses page scope
-     *    }
-     *    var b = bindings(page);
-     *    // operate on bindings here.
-     */
-    public static Object bindings(Context cx, Scriptable thisObj, Object[] args,
-            Function funObj) {
-        if (args.length == 1) {
-            Object arg = args[0];
-            if (arg instanceof Wrapper) {
-                arg = ((Wrapper)arg).unwrap();
-            }
-            if (arg instanceof ExternalScriptable) {
-                ScriptContext ctx = ((ExternalScriptable)arg).getContext();
-                Bindings bind = ctx.getBindings(ScriptContext.ENGINE_SCOPE);
-                return Context.javaToJS(bind,
-                           ScriptableObject.getTopLevelScope(thisObj));
-            }
-        }
-        return cx.getUndefinedValue();
-    }
-
-    /**
-     * The scope function creates a new JavaScript scope object
-     * with given Bindings object as backing store. This can be used
-     * to create a script scope based on arbitrary Bindings instance.
-     * For example, in webapp scenario, a 'page' level Bindings instance
-     * may be wrapped as a scope and code can be run in JavaScripe 'with'
-     * statement:
-     *
-     *    var page = scope(pageBindings);
-     *    with (page) {
-     *       // code that uses page scope
-     *    }
-     */
-    public static Object scope(Context cx, Scriptable thisObj, Object[] args,
-            Function funObj) {
-        if (args.length == 1) {
-            Object arg = args[0];
-            if (arg instanceof Wrapper) {
-                arg = ((Wrapper)arg).unwrap();
-            }
-            if (arg instanceof Bindings) {
-                ScriptContext ctx = new SimpleScriptContext();
-                ctx.setBindings((Bindings)arg, ScriptContext.ENGINE_SCOPE);
-                Scriptable res = new ExternalScriptable(ctx);
-                res.setPrototype(ScriptableObject.getObjectPrototype(thisObj));
-                res.setParentScope(ScriptableObject.getTopLevelScope(thisObj));
-                return res;
-            }
-        }
-        return cx.getUndefinedValue();
-    }
-
-    /**
-     * The sync function creates a synchronized function (in the sense
-     * of a Java synchronized method) from an existing function. The
-     * new function synchronizes on the <code>this</code> object of
-     * its invocation.
-     * js> var o = { f : sync(function(x) {
-     *       print("entry");
-     *       Packages.java.lang.Thread.sleep(x*1000);
-     *       print("exit");
-     *     })};
-     * js> thread(function() {o.f(5);});
-     * entry
-     * js> thread(function() {o.f(5);});
-     * js>
-     * exit
-     * entry
-     * exit
-     */
-    public static Object sync(Context cx, Scriptable thisObj, Object[] args,
-            Function funObj) {
-        if (args.length == 1 && args[0] instanceof Function) {
-            return new Synchronizer((Function)args[0]);
-        } else {
-            throw Context.reportRuntimeError("wrong argument(s) for sync");
-        }
-    }
-
-    RhinoScriptEngine getScriptEngine() {
-        return engine;
-    }
-
-    private RhinoScriptEngine engine;
-}
diff --git a/jdk/src/share/classes/com/sun/script/javascript/RhinoWrapFactory.java b/jdk/src/share/classes/com/sun/script/javascript/RhinoWrapFactory.java
deleted file mode 100644
index 906ffba..0000000
--- a/jdk/src/share/classes/com/sun/script/javascript/RhinoWrapFactory.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.script.javascript;
-
-import java.lang.reflect.*;
-import static sun.security.util.SecurityConstants.*;
-import sun.org.mozilla.javascript.internal.*;
-
-/**
- * This wrap factory is used for security reasons. JSR 223 script
- * engine interface and JavaScript engine classes are run as bootstrap
- * classes. For example, java.lang.Class.forName method (when called without
- * class loader) uses caller's class loader. This may be exploited by script
- * authors to access classes otherwise not accessible. For example,
- * classes in sun.* namespace are normally not accessible to untrusted
- * code and hence should not be accessible to JavaScript run from
- * untrusted code.
- *
- * @author A. Sundararajan
- * @since 1.6
- */
-final class RhinoWrapFactory extends WrapFactory {
-    private RhinoWrapFactory() {}
-    private static RhinoWrapFactory theInstance;
-
-    static synchronized WrapFactory getInstance() {
-        if (theInstance == null) {
-            theInstance = new RhinoWrapFactory();
-        }
-        return theInstance;
-    }
-
-    // We use instance of this class to wrap security sensitive
-    // Java object. Please refer below.
-    private static class RhinoJavaObject extends NativeJavaObject {
-        RhinoJavaObject(Scriptable scope, Object obj, Class type) {
-            // we pass 'null' to object. NativeJavaObject uses
-            // passed 'type' to reflect fields and methods when
-            // object is null.
-            super(scope, null, type);
-
-            // Now, we set actual object. 'javaObject' is protected
-            // field of NativeJavaObject.
-            javaObject = obj;
-        }
-    }
-
-    public Scriptable wrapAsJavaObject(Context cx, Scriptable scope,
-            Object javaObject, Class staticType) {
-        SecurityManager sm = System.getSecurityManager();
-        ClassShutter classShutter = RhinoClassShutter.getInstance();
-        if (javaObject instanceof ClassLoader) {
-            // Check with Security Manager whether we can expose a
-            // ClassLoader...
-            if (sm != null) {
-                sm.checkPermission(GET_CLASSLOADER_PERMISSION);
-            }
-            // if we fall through here, check permission succeeded.
-            return super.wrapAsJavaObject(cx, scope, javaObject, staticType);
-        } else {
-            String name = null;
-            if (javaObject instanceof Class) {
-                name = ((Class)javaObject).getName();
-            } else if (javaObject instanceof Member) {
-                Member member = (Member) javaObject;
-                // Check member access. Don't allow reflective access to
-                // non-public members. Note that we can't call checkMemberAccess
-                // because that expects exact stack depth!
-                if (sm != null && !Modifier.isPublic(member.getModifiers())) {
-                    return null;
-                }
-                name = member.getDeclaringClass().getName();
-            }
-            // Now, make sure that no ClassShutter prevented Class or Member
-            // of it is accessed reflectively. Note that ClassShutter may
-            // prevent access to a class, even though SecurityManager permit.
-            if (name != null) {
-                if (!classShutter.visibleToScripts(name)) {
-                    return null;
-                } else {
-                    return super.wrapAsJavaObject(cx, scope, javaObject, staticType);
-                }
-            }
-        }
-
-        // we have got some non-reflective object.
-        Class dynamicType = javaObject.getClass();
-        String name = dynamicType.getName();
-        if (!classShutter.visibleToScripts(name)) {
-            // Object of some sensitive class (such as sun.net.www.*
-            // objects returned from public method of java.net.URL class.
-            // We expose this object as though it is an object of some
-            // super class that is safe for access.
-
-            Class type = null;
-
-            // Whenever a Java Object is wrapped, we are passed with a
-            // staticType which is the type found from environment. For
-            // example, method return type known from signature. The dynamic
-            // type would be the actual Class of the actual returned object.
-            // If the staticType is an interface, we just use that type.
-            if (staticType != null && staticType.isInterface()) {
-                type = staticType;
-            } else {
-                // dynamicType is always a class type and never an interface.
-                // find an accessible super class of the dynamic type.
-                while (dynamicType != null) {
-                    dynamicType = dynamicType.getSuperclass();
-                    name = dynamicType.getName();
-                    if (classShutter.visibleToScripts(name)) {
-                         type = dynamicType; break;
-                    }
-                }
-                // atleast java.lang.Object has to be accessible. So, when
-                // we reach here, type variable should not be null.
-                assert type != null:
-                       "even java.lang.Object is not accessible?";
-            }
-            // create custom wrapper with the 'safe' type.
-            return new RhinoJavaObject(scope, javaObject, type);
-        } else {
-            return super.wrapAsJavaObject(cx, scope, javaObject, staticType);
-        }
-    }
-}
diff --git a/jdk/src/share/classes/com/sun/script/util/BindingsBase.java b/jdk/src/share/classes/com/sun/script/util/BindingsBase.java
deleted file mode 100644
index de0704c..0000000
--- a/jdk/src/share/classes/com/sun/script/util/BindingsBase.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.script.util;
-
-import javax.script.Bindings;
-import java.util.Map;
-import java.util.AbstractMap;
-
-/**
- * Abstract super class for Bindings implementations
- *
- * @author Mike Grogan
- * @since 1.6
- */
-public abstract class BindingsBase extends AbstractMap<String, Object>
-        implements Bindings {
-
-    //AbstractMap methods
-    public Object get(Object name) {
-        checkKey(name);
-        return getImpl((String)name);
-    }
-
-    public Object remove(Object key) {
-        checkKey(key);
-        return removeImpl((String)key);
-    }
-
-    public Object put(String key, Object value) {
-        checkKey(key);
-        return putImpl(key, value);
-    }
-
-    public void putAll(Map<? extends String, ? extends Object> toMerge) {
-        for (Map.Entry<? extends String, ? extends Object> entry : toMerge.entrySet()) {
-            String key = entry.getKey();
-            checkKey(key);
-            putImpl(entry.getKey(), entry.getValue());
-        }
-    }
-
-    //BindingsBase methods
-    public abstract Object putImpl(String name, Object value);
-    public abstract Object getImpl(String name);
-    public abstract Object removeImpl(String name);
-    public abstract String[] getNames();
-
-    protected void checkKey(Object key) {
-        if (key == null) {
-            throw new NullPointerException("key can not be null");
-        }
-        if (!(key instanceof String)) {
-            throw new ClassCastException("key should be String");
-        }
-        if (key.equals("")) {
-            throw new IllegalArgumentException("key can not be empty");
-        }
-    }
-}
diff --git a/jdk/src/share/classes/com/sun/script/util/BindingsEntrySet.java b/jdk/src/share/classes/com/sun/script/util/BindingsEntrySet.java
deleted file mode 100644
index 3755844..0000000
--- a/jdk/src/share/classes/com/sun/script/util/BindingsEntrySet.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.script.util;
-import java.util.*;
-
-/**
- * Entry set implementation for Bindings implementations
- *
- * @author Mike Grogan
- * @since 1.6
- */
-public class BindingsEntrySet extends AbstractSet<Map.Entry<String, Object>> {
-
-    private BindingsBase base;
-    private String[] keys;
-
-    public BindingsEntrySet(BindingsBase base) {
-        this.base = base;
-        keys = base.getNames();
-    }
-
-    public int size() {
-        return keys.length;
-    }
-
-    public Iterator<Map.Entry<String, Object>> iterator() {
-        return new BindingsIterator();
-    }
-
-    public class BindingsEntry implements Map.Entry<String, Object> {
-        private String key;
-        public BindingsEntry(String key) {
-            this.key = key;
-        }
-
-        public Object setValue(Object value) {
-            throw new UnsupportedOperationException();
-        }
-
-        public String getKey() {
-            return key;
-        }
-
-        public Object getValue() {
-            return base.get(key);
-        }
-
-    }
-
-    public class BindingsIterator implements Iterator<Map.Entry<String, Object>> {
-
-        private int current = 0;
-        private boolean stale = false;
-
-        public boolean hasNext() {
-            return (current < keys.length);
-        }
-
-        public BindingsEntry next() {
-            stale = false;
-            return new BindingsEntry(keys[current++]);
-        }
-
-        public void remove() {
-            if (stale || current == 0) {
-                throw new IllegalStateException();
-            }
-
-            stale = true;
-            base.remove(keys[current - 1]);
-        }
-
-    }
-
-}
diff --git a/jdk/src/share/classes/com/sun/script/util/BindingsImpl.java b/jdk/src/share/classes/com/sun/script/util/BindingsImpl.java
deleted file mode 100644
index 44eed88..0000000
--- a/jdk/src/share/classes/com/sun/script/util/BindingsImpl.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.script.util;
-import java.util.*;
-import javax.script.Bindings;
-
-/*
- * Abstract super class for Bindings implementations. Handles
- * global and local scopes.
- *
- * @author Mike Grogan
- * @since 1.6
- */
-public abstract class BindingsImpl extends BindingsBase {
-
-    //get method delegates to global if key is not defined in
-    //base class or local scope
-    protected Bindings global = null;
-
-    //get delegates to local scope
-    protected Bindings local = null;
-
-    public void setGlobal(Bindings n) {
-        global = n;
-    }
-
-    public void setLocal(Bindings n) {
-        local = n;
-    }
-
-    public  Set<Map.Entry<String, Object>> entrySet() {
-        return new BindingsEntrySet(this);
-    }
-
-    public Object get(Object key) {
-        checkKey(key);
-
-        Object ret  = null;
-        if ((local != null) && (null != (ret = local.get(key)))) {
-            return ret;
-        }
-
-        ret = getImpl((String)key);
-
-        if (ret != null) {
-            return ret;
-        } else if (global != null) {
-            return global.get(key);
-        } else {
-            return null;
-        }
-    }
-
-    public Object remove(Object key) {
-        checkKey(key);
-        Object ret = get(key);
-        if (ret != null) {
-            removeImpl((String)key);
-        }
-        return ret;
-    }
-}
diff --git a/jdk/src/share/classes/com/sun/script/util/InterfaceImplementor.java b/jdk/src/share/classes/com/sun/script/util/InterfaceImplementor.java
deleted file mode 100644
index 7e94c96..0000000
--- a/jdk/src/share/classes/com/sun/script/util/InterfaceImplementor.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2005, 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 com.sun.script.util;
-
-import javax.script.*;
-import java.lang.reflect.*;
-import java.security.*;
-
-/*
- * java.lang.reflect.Proxy based interface implementor. This is meant
- * to be used to implement Invocable.getInterface.
- *
- * @author Mike Grogan
- * @since 1.6
- */
-public class InterfaceImplementor {
-
-    private Invocable engine;
-
-    /** Creates a new instance of Invocable */
-    public InterfaceImplementor(Invocable engine) {
-        this.engine = engine;
-    }
-
-    private final class InterfaceImplementorInvocationHandler
-                        implements InvocationHandler {
-        private Object thiz;
-        private AccessControlContext accCtxt;
-
-        public InterfaceImplementorInvocationHandler(Object thiz,
-            AccessControlContext accCtxt) {
-            this.thiz = thiz;
-            this.accCtxt = accCtxt;
-        }
-
-        public Object invoke(Object proxy , Method method, Object[] args)
-        throws java.lang.Throwable {
-            // give chance to convert input args
-            args = convertArguments(method, args);
-            Object result;
-            final Method m = method;
-            final Object[] a = args;
-            result = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
-                public Object run() throws Exception {
-                    if (thiz == null) {
-                        return engine.invokeFunction(m.getName(), a);
-                    } else {
-                        return engine.invokeMethod(thiz, m.getName(), a);
-                    }
-                }
-            }, accCtxt);
-            // give chance to convert the method result
-            return convertResult(method, result);
-        }
-    }
-
-    public <T> T getInterface(Object thiz, Class<T> iface)
-    throws ScriptException {
-        if (iface == null || !iface.isInterface()) {
-            throw new IllegalArgumentException("interface Class expected");
-        }
-        if (! isImplemented(thiz, iface)) {
-            return null;
-        }
-        AccessControlContext accCtxt = AccessController.getContext();
-        return iface.cast(Proxy.newProxyInstance(iface.getClassLoader(),
-            new Class[]{iface},
-            new InterfaceImplementorInvocationHandler(thiz, accCtxt)));
-    }
-
-    protected boolean isImplemented(Object thiz, Class<?> iface) {
-        return true;
-    }
-
-    // called to convert method result after invoke
-    protected Object convertResult(Method method, Object res)
-                                   throws ScriptException {
-        // default is identity conversion
-        return res;
-    }
-
-    // called to convert method arguments before invoke
-    protected Object[] convertArguments(Method method, Object[] args)
-                                      throws ScriptException {
-        // default is identity conversion
-        return args;
-    }
-}
diff --git a/jdk/src/share/classes/com/sun/script/util/ScriptEngineFactoryBase.java b/jdk/src/share/classes/com/sun/script/util/ScriptEngineFactoryBase.java
deleted file mode 100644
index 3867045..0000000
--- a/jdk/src/share/classes/com/sun/script/util/ScriptEngineFactoryBase.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.script.util;
-import javax.script.*;
-
-/*
- * Abstract super class for factory implementations.
- *
- * @author Mike Grogan
- * @since 1.6
- */
-public abstract class ScriptEngineFactoryBase implements ScriptEngineFactory {
-
-    public String getName() {
-        return (String)getParameter(ScriptEngine.NAME);
-    }
-
-    public String getEngineName() {
-        return (String)getParameter(ScriptEngine.ENGINE);
-    }
-
-    public String getEngineVersion() {
-        return (String)getParameter(ScriptEngine.ENGINE_VERSION);
-    }
-
-    public String getLanguageName() {
-        return (String)getParameter(ScriptEngine.LANGUAGE);
-    }
-
-    public String getLanguageVersion() {
-        return (String)getParameter(ScriptEngine.LANGUAGE_VERSION);
-    }
-}
diff --git a/jdk/src/share/classes/com/sun/security/sasl/digest/DigestMD5Client.java b/jdk/src/share/classes/com/sun/security/sasl/digest/DigestMD5Client.java
index 07072e3..44cee0b 100644
--- a/jdk/src/share/classes/com/sun/security/sasl/digest/DigestMD5Client.java
+++ b/jdk/src/share/classes/com/sun/security/sasl/digest/DigestMD5Client.java
@@ -348,14 +348,23 @@
                     0, false);
                 cbh.handle(new Callback[] {ccb, ncb, pcb});
 
-                /* Acquire realm from RealmChoiceCallback*/
-                negotiatedRealm = realmTokens[ccb.getSelectedIndexes()[0]];
+                // Acquire realm from RealmChoiceCallback
+                int[] selected = ccb.getSelectedIndexes();
+                if (selected == null
+                        || selected[0] < 0
+                        || selected[0] >= realmTokens.length) {
+                    throw new SaslException("DIGEST-MD5: Invalid realm chosen");
+                }
+                negotiatedRealm = realmTokens[selected[0]];
             }
 
             passwd = pcb.getPassword();
             pcb.clearPassword();
             username = ncb.getName();
 
+        } catch (SaslException se) {
+            throw se;
+
         } catch (UnsupportedCallbackException e) {
             throw new SaslException("DIGEST-MD5: Cannot perform callback to " +
                 "acquire realm, authentication ID or password", e);
diff --git a/jdk/src/share/classes/com/sun/tools/jdi/AbstractLauncher.java b/jdk/src/share/classes/com/sun/tools/jdi/AbstractLauncher.java
index 1299201..736da0a 100644
--- a/jdk/src/share/classes/com/sun/tools/jdi/AbstractLauncher.java
+++ b/jdk/src/share/classes/com/sun/tools/jdi/AbstractLauncher.java
@@ -142,7 +142,7 @@
      * This class simply provides a context for a single launch and
      * accept. It provides instance fields that can be used by
      * all threads involved. This stuff can't be in the Connector proper
-     * because the connector is is a singleton and not specific to any
+     * because the connector is a singleton and is not specific to any
      * one launch.
      */
     private class Helper {
diff --git a/jdk/src/share/classes/com/sun/tools/jdi/SunCommandLineLauncher.java b/jdk/src/share/classes/com/sun/tools/jdi/SunCommandLineLauncher.java
index b5086fd..20be57c 100644
--- a/jdk/src/share/classes/com/sun/tools/jdi/SunCommandLineLauncher.java
+++ b/jdk/src/share/classes/com/sun/tools/jdi/SunCommandLineLauncher.java
@@ -213,7 +213,7 @@
                 exePath = exe;
             }
             // Quote only if necessary in case the quote arg value is bogus
-            if (hasWhitespace(exe)) {
+            if (hasWhitespace(exePath)) {
                 exePath = quote + exePath + quote;
             }
 
diff --git a/jdk/src/share/classes/java/awt/Component.java b/jdk/src/share/classes/java/awt/Component.java
index 0dfb999..846ea97 100644
--- a/jdk/src/share/classes/java/awt/Component.java
+++ b/jdk/src/share/classes/java/awt/Component.java
@@ -1671,6 +1671,15 @@
         /* do nothing */
     }
 
+    /*
+     * Delete references from LightweithDispatcher of a heavyweight parent
+     */
+    void clearLightweightDispatcherOnRemove(Component removedComponent) {
+        if (parent != null) {
+            parent.clearLightweightDispatcherOnRemove(removedComponent);
+        }
+    }
+
     /**
      * @deprecated As of JDK version 1.1,
      * replaced by <code>setVisible(boolean)</code>.
@@ -6974,6 +6983,8 @@
         }
 
         synchronized (getTreeLock()) {
+            clearLightweightDispatcherOnRemove(this);
+
             if (isFocusOwner() && KeyboardFocusManager.isAutoFocusTransferEnabledFor(this)) {
                 transferFocus(true);
             }
diff --git a/jdk/src/share/classes/java/awt/Container.java b/jdk/src/share/classes/java/awt/Container.java
index 1118852..1525a74 100644
--- a/jdk/src/share/classes/java/awt/Container.java
+++ b/jdk/src/share/classes/java/awt/Container.java
@@ -3306,6 +3306,16 @@
         }
     }
 
+    @Override
+    void clearLightweightDispatcherOnRemove(Component removedComponent) {
+        if (dispatcher != null) {
+            dispatcher.removeReferences(removedComponent);
+        } else {
+            //It is a Lightweight Container, should clear parent`s Dispatcher
+            super.clearLightweightDispatcherOnRemove(removedComponent);
+        }
+    }
+
     final Container getTraversalRoot() {
         if (isFocusCycleRoot()) {
             return findTraversalRoot();
@@ -4411,6 +4421,7 @@
         //System.out.println("Disposing lw dispatcher");
         stopListeningForOtherDrags();
         mouseEventTarget = null;
+        targetLastEntered = null;
     }
 
     /**
@@ -4502,6 +4513,7 @@
     // MOUSE_CLICKED.
     if (!isMouseGrab(e) && id != MouseEvent.MOUSE_CLICKED) {
             mouseEventTarget = (mouseOver != nativeContainer) ? mouseOver: null;
+            isCleaned = false;
         }
 
         if (mouseEventTarget != null) {
@@ -4545,10 +4557,14 @@
             retargetMouseEvent(mouseOver, id, e);
         break;
             }
-            //Consuming of wheel events is implemented in "retargetMouseEvent".
-            if (id != MouseEvent.MOUSE_WHEEL) {
-                e.consume();
-            }
+        //Consuming of wheel events is implemented in "retargetMouseEvent".
+        if (id != MouseEvent.MOUSE_WHEEL) {
+            e.consume();
+        }
+    } else if (isCleaned && id != MouseEvent.MOUSE_WHEEL) {
+        //After mouseEventTarget was removed and cleaned should consume all events
+        //until new mouseEventTarget is found
+        e.consume();
     }
     return e.isConsumed();
     }
@@ -4892,6 +4908,11 @@
     private transient Component targetLastEntered;
 
     /**
+     * Indicates whether {@code mouseEventTarget} was removed and nulled
+     */
+    private transient boolean isCleaned;
+
+    /**
      * Is the mouse over the native container
      */
     private transient boolean isMouseInNativeContainer = false;
@@ -4925,4 +4946,14 @@
         AWTEvent.MOUSE_EVENT_MASK |
         AWTEvent.MOUSE_MOTION_EVENT_MASK |
         AWTEvent.MOUSE_WHEEL_EVENT_MASK;
+
+    void removeReferences(Component removedComponent) {
+        if (mouseEventTarget == removedComponent) {
+            isCleaned = true;
+            mouseEventTarget = null;
+        }
+        if (targetLastEntered == removedComponent) {
+            targetLastEntered = null;
+        }
+    }
 }
diff --git a/jdk/src/share/classes/java/io/BufferedReader.java b/jdk/src/share/classes/java/io/BufferedReader.java
index 556abb2..d742233 100644
--- a/jdk/src/share/classes/java/io/BufferedReader.java
+++ b/jdk/src/share/classes/java/io/BufferedReader.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,13 @@
 package java.io;
 
 
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
 /**
  * Reads text from a character-input stream, buffering characters so as to
  * provide for the efficient reading of characters, arrays, and lines.
@@ -522,4 +529,64 @@
             }
         }
     }
+
+    /**
+     * Returns a {@code Stream}, the elements of which are lines read from
+     * this {@code BufferedReader}.  The {@link Stream} is lazily populated,
+     * i.e, read only occurs during the
+     * <a href="../util/stream/package-summary.html#StreamOps">terminal
+     * stream operation</a>.
+     *
+     * <p> The reader must not be operated on during the execution of the
+     * terminal stream operation. Otherwise, the result of the terminal stream
+     * operation is undefined.
+     *
+     * <p> After execution of the terminal stream operation there are no
+     * guarantees that the reader will be at a specific position from which to
+     * read the next character or line.
+     *
+     * <p> If an {@link IOException} is thrown when accessing the underlying
+     * {@code BufferedReader}, it is wrapped in an {@link
+     * UncheckedIOException} which will be thrown from the {@code Stream}
+     * method that caused the read to take place. This method will return a
+     * Stream if invoked on a BufferedReader that is closed. Any operation on
+     * that stream requires reading from the BufferedReader after is it closed
+     * will cause an UncheckedIOException to be thrown.
+     *
+     * @return a {@code Stream<String>} providing the lines of text
+     *         described by this {@code BufferedReader}
+     *
+     * @since 1.8
+     */
+    public Stream<String> lines() {
+        Iterator<String> iter = new Iterator<String>() {
+            String nextLine = null;
+
+            @Override
+            public boolean hasNext() {
+                if (nextLine != null) {
+                    return true;
+                } else {
+                    try {
+                        nextLine = readLine();
+                        return (nextLine != null);
+                    } catch (IOException e) {
+                        throw new UncheckedIOException(e);
+                    }
+                }
+            }
+
+            @Override
+            public String next() {
+                if (nextLine != null || hasNext()) {
+                    String line = nextLine;
+                    nextLine = null;
+                    return line;
+                } else {
+                    throw new NoSuchElementException();
+                }
+            }
+        };
+        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iter, Spliterator.ORDERED));
+    }
 }
diff --git a/jdk/src/share/classes/java/io/File.java b/jdk/src/share/classes/java/io/File.java
index dd313dd..1f1d044 100644
--- a/jdk/src/share/classes/java/io/File.java
+++ b/jdk/src/share/classes/java/io/File.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -156,7 +156,7 @@
     private static final FileSystem fs = DefaultFileSystem.getFileSystem();
 
     /**
-     * This abstract pathname's normalized pathname string.  A normalized
+     * This abstract pathname's normalized pathname string. A normalized
      * pathname string uses the default name-separator character and does not
      * contain any duplicate or redundant separators.
      *
@@ -165,6 +165,32 @@
     private final String path;
 
     /**
+     * Enum type that indicates the status of a file path.
+     */
+    private static enum PathStatus { INVALID, CHECKED };
+
+    /**
+     * The flag indicating whether the file path is invalid.
+     */
+    private transient PathStatus status = null;
+
+    /**
+     * Check if the file has an invalid path. Currently, the inspection of
+     * a file path is very limited, and it only covers Nul character check.
+     * Returning true means the path is definitely invalid/garbage. But
+     * returning false does not guarantee that the path is valid.
+     *
+     * @return true if the file path is invalid.
+     */
+    final boolean isInvalid() {
+        if (status == null) {
+            status = (this.path.indexOf('\u0000') < 0) ? PathStatus.CHECKED
+                                                       : PathStatus.INVALID;
+        }
+        return status == PathStatus.INVALID;
+    }
+
+    /**
      * The length of this abstract pathname's prefix, or zero if it has no
      * prefix.
      */
@@ -586,6 +612,9 @@
      * @see     Path#toRealPath
      */
     public String getCanonicalPath() throws IOException {
+        if (isInvalid()) {
+            throw new IOException("Invalid file path");
+        }
         return fs.canonicalize(fs.resolve(this));
     }
 
@@ -651,6 +680,9 @@
      */
     @Deprecated
     public URL toURL() throws MalformedURLException {
+        if (isInvalid()) {
+            throw new MalformedURLException("Invalid file path");
+        }
         return new URL("file", "", slashify(getAbsolutePath(), isDirectory()));
     }
 
@@ -730,6 +762,9 @@
         if (security != null) {
             security.checkRead(path);
         }
+        if (isInvalid()) {
+            return false;
+        }
         return fs.checkAccess(this, FileSystem.ACCESS_READ);
     }
 
@@ -755,6 +790,9 @@
         if (security != null) {
             security.checkWrite(path);
         }
+        if (isInvalid()) {
+            return false;
+        }
         return fs.checkAccess(this, FileSystem.ACCESS_WRITE);
     }
 
@@ -775,6 +813,9 @@
         if (security != null) {
             security.checkRead(path);
         }
+        if (isInvalid()) {
+            return false;
+        }
         return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0);
     }
 
@@ -802,6 +843,9 @@
         if (security != null) {
             security.checkRead(path);
         }
+        if (isInvalid()) {
+            return false;
+        }
         return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY)
                 != 0);
     }
@@ -832,6 +876,9 @@
         if (security != null) {
             security.checkRead(path);
         }
+        if (isInvalid()) {
+            return false;
+        }
         return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0);
     }
 
@@ -858,6 +905,9 @@
         if (security != null) {
             security.checkRead(path);
         }
+        if (isInvalid()) {
+            return false;
+        }
         return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0);
     }
 
@@ -887,6 +937,9 @@
         if (security != null) {
             security.checkRead(path);
         }
+        if (isInvalid()) {
+            return 0L;
+        }
         return fs.getLastModifiedTime(this);
     }
 
@@ -915,6 +968,9 @@
         if (security != null) {
             security.checkRead(path);
         }
+        if (isInvalid()) {
+            return 0L;
+        }
         return fs.getLength(this);
     }
 
@@ -950,6 +1006,9 @@
     public boolean createNewFile() throws IOException {
         SecurityManager security = System.getSecurityManager();
         if (security != null) security.checkWrite(path);
+        if (isInvalid()) {
+            throw new IOException("Invalid file path");
+        }
         return fs.createFileExclusively(path);
     }
 
@@ -976,6 +1035,9 @@
         if (security != null) {
             security.checkDelete(path);
         }
+        if (isInvalid()) {
+            return false;
+        }
         return fs.delete(this);
     }
 
@@ -1011,6 +1073,9 @@
         if (security != null) {
             security.checkDelete(path);
         }
+        if (isInvalid()) {
+            return;
+        }
         DeleteOnExitHook.add(path);
     }
 
@@ -1051,6 +1116,9 @@
         if (security != null) {
             security.checkRead(path);
         }
+        if (isInvalid()) {
+            return null;
+        }
         return fs.list(this);
     }
 
@@ -1242,6 +1310,9 @@
         if (security != null) {
             security.checkWrite(path);
         }
+        if (isInvalid()) {
+            return false;
+        }
         return fs.createDirectory(this);
     }
 
@@ -1317,6 +1388,12 @@
             security.checkWrite(path);
             security.checkWrite(dest.path);
         }
+        if (dest == null) {
+            throw new NullPointerException();
+        }
+        if (this.isInvalid() || dest.isInvalid()) {
+            return false;
+        }
         return fs.rename(this, dest);
     }
 
@@ -1352,6 +1429,9 @@
         if (security != null) {
             security.checkWrite(path);
         }
+        if (isInvalid()) {
+            return false;
+        }
         return fs.setLastModifiedTime(this, time);
     }
 
@@ -1379,6 +1459,9 @@
         if (security != null) {
             security.checkWrite(path);
         }
+        if (isInvalid()) {
+            return false;
+        }
         return fs.setReadOnly(this);
     }
 
@@ -1419,6 +1502,9 @@
         if (security != null) {
             security.checkWrite(path);
         }
+        if (isInvalid()) {
+            return false;
+        }
         return fs.setPermission(this, FileSystem.ACCESS_WRITE, writable, ownerOnly);
     }
 
@@ -1493,6 +1579,9 @@
         if (security != null) {
             security.checkWrite(path);
         }
+        if (isInvalid()) {
+            return false;
+        }
         return fs.setPermission(this, FileSystem.ACCESS_READ, readable, ownerOnly);
     }
 
@@ -1570,6 +1659,9 @@
         if (security != null) {
             security.checkWrite(path);
         }
+        if (isInvalid()) {
+            return false;
+        }
         return fs.setPermission(this, FileSystem.ACCESS_EXECUTE, executable, ownerOnly);
     }
 
@@ -1629,6 +1721,9 @@
         if (security != null) {
             security.checkExec(path);
         }
+        if (isInvalid()) {
+            return false;
+        }
         return fs.checkAccess(this, FileSystem.ACCESS_EXECUTE);
     }
 
@@ -1705,6 +1800,9 @@
             sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
             sm.checkRead(path);
         }
+        if (isInvalid()) {
+            return 0L;
+        }
         return fs.getSpace(this, FileSystem.SPACE_TOTAL);
     }
 
@@ -1721,7 +1819,7 @@
      * makes no guarantee that write operations to this file system
      * will succeed.
      *
-     * @return  The number of unallocated bytes on the partition <tt>0L</tt>
+     * @return  The number of unallocated bytes on the partition or <tt>0L</tt>
      *          if the abstract pathname does not name a partition.  This
      *          value will be less than or equal to the total file system size
      *          returned by {@link #getTotalSpace}.
@@ -1740,6 +1838,9 @@
             sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
             sm.checkRead(path);
         }
+        if (isInvalid()) {
+            return 0L;
+        }
         return fs.getSpace(this, FileSystem.SPACE_FREE);
     }
 
@@ -1778,6 +1879,9 @@
             sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
             sm.checkRead(path);
         }
+        if (isInvalid()) {
+            return 0L;
+        }
         return fs.getSpace(this, FileSystem.SPACE_USABLE);
     }
 
@@ -1787,8 +1891,8 @@
         private TempDirectory() { }
 
         // temporary directory location
-        private static final File tmpdir = new File(fs.normalize(AccessController
-            .doPrivileged(new GetPropertyAction("java.io.tmpdir"))));
+        private static final File tmpdir = new File(AccessController
+            .doPrivileged(new GetPropertyAction("java.io.tmpdir")));
         static File location() {
             return tmpdir;
         }
@@ -1899,6 +2003,9 @@
                     throw se;
                 }
             }
+            if (f.isInvalid()) {
+                throw new IOException("Unable to create temporary file");
+            }
         } while (!fs.createFileExclusively(f.getPath()));
         return f;
     }
diff --git a/jdk/src/share/classes/java/io/FileInputStream.java b/jdk/src/share/classes/java/io/FileInputStream.java
index d796bf0..740b674 100644
--- a/jdk/src/share/classes/java/io/FileInputStream.java
+++ b/jdk/src/share/classes/java/io/FileInputStream.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -123,6 +123,9 @@
         if (name == null) {
             throw new NullPointerException();
         }
+        if (file.isInvalid()) {
+            throw new FileNotFoundException("Invalid file path");
+        }
         fd = new FileDescriptor();
         fd.attach(this);
         open(name);
diff --git a/jdk/src/share/classes/java/io/FileOutputStream.java b/jdk/src/share/classes/java/io/FileOutputStream.java
index 50bd29b..928e4f3 100644
--- a/jdk/src/share/classes/java/io/FileOutputStream.java
+++ b/jdk/src/share/classes/java/io/FileOutputStream.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -196,6 +196,9 @@
         if (name == null) {
             throw new NullPointerException();
         }
+        if (file.isInvalid()) {
+            throw new FileNotFoundException("Invalid file path");
+        }
         this.fd = new FileDescriptor();
         fd.attach(this);
         this.append = append;
diff --git a/jdk/src/share/classes/java/io/RandomAccessFile.java b/jdk/src/share/classes/java/io/RandomAccessFile.java
index cf1e5c7..adccfbc 100644
--- a/jdk/src/share/classes/java/io/RandomAccessFile.java
+++ b/jdk/src/share/classes/java/io/RandomAccessFile.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -228,6 +228,9 @@
         if (name == null) {
             throw new NullPointerException();
         }
+        if (file.isInvalid()) {
+            throw new FileNotFoundException("Invalid file path");
+        }
         fd = new FileDescriptor();
         fd.attach(this);
         open(name, imode);
diff --git a/jdk/src/share/classes/java/io/UncheckedIOException.java b/jdk/src/share/classes/java/io/UncheckedIOException.java
new file mode 100644
index 0000000..22c43e3
--- /dev/null
+++ b/jdk/src/share/classes/java/io/UncheckedIOException.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012, 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.io;
+
+import java.util.Objects;
+
+/**
+ * Wraps an {@link IOException} with an unchecked exception.
+ *
+ * @since   1.8
+ */
+public class UncheckedIOException extends RuntimeException {
+    private static final long serialVersionUID = -8134305061645241065L;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   message
+     *          the detail message, can be null
+     * @param   cause
+     *          the {@code IOException}
+     *
+     * @throws  NullPointerException
+     *          if the cause is {@code null}
+     */
+    public UncheckedIOException(String message, IOException cause) {
+        super(message, Objects.requireNonNull(cause));
+    }
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   cause
+     *          the {@code IOException}
+     *
+     * @throws  NullPointerException
+     *          if the cause is {@code null}
+     */
+    public UncheckedIOException(IOException cause) {
+        super(Objects.requireNonNull(cause));
+    }
+
+    /**
+     * Returns the cause of this exception.
+     *
+     * @return  the {@code IOException} which is the cause of this exception.
+     */
+    @Override
+    public IOException getCause() {
+        return (IOException) super.getCause();
+    }
+
+    /**
+     * Called to read the object from a stream.
+     *
+     * @throws  InvalidObjectException
+     *          if the object is invalid or has a cause that is not
+     *          an {@code IOException}
+     */
+    private void readObject(ObjectInputStream s)
+        throws IOException, ClassNotFoundException
+    {
+        s.defaultReadObject();
+        Throwable cause = super.getCause();
+        if (!(cause instanceof IOException))
+            throw new InvalidObjectException("Cause must be an IOException");
+    }
+}
diff --git a/jdk/src/share/classes/java/lang/ProcessBuilder.java b/jdk/src/share/classes/java/lang/ProcessBuilder.java
index 64f56d7..b467f45 100644
--- a/jdk/src/share/classes/java/lang/ProcessBuilder.java
+++ b/jdk/src/share/classes/java/lang/ProcessBuilder.java
@@ -29,7 +29,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.io.FileOutputStream;
 import java.security.AccessControlException;
 import java.util.Arrays;
 import java.util.ArrayList;
@@ -1024,10 +1023,10 @@
                                      dir,
                                      redirects,
                                      redirectErrorStream);
-        } catch (IOException e) {
+        } catch (IOException | IllegalArgumentException e) {
             String exceptionInfo = ": " + e.getMessage();
             Throwable cause = e;
-            if (security != null) {
+            if ((e instanceof IOException) && security != null) {
                 // Can not disclose the fail reason for read-protected files.
                 try {
                     security.checkRead(prog);
diff --git a/jdk/src/share/classes/java/lang/StringBuffer.java b/jdk/src/share/classes/java/lang/StringBuffer.java
index f31a53c..8ead072 100644
--- a/jdk/src/share/classes/java/lang/StringBuffer.java
+++ b/jdk/src/share/classes/java/lang/StringBuffer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -25,6 +25,7 @@
 
 package java.lang;
 
+import java.util.Arrays;
 
 /**
  * A thread-safe, mutable sequence of characters.
@@ -98,6 +99,12 @@
     implements java.io.Serializable, CharSequence
 {
 
+    /**
+     * A cache of the last value returned by toString. Cleared
+     * whenever the StringBuffer is modified.
+     */
+    private transient char[] toStringCache;
+
     /** use serialVersionUID from JDK 1.0.2 for interoperability */
     static final long serialVersionUID = 3388685877147921107L;
 
@@ -183,6 +190,7 @@
      */
     @Override
     public synchronized void setLength(int newLength) {
+        toStringCache = null;
         super.setLength(newLength);
     }
 
@@ -247,17 +255,20 @@
     public synchronized void setCharAt(int index, char ch) {
         if ((index < 0) || (index >= count))
             throw new StringIndexOutOfBoundsException(index);
+        toStringCache = null;
         value[index] = ch;
     }
 
     @Override
     public synchronized StringBuffer append(Object obj) {
+        toStringCache = null;
         super.append(String.valueOf(obj));
         return this;
     }
 
     @Override
     public synchronized StringBuffer append(String str) {
+        toStringCache = null;
         super.append(str);
         return this;
     }
@@ -287,6 +298,7 @@
      * @since 1.4
      */
     public synchronized StringBuffer append(StringBuffer sb) {
+        toStringCache = null;
         super.append(sb);
         return this;
     }
@@ -296,6 +308,7 @@
      */
     @Override
     synchronized StringBuffer append(AbstractStringBuilder asb) {
+        toStringCache = null;
         super.append(asb);
         return this;
     }
@@ -325,6 +338,7 @@
     public StringBuffer append(CharSequence s) {
         // Note, synchronization achieved via invocations of other StringBuffer methods after
         // narrowing of s to specific type
+        // Ditto for toStringCache clearing
         super.append(s);
         return this;
     }
@@ -336,12 +350,14 @@
     @Override
     public synchronized StringBuffer append(CharSequence s, int start, int end)
     {
+        toStringCache = null;
         super.append(s, start, end);
         return this;
     }
 
     @Override
     public synchronized StringBuffer append(char[] str) {
+        toStringCache = null;
         super.append(str);
         return this;
     }
@@ -351,24 +367,28 @@
      */
     @Override
     public synchronized StringBuffer append(char[] str, int offset, int len) {
+        toStringCache = null;
         super.append(str, offset, len);
         return this;
     }
 
     @Override
     public synchronized StringBuffer append(boolean b) {
+        toStringCache = null;
         super.append(b);
         return this;
     }
 
     @Override
     public synchronized StringBuffer append(char c) {
+        toStringCache = null;
         super.append(c);
         return this;
     }
 
     @Override
     public synchronized StringBuffer append(int i) {
+        toStringCache = null;
         super.append(i);
         return this;
     }
@@ -378,24 +398,28 @@
      */
     @Override
     public synchronized StringBuffer appendCodePoint(int codePoint) {
+        toStringCache = null;
         super.appendCodePoint(codePoint);
         return this;
     }
 
     @Override
     public synchronized StringBuffer append(long lng) {
+        toStringCache = null;
         super.append(lng);
         return this;
     }
 
     @Override
     public synchronized StringBuffer append(float f) {
+        toStringCache = null;
         super.append(f);
         return this;
     }
 
     @Override
     public synchronized StringBuffer append(double d) {
+        toStringCache = null;
         super.append(d);
         return this;
     }
@@ -406,6 +430,7 @@
      */
     @Override
     public synchronized StringBuffer delete(int start, int end) {
+        toStringCache = null;
         super.delete(start, end);
         return this;
     }
@@ -416,6 +441,7 @@
      */
     @Override
     public synchronized StringBuffer deleteCharAt(int index) {
+        toStringCache = null;
         super.deleteCharAt(index);
         return this;
     }
@@ -426,6 +452,7 @@
      */
     @Override
     public synchronized StringBuffer replace(int start, int end, String str) {
+        toStringCache = null;
         super.replace(start, end, str);
         return this;
     }
@@ -465,6 +492,7 @@
     public synchronized StringBuffer insert(int index, char[] str, int offset,
                                             int len)
     {
+        toStringCache = null;
         super.insert(index, str, offset, len);
         return this;
     }
@@ -474,6 +502,7 @@
      */
     @Override
     public synchronized StringBuffer insert(int offset, Object obj) {
+        toStringCache = null;
         super.insert(offset, String.valueOf(obj));
         return this;
     }
@@ -483,6 +512,7 @@
      */
     @Override
     public synchronized StringBuffer insert(int offset, String str) {
+        toStringCache = null;
         super.insert(offset, str);
         return this;
     }
@@ -492,6 +522,7 @@
      */
     @Override
     public synchronized StringBuffer insert(int offset, char[] str) {
+        toStringCache = null;
         super.insert(offset, str);
         return this;
     }
@@ -504,6 +535,7 @@
     public StringBuffer insert(int dstOffset, CharSequence s) {
         // Note, synchronization achieved via invocations of other StringBuffer methods
         // after narrowing of s to specific type
+        // Ditto for toStringCache clearing
         super.insert(dstOffset, s);
         return this;
     }
@@ -516,6 +548,7 @@
     public synchronized StringBuffer insert(int dstOffset, CharSequence s,
             int start, int end)
     {
+        toStringCache = null;
         super.insert(dstOffset, s, start, end);
         return this;
     }
@@ -527,6 +560,7 @@
     public  StringBuffer insert(int offset, boolean b) {
         // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
         // after conversion of b to String by super class method
+        // Ditto for toStringCache clearing
         super.insert(offset, b);
         return this;
     }
@@ -536,6 +570,7 @@
      */
     @Override
     public synchronized StringBuffer insert(int offset, char c) {
+        toStringCache = null;
         super.insert(offset, c);
         return this;
     }
@@ -547,6 +582,7 @@
     public StringBuffer insert(int offset, int i) {
         // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
         // after conversion of i to String by super class method
+        // Ditto for toStringCache clearing
         super.insert(offset, i);
         return this;
     }
@@ -558,6 +594,7 @@
     public StringBuffer insert(int offset, long l) {
         // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
         // after conversion of l to String by super class method
+        // Ditto for toStringCache clearing
         super.insert(offset, l);
         return this;
     }
@@ -569,6 +606,7 @@
     public StringBuffer insert(int offset, float f) {
         // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
         // after conversion of f to String by super class method
+        // Ditto for toStringCache clearing
         super.insert(offset, f);
         return this;
     }
@@ -580,6 +618,7 @@
     public StringBuffer insert(int offset, double d) {
         // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
         // after conversion of d to String by super class method
+        // Ditto for toStringCache clearing
         super.insert(offset, d);
         return this;
     }
@@ -623,13 +662,17 @@
      */
     @Override
     public synchronized StringBuffer reverse() {
+        toStringCache = null;
         super.reverse();
         return this;
     }
 
     @Override
     public synchronized String toString() {
-        return new String(value, 0, count);
+        if (toStringCache == null) {
+            toStringCache = Arrays.copyOfRange(value, 0, count);
+        }
+        return new String(toStringCache, true);
     }
 
     /**
diff --git a/jdk/src/share/classes/java/lang/System.java b/jdk/src/share/classes/java/lang/System.java
index c7f69f5..bd72188 100644
--- a/jdk/src/share/classes/java/lang/System.java
+++ b/jdk/src/share/classes/java/lang/System.java
@@ -1246,6 +1246,9 @@
             public StackTraceElement getStackTraceElement(Throwable t, int i) {
                 return t.getStackTraceElement(i);
             }
+            public String newStringUnsafe(char[] chars) {
+                return new String(chars, true);
+            }
         });
     }
 }
diff --git a/jdk/src/share/classes/java/lang/invoke/MemberName.java b/jdk/src/share/classes/java/lang/invoke/MemberName.java
index 5909601..dfb4684 100644
--- a/jdk/src/share/classes/java/lang/invoke/MemberName.java
+++ b/jdk/src/share/classes/java/lang/invoke/MemberName.java
@@ -236,6 +236,8 @@
             assert(MethodHandleNatives.refKindIsMethod(refKind));
             if (clazz.isInterface())
                 assert(refKind == REF_invokeInterface ||
+                       refKind == REF_invokeStatic    ||
+                       refKind == REF_invokeSpecial   ||
                        refKind == REF_invokeVirtual && isObjectPublicMethod());
         } else {
             assert(false);
@@ -268,7 +270,7 @@
             assert(refKind == REF_invokeSpecial) : this;
             return true;
         }
-        assert(false) : this;
+        assert(false) : this+" != "+MethodHandleNatives.refKindName((byte)originalRefKind);
         return true;
     }
     private boolean staticIsConsistent() {
@@ -485,14 +487,19 @@
         if (this.type == null)
             this.type = new Object[] { m.getReturnType(), m.getParameterTypes() };
         if (wantSpecial) {
+            assert(!isAbstract()) : this;
             if (getReferenceKind() == REF_invokeVirtual)
                 changeReferenceKind(REF_invokeSpecial, REF_invokeVirtual);
+            else if (getReferenceKind() == REF_invokeInterface)
+                // invokeSpecial on a default method
+                changeReferenceKind(REF_invokeSpecial, REF_invokeInterface);
         }
     }
     public MemberName asSpecial() {
         switch (getReferenceKind()) {
         case REF_invokeSpecial:     return this;
         case REF_invokeVirtual:     return clone().changeReferenceKind(REF_invokeSpecial, REF_invokeVirtual);
+        case REF_invokeInterface:   return clone().changeReferenceKind(REF_invokeSpecial, REF_invokeInterface);
         case REF_newInvokeSpecial:  return clone().changeReferenceKind(REF_invokeSpecial, REF_newInvokeSpecial);
         }
         throw new IllegalArgumentException(this.toString());
diff --git a/jdk/src/share/classes/java/lang/reflect/Executable.java b/jdk/src/share/classes/java/lang/reflect/Executable.java
index 78a1db9..00e08a6 100644
--- a/jdk/src/share/classes/java/lang/reflect/Executable.java
+++ b/jdk/src/share/classes/java/lang/reflect/Executable.java
@@ -486,8 +486,8 @@
     }
 
     /**
-     * Returns an AnnotatedType object that represents the potentially
-     * annotated return type of the method/constructor represented by this
+     * Returns an AnnotatedType object that represents the use of a type to
+     * specify the return type of the method/constructor represented by this
      * Executable.
      *
      * If this Executable represents a constructor, the AnnotatedType object
@@ -510,12 +510,12 @@
      */
     AnnotatedType getAnnotatedReturnType0(Type returnType) {
         return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes(),
-                                                       sun.misc.SharedSecrets.getJavaLangAccess().
-                                                           getConstantPool(getDeclaringClass()),
-                                                       this,
-                                                       getDeclaringClass(),
-                                                       returnType,
-                                                       TypeAnnotation.TypeAnnotationTarget.METHOD_RETURN_TYPE);
+                sun.misc.SharedSecrets.getJavaLangAccess().
+                        getConstantPool(getDeclaringClass()),
+                this,
+                getDeclaringClass(),
+                returnType,
+                TypeAnnotation.TypeAnnotationTarget.METHOD_RETURN);
     }
 
     /**
@@ -535,12 +535,12 @@
      */
     public AnnotatedType getAnnotatedReceiverType() {
         return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes(),
-                                                       sun.misc.SharedSecrets.getJavaLangAccess().
-                                                           getConstantPool(getDeclaringClass()),
-                                                       this,
-                                                       getDeclaringClass(),
-                                                       getDeclaringClass(),
-                                                       TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER_TYPE);
+                sun.misc.SharedSecrets.getJavaLangAccess().
+                        getConstantPool(getDeclaringClass()),
+                this,
+                getDeclaringClass(),
+                getDeclaringClass(),
+                TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER);
     }
 
     /**
@@ -556,7 +556,13 @@
      * @since 1.8
      */
     public AnnotatedType[] getAnnotatedParameterTypes() {
-        throw new UnsupportedOperationException("Not yet");
+        return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes(),
+                sun.misc.SharedSecrets.getJavaLangAccess().
+                        getConstantPool(getDeclaringClass()),
+                this,
+                getDeclaringClass(),
+                getParameterTypes(),
+                TypeAnnotation.TypeAnnotationTarget.METHOD_FORMAL_PARAMETER);
     }
 
     /**
@@ -573,12 +579,12 @@
      */
     public AnnotatedType[] getAnnotatedExceptionTypes() {
         return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes(),
-                                                        sun.misc.SharedSecrets.getJavaLangAccess().
-                                                            getConstantPool(getDeclaringClass()),
-                                                        this,
-                                                        getDeclaringClass(),
-                                                        getGenericExceptionTypes(),
-                                                        TypeAnnotation.TypeAnnotationTarget.THROWS);
+                sun.misc.SharedSecrets.getJavaLangAccess().
+                        getConstantPool(getDeclaringClass()),
+                this,
+                getDeclaringClass(),
+                getGenericExceptionTypes(),
+                TypeAnnotation.TypeAnnotationTarget.THROWS);
     }
 
 }
diff --git a/jdk/src/share/classes/java/lang/reflect/Field.java b/jdk/src/share/classes/java/lang/reflect/Field.java
index a25223f..8b2603a 100644
--- a/jdk/src/share/classes/java/lang/reflect/Field.java
+++ b/jdk/src/share/classes/java/lang/reflect/Field.java
@@ -1161,6 +1161,6 @@
                                                        this,
                                                        getDeclaringClass(),
                                                        getGenericType(),
-                                                       TypeAnnotation.TypeAnnotationTarget.FIELD_TYPE);
+                                                       TypeAnnotation.TypeAnnotationTarget.FIELD);
 }
 }
diff --git a/jdk/src/share/classes/java/lang/reflect/Modifier.java b/jdk/src/share/classes/java/lang/reflect/Modifier.java
index 227beee..7387bbe 100644
--- a/jdk/src/share/classes/java/lang/reflect/Modifier.java
+++ b/jdk/src/share/classes/java/lang/reflect/Modifier.java
@@ -350,8 +350,19 @@
       return (mod & MANDATED) != 0;
     }
 
+    // Note on the FOO_MODIFIERS fields and fooModifiers() methods:
+    // the sets of modifiers are not guaranteed to be constants
+    // across time and Java SE releases. Therefore, it would not be
+    // appropriate to expose an external interface to this information
+    // that would allow the values to be treated as Java-level
+    // constants since the values could be constant folded and updates
+    // to the sets of modifiers missed. Thus, the fooModifiers()
+    // methods return an unchanging values for a given release, but a
+    // value that can potentially change over time.
+
     /**
-     * See JLSv3 section 8.1.1.
+     * The Java source modifiers that can be applied to a class.
+     * @jls 8.1.1 Class Modifiers
      */
     private static final int CLASS_MODIFIERS =
         Modifier.PUBLIC         | Modifier.PROTECTED    | Modifier.PRIVATE |
@@ -359,7 +370,8 @@
         Modifier.STRICT;
 
     /**
-     * See JLSv3 section 9.1.1.
+     * The Java source modifiers that can be applied to an interface.
+     * @jls 9.1.1 Interface Modifiers
      */
     private static final int INTERFACE_MODIFIERS =
         Modifier.PUBLIC         | Modifier.PROTECTED    | Modifier.PRIVATE |
@@ -367,13 +379,15 @@
 
 
     /**
-     * See JLSv3 section 8.8.3.
+     * The Java source modifiers that can be applied to a constructor.
+     * @jls 8.8.3 Constructor Modifiers
      */
     private static final int CONSTRUCTOR_MODIFIERS =
         Modifier.PUBLIC         | Modifier.PROTECTED    | Modifier.PRIVATE;
 
     /**
-     * See JLSv3 section 8.4.3.
+     * The Java source modifiers that can be applied to a method.
+     * @jls8.4.3  Method Modifiers
      */
     private static final int METHOD_MODIFIERS =
         Modifier.PUBLIC         | Modifier.PROTECTED    | Modifier.PRIVATE |
@@ -381,7 +395,8 @@
         Modifier.SYNCHRONIZED   | Modifier.NATIVE       | Modifier.STRICT;
 
     /**
-     * See JLSv3 section 8.3.1.
+     * The Java source modifiers that can be applied to a field.
+     * @jls 8.3.1  Field Modifiers
      */
     private static final int FIELD_MODIFIERS =
         Modifier.PUBLIC         | Modifier.PROTECTED    | Modifier.PRIVATE |
@@ -389,6 +404,13 @@
         Modifier.VOLATILE;
 
     /**
+     * The Java source modifiers that can be applied to a method or constructor parameter.
+     * @jls 8.4.1 Formal Parameters
+     */
+    private static final int PARAMETER_MODIFIERS =
+        Modifier.FINAL;
+
+    /**
      *
      */
     static final int ACCESS_MODIFIERS =
@@ -411,7 +433,7 @@
      * Return an {@code int} value OR-ing together the source language
      * modifiers that can be applied to an interface.
      * @return an {@code int} value OR-ing together the source language
-     * modifiers that can be applied to an inteface.
+     * modifiers that can be applied to an interface.
      *
      * @jls 9.1.1 Interface Modifiers
      * @since 1.7
@@ -446,7 +468,6 @@
         return METHOD_MODIFIERS;
     }
 
-
     /**
      * Return an {@code int} value OR-ing together the source language
      * modifiers that can be applied to a field.
@@ -459,4 +480,17 @@
     public static int fieldModifiers() {
         return FIELD_MODIFIERS;
     }
+
+    /**
+     * Return an {@code int} value OR-ing together the source language
+     * modifiers that can be applied to a parameter.
+     * @return an {@code int} value OR-ing together the source language
+     * modifiers that can be applied to a parameter.
+     *
+     * @jls 8.4.1 Formal Parameters
+     * @since 1.8
+     */
+    public static int parameterModifiers() {
+        return PARAMETER_MODIFIERS;
+    }
 }
diff --git a/jdk/src/share/classes/java/lang/reflect/Parameter.java b/jdk/src/share/classes/java/lang/reflect/Parameter.java
index 57097e0..c50e0fe 100644
--- a/jdk/src/share/classes/java/lang/reflect/Parameter.java
+++ b/jdk/src/share/classes/java/lang/reflect/Parameter.java
@@ -200,6 +200,19 @@
         return tmp;
     }
 
+    /**
+     * Returns an AnnotatedType object that represents the use of a type to
+     * specify the type of the formal parameter represented by this Parameter.
+     *
+     * @return an {@code AnnotatedType} object representing the use of a type
+     *         to specify the type of the formal parameter represented by this
+     *         Parameter
+     */
+    public AnnotatedType getAnnotatedType() {
+        // no caching for now
+        return executable.getAnnotatedParameterTypes()[index];
+    }
+
     private transient volatile Class<?> parameterClassCache = null;
 
     /**
diff --git a/jdk/src/share/classes/java/lang/reflect/Proxy.java b/jdk/src/share/classes/java/lang/reflect/Proxy.java
index 49dc21d..7b3d90f 100644
--- a/jdk/src/share/classes/java/lang/reflect/Proxy.java
+++ b/jdk/src/share/classes/java/lang/reflect/Proxy.java
@@ -31,6 +31,7 @@
 import java.util.Arrays;
 import java.util.IdentityHashMap;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.BiFunction;
 import sun.misc.ProxyGenerator;
@@ -255,9 +256,13 @@
      * (typically, a dynamic proxy class) with the specified value
      * for its invocation handler.
      *
-     * @param   h the invocation handler for this proxy instance
+     * @param  h the invocation handler for this proxy instance
+     *
+     * @throws NullPointerException if the given invocation handler, {@code h},
+     *         is {@code null}.
      */
     protected Proxy(InvocationHandler h) {
+        Objects.requireNonNull(h);
         this.h = h;
     }
 
@@ -698,9 +703,7 @@
                                           InvocationHandler h)
         throws IllegalArgumentException
     {
-        if (h == null) {
-            throw new NullPointerException();
-        }
+        Objects.requireNonNull(h);
 
         final SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
diff --git a/jdk/src/share/classes/java/net/HttpURLConnection.java b/jdk/src/share/classes/java/net/HttpURLConnection.java
index d52c267..193b9ce 100644
--- a/jdk/src/share/classes/java/net/HttpURLConnection.java
+++ b/jdk/src/share/classes/java/net/HttpURLConnection.java
@@ -50,6 +50,18 @@
  * <a href="doc-files/net-properties.html#Proxies">Proxy settings</a> as well as
  * <a href="doc-files/net-properties.html#MiscHTTP"> various other settings</a>.
  * </P>
+ * <p>
+ * <b>Security permissions</b>
+ * <p>
+ * If a security manager is installed, and if a method is called which results in an
+ * attempt to open a connection, the caller must possess either:-
+ * <ul><li>a "connect" {@link SocketPermission} to the host/port combination of the
+ * destination URL or</li>
+ * <li>a {@link HttpURLPermission} that permits this request.</li>
+ * </ul><p>
+ * If automatic redirection is enabled, and this request is redirected to another
+ * destination, then the caller must also have permission to connect to the
+ * redirected host/URL.
  *
  * @see     java.net.HttpURLConnection#disconnect()
  * @since JDK1.1
diff --git a/jdk/src/share/classes/java/net/HttpURLPermission.java b/jdk/src/share/classes/java/net/HttpURLPermission.java
new file mode 100644
index 0000000..52d6e79
--- /dev/null
+++ b/jdk/src/share/classes/java/net/HttpURLPermission.java
@@ -0,0 +1,406 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.ObjectInputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.security.Permission;
+
+/**
+ * Represents permission to access a resource or set of resources defined by a
+ * given http or https url, and for a given set of user-settable request methods
+ * and request headers. The <i>name</i> of the permission is the url string.
+ * The <i>actions</i> string is a concatenation of the request methods and headers.
+ * The range of method and header names is not restricted by this class.
+ * <p><b>The url</b><p>
+ * The url string is also used to instantiate a {@link URI} object which is
+ * used for comparison with other HttpURLPermission instances. Therefore, any
+ * references in this specification to url, mean this URI object.
+ * The path component of the url comprises a sequence of path segments, separated
+ * by '/' characters. The path is specified in a similar way to the path
+ * in {@link java.io.FilePermission}. There are three different ways
+ * as the following examples show:
+ * <table border>
+ * <tr><th>Example url</th><th>Description</th></tr>
+ * <tr><td style="white-space:nowrap;">http://www.oracle.com/a/b/c.html</td>
+ *   <td>A url which identifies a specific (single) resource</td>
+ * </tr>
+ * <tr><td>http://www.oracle.com/a/b/*</td>
+ *   <td>The '*' character refers to all resources in the same "directory" - in
+ *       other words all resources with the same number of path components, and
+ *       which only differ in the final path component, represented by the '*'.
+ *   </td>
+ * </tr>
+ * <tr><td>http://www.oracle.com/a/b/-</li>
+ *   <td>The '-' character refers to all resources recursively below the
+ *       preceding path (eg. http://www.oracle.com/a/b/c/d/e.html matches this
+ *       example).
+ *   </td>
+ * </tr>
+ * </table>
+ * <p>
+ * The '*' and '-' may only be specified in the final segment of a path and must be
+ * the only character in that segment. Any query or fragment components of the
+ * url are ignored when constructing HttpURLPermissions.
+ * <p>
+ * As a special case, urls of the form, "http:*" or "https:*" are accepted to
+ * mean any url of the given scheme.
+ * <p><b>The actions string</b><p>
+ * The actions string of a HttpURLPermission is a concatenation of the <i>method list</i>
+ * and the <i>request headers list</i>. These are lists of the permitted HTTP request
+ * methods and permitted request headers of the permission (respectively). The two lists
+ * are separated by a colon ':' character and elements of each list are comma separated.
+ * Some examples are:
+ * <pre>
+ *         "POST,GET,DELETE"
+ *         "GET:X-Foo-Request,X-Bar-Request"
+ *         "POST,GET:Header1,Header2"
+ * </pre>
+ * The first example specifies the methods: POST, GET and DELETE, but no request headers.
+ * The second example specifies one request method and two headers. The third
+ * example specifies two request methods, and two headers.
+ * <p>
+ * The colon separator need not be present if the request headers list is empty.
+ * No white-space is permitted in the actions string. The action strings supplied to
+ * the HttpURLPermission constructors are case-insensitive and are normalized by converting
+ * method names to upper-case and header names to the form defines in RFC2616 (lower case
+ * with initial letter of each word capitalized). Either list can contain a wild-card '*'
+ * character which signifies all request methods or headers respectively.
+ * <p>
+ * Note. Depending on the context of use, some request methods and headers may be permitted
+ * at all times, and others may not be permitted at any time. For example, the
+ * HTTP protocol handler might disallow certain headers such as Content-Length
+ * from being set by application code, regardless of whether the security policy
+ * in force, permits it.
+ *
+ * @since 1.8
+ */
+public final class HttpURLPermission extends Permission {
+
+    private static final long serialVersionUID = -2702463814894478682L;
+
+    private transient URI uri;
+    private transient List<String> methods;
+    private transient List<String> requestHeaders;
+
+    // serialized field
+    private String actions;
+
+    /**
+     * Creates a new HttpURLPermission from a url string and which permits the given
+     * request methods and user-settable request headers.
+     * The name of the permission is its url string. Only the scheme, authority
+     * and path components of the url are used. Any fragment or query
+     * components are ignored. The permissions action string is as specified above.
+     *
+     * @param url the url string
+     *
+     * @param actions the actions string
+     *
+     * @throws    IllegalArgumentException if url does not result in a valid {@link URI},
+     *            its scheme is not http or https, or if actions contains white-space.
+     */
+    public HttpURLPermission(String url, String actions) {
+        super(url);
+        init(actions);
+    }
+
+    private void init(String actions) {
+        URI uri = parseURI(getName());
+        int colon = actions.indexOf(':');
+        if (actions.lastIndexOf(':') != colon) {
+            throw new IllegalArgumentException("invalid actions string");
+        }
+
+        String methods, headers;
+        if (colon == -1) {
+            methods = actions;
+            headers = "";
+        } else {
+            methods = actions.substring(0, colon);
+            headers = actions.substring(colon+1);
+        }
+
+        List<String> l = normalizeMethods(methods);
+        Collections.sort(l);
+        this.methods = Collections.unmodifiableList(l);
+
+        l = normalizeHeaders(headers);
+        Collections.sort(l);
+        this.requestHeaders = Collections.unmodifiableList(l);
+
+        this.actions = actions();
+        this.uri = uri;
+    }
+
+    /**
+     * Creates a HttpURLPermission with the given url string and unrestricted
+     * methods and request headers by invoking the two argument
+     * constructor as follows: HttpURLPermission(url, "*:*")
+     *
+     * @throws    IllegalArgumentException if url does not result in a valid {@link URI}
+     */
+    public HttpURLPermission(String url) {
+        this(url, "*:*");
+    }
+
+    /**
+     * Returns the normalized method list and request
+     * header list, in the form:
+     * <pre>
+     *      "method-names : header-names"
+     * </pre>
+     * <p>
+     * where method-names is the list of methods separated by commas
+     * and header-names is the list of permitted headers separated by commas.
+     * There is no white space in the returned String. If header-names is empty
+     * then the colon separator will not be present.
+     */
+    public String getActions() {
+        return actions;
+    }
+
+    /**
+     * Checks if this HttpURLPermission implies the given permission.
+     * Specifically, the following checks are done as if in the
+     * following sequence:
+     * <p><ul>
+     * <li>if 'p' is not an instance of HttpURLPermission return false</li>
+     * <li>if any of p's methods are not in this's method list, and if
+     *     this's method list is not equal to "*", then return false.</li>
+     * <li>if any of p's headers are not in this's request header list, and if
+     *     this's request header list is not equal to "*", then return false.</li>
+     * <li>if this's url is equal to p's url , then return true</li>
+     * <li>if this's url scheme is not equal to p's url scheme return false</li>
+     * <li>if the scheme specific part of this's url is '*' return true</li>
+     * <li>if this's url authority is not equal to p's url authority
+     *     return false</li>
+     * <li>if the path or paths specified by p's url are contained in the
+     *     set of paths specified by this's url, then return true
+     * <li>otherwise, return false</li>
+     * </ol>
+     * <p>
+     * Some examples of how paths are matched are shown below:
+     * <p>
+     * <table border>
+     * <tr><th>this's path</th><th>p's path</th><th>match</th></tr>
+     * <tr><td>/a/b</td><td>/a/b</td><td>yes</td></tr>
+     * <tr><td>/a/b/*</td><td>/a/b/c</td><td>yes</td></tr>
+     * <tr><td>/a/b/*</td><td>/a/b/c/d</td><td>no</td></tr>
+     * <tr><td>/a/b/-</td><td>/a/b/c/d</td><td>yes</td></tr>
+     * <tr><td>/a/b/-</td><td>/a/b/c/d/e</td><td>yes</td></tr>
+     * <tr><td>/a/b/-</td><td>/a/b/c/*</td><td>yes</td></tr>
+     * <tr><td>/a/b/*</td><td>/a/b/c/-</td><td>no</td></tr>
+     * </table>
+     */
+    public boolean implies(Permission p) {
+        if (! (p instanceof HttpURLPermission)) {
+            return false;
+        }
+
+        HttpURLPermission that = (HttpURLPermission)p;
+
+        if (!this.methods.get(0).equals("*") &&
+                Collections.indexOfSubList(this.methods, that.methods) == -1) {
+            return false;
+        }
+
+        if (this.requestHeaders.isEmpty() && !that.requestHeaders.isEmpty()) {
+            return false;
+        }
+
+        if (!this.requestHeaders.isEmpty() &&
+            !this.requestHeaders.get(0).equals("*") &&
+             Collections.indexOfSubList(this.requestHeaders,
+                                        that.requestHeaders) == -1) {
+            return false;
+        }
+
+        if (this.uri.equals(that.uri)) {
+            return true;
+        }
+
+        if (!this.uri.getScheme().equals(that.uri.getScheme())) {
+            return false;
+        }
+
+        if (this.uri.getSchemeSpecificPart().equals("*")) {
+            return true;
+        }
+
+        String thisAuthority = this.uri.getAuthority();
+
+            if (thisAuthority != null &&
+                    !thisAuthority.equals(that.uri.getAuthority())) {
+            return false;
+        }
+
+        String thispath = this.uri.getPath();
+        String thatpath = that.uri.getPath();
+
+        if (thispath.endsWith("/-")) {
+            String thisprefix = thispath.substring(0, thispath.length() - 1);
+            return thatpath.startsWith(thisprefix);
+            }
+
+        if (thispath.endsWith("/*")) {
+            String thisprefix = thispath.substring(0, thispath.length() - 1);
+            if (!thatpath.startsWith(thisprefix)) {
+                return false;
+            }
+            String thatsuffix = thatpath.substring(thisprefix.length());
+            // suffix must not contain '/' chars
+            if (thatsuffix.indexOf('/') != -1) {
+                return false;
+            }
+            if (thatsuffix.equals("-")) {
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * Returns true if, this.getActions().equals(p.getActions())
+     * and p's url equals this's url.  Returns false otherwise.
+     */
+    public boolean equals(Object p) {
+        if (!(p instanceof HttpURLPermission)) {
+            return false;
+        }
+        HttpURLPermission that = (HttpURLPermission)p;
+        return this.getActions().equals(that.getActions()) &&
+                  this.uri.equals(that.uri);
+    }
+
+    /**
+     * Returns a hashcode calculated from the hashcode of the
+     * actions String and the url
+     */
+    public int hashCode() {
+        return getActions().hashCode() + uri.hashCode();
+    }
+
+
+    private List<String> normalizeMethods(String methods) {
+        List<String> l = new ArrayList<>();
+        StringBuilder b = new StringBuilder();
+        for (int i=0; i<methods.length(); i++) {
+            char c = methods.charAt(i);
+            if (c == ',') {
+                String s = b.toString();
+                if (s.length() > 0)
+                    l.add(s);
+                b = new StringBuilder();
+            } else if (c == ' ' || c == '\t') {
+                throw new IllegalArgumentException("white space not allowed");
+            } else {
+                if (c >= 'a' && c <= 'z') {
+                    c += 'A' - 'a';
+                }
+                b.append(c);
+            }
+        }
+        String s = b.toString();
+        if (s.length() > 0)
+            l.add(s);
+        return l;
+    }
+
+    private List<String> normalizeHeaders(String headers) {
+        List<String> l = new ArrayList<>();
+        StringBuilder b = new StringBuilder();
+        boolean capitalizeNext = true;
+        for (int i=0; i<headers.length(); i++) {
+            char c = headers.charAt(i);
+            if (c >= 'a' && c <= 'z') {
+                if (capitalizeNext) {
+                    c += 'A' - 'a';
+                    capitalizeNext = false;
+                }
+                b.append(c);
+            } else if (c == ' ' || c == '\t') {
+                throw new IllegalArgumentException("white space not allowed");
+            } else if (c == '-') {
+                    capitalizeNext = true;
+                b.append(c);
+            } else if (c == ',') {
+                String s = b.toString();
+                if (s.length() > 0)
+                    l.add(s);
+                b = new StringBuilder();
+                capitalizeNext = true;
+            } else {
+                capitalizeNext = false;
+                b.append(c);
+            }
+        }
+        String s = b.toString();
+        if (s.length() > 0)
+            l.add(s);
+        return l;
+    }
+
+    private URI parseURI(String url) {
+        URI u = URI.create(url);
+        String scheme = u.getScheme();
+        if (!(scheme.equalsIgnoreCase("http") ||
+             scheme.equalsIgnoreCase("https"))) {
+            throw new IllegalArgumentException ("unexpected URL scheme");
+        }
+        if (!u.getSchemeSpecificPart().equals("*")) {
+            u = URI.create(scheme + "://" + u.getAuthority() + u.getPath());
+        }
+        return u;
+    }
+
+    private String actions() {
+        StringBuilder b = new StringBuilder();
+        for (String s : methods) {
+            b.append(s);
+        }
+        b.append(":");
+        for (String s : requestHeaders) {
+            b.append(s);
+        }
+        return b.toString();
+    }
+    /**
+     * restore the state of this object from stream
+     */
+    private void readObject(ObjectInputStream s)
+        throws IOException, ClassNotFoundException {
+        ObjectInputStream.GetField fields = s.readFields();
+        String actions = (String)fields.get("actions", null);
+
+        init(actions);
+    }
+}
diff --git a/jdk/src/share/classes/java/net/ServerSocket.java b/jdk/src/share/classes/java/net/ServerSocket.java
index 887a1e7..b47e442 100644
--- a/jdk/src/share/classes/java/net/ServerSocket.java
+++ b/jdk/src/share/classes/java/net/ServerSocket.java
@@ -607,9 +607,9 @@
     }
 
     /**
-     * Enable/disable SO_TIMEOUT with the specified timeout, in
-     * milliseconds.  With this option set to a non-zero timeout,
-     * a call to accept() for this ServerSocket
+     * Enable/disable {@link SocketOptions#SO_TIMEOUT SO_TIMEOUT} with the
+     * specified timeout, in milliseconds.  With this option set to a non-zero
+     * timeout, a call to accept() for this ServerSocket
      * will block for only this amount of time.  If the timeout expires,
      * a <B>java.net.SocketTimeoutException</B> is raised, though the
      * ServerSocket is still valid.  The option <B>must</B> be enabled
@@ -629,9 +629,9 @@
     }
 
     /**
-     * Retrieve setting for SO_TIMEOUT.  0 returns implies that the
-     * option is disabled (i.e., timeout of infinity).
-     * @return the SO_TIMEOUT value
+     * Retrieve setting for {@link SocketOptions#SO_TIMEOUT SO_TIMEOUT}.
+     * 0 returns implies that the option is disabled (i.e., timeout of infinity).
+     * @return the {@link SocketOptions#SO_TIMEOUT SO_TIMEOUT} value
      * @exception IOException if an I/O error occurs
      * @since   JDK1.1
      * @see #setSoTimeout(int)
@@ -649,7 +649,8 @@
     }
 
     /**
-     * Enable/disable the SO_REUSEADDR socket option.
+     * Enable/disable the {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR}
+     * socket option.
      * <p>
      * When a TCP connection is closed the connection may remain
      * in a timeout state for a period of time after the connection
@@ -660,24 +661,23 @@
      * <tt>SocketAddress</tt> if there is a connection in the
      * timeout state involving the socket address or port.
      * <p>
-     * Enabling <tt>SO_REUSEADDR</tt> prior to binding the socket
-     * using {@link #bind(SocketAddress)} allows the socket to be
-     * bound even though a previous connection is in a timeout
-     * state.
+     * Enabling {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} prior to
+     * binding the socket using {@link #bind(SocketAddress)} allows the socket
+     * to be bound even though a previous connection is in a timeout state.
      * <p>
      * When a <tt>ServerSocket</tt> is created the initial setting
-     * of <tt>SO_REUSEADDR</tt> is not defined. Applications can
-     * use {@link #getReuseAddress()} to determine the initial
-     * setting of <tt>SO_REUSEADDR</tt>.
+     * of {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is not defined.
+     * Applications can use {@link #getReuseAddress()} to determine the initial
+     * setting of {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR}.
      * <p>
-     * The behaviour when <tt>SO_REUSEADDR</tt> is enabled or
-     * disabled after a socket is bound (See {@link #isBound()})
+     * The behaviour when {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is
+     * enabled or disabled after a socket is bound (See {@link #isBound()})
      * is not defined.
      *
      * @param on  whether to enable or disable the socket option
      * @exception SocketException if an error occurs enabling or
-     *            disabling the <tt>SO_RESUEADDR</tt> socket option,
-     *            or the socket is closed.
+     *            disabling the {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR}
+     *            socket option, or the socket is closed.
      * @since 1.4
      * @see #getReuseAddress()
      * @see #bind(SocketAddress)
@@ -691,9 +691,10 @@
     }
 
     /**
-     * Tests if SO_REUSEADDR is enabled.
+     * Tests if {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is enabled.
      *
-     * @return a <code>boolean</code> indicating whether or not SO_REUSEADDR is enabled.
+     * @return a <code>boolean</code> indicating whether or not
+     *         {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is enabled.
      * @exception SocketException if there is an error
      * in the underlying protocol, such as a TCP error.
      * @since   1.4
@@ -768,15 +769,16 @@
     }
 
     /**
-     * Sets a default proposed value for the SO_RCVBUF option for sockets
+     * Sets a default proposed value for the
+     * {@link SocketOptions#SO_RCVBUF SO_RCVBUF} option for sockets
      * accepted from this <tt>ServerSocket</tt>. The value actually set
      * in the accepted socket must be determined by calling
      * {@link Socket#getReceiveBufferSize()} after the socket
      * is returned by {@link #accept()}.
      * <p>
-     * The value of SO_RCVBUF is used both to set the size of the internal
-     * socket receive buffer, and to set the size of the TCP receive window
-     * that is advertized to the remote peer.
+     * The value of {@link SocketOptions#SO_RCVBUF SO_RCVBUF} is used both to
+     * set the size of the internal socket receive buffer, and to set the size
+     * of the TCP receive window that is advertized to the remote peer.
      * <p>
      * It is possible to change the value subsequently, by calling
      * {@link Socket#setReceiveBufferSize(int)}. However, if the application
@@ -812,15 +814,16 @@
     }
 
     /**
-     * Gets the value of the SO_RCVBUF option for this <tt>ServerSocket</tt>,
-     * that is the proposed buffer size that will be used for Sockets accepted
-     * from this <tt>ServerSocket</tt>.
+     * Gets the value of the {@link SocketOptions#SO_RCVBUF SO_RCVBUF} option
+     * for this <tt>ServerSocket</tt>, that is the proposed buffer size that
+     * will be used for Sockets accepted from this <tt>ServerSocket</tt>.
      *
      * <p>Note, the value actually set in the accepted socket is determined by
      * calling {@link Socket#getReceiveBufferSize()}.
-     * @return the value of the SO_RCVBUF option for this <tt>Socket</tt>.
+     * @return the value of the {@link SocketOptions#SO_RCVBUF SO_RCVBUF}
+     *         option for this <tt>Socket</tt>.
      * @exception SocketException if there is an error
-     * in the underlying protocol, such as a TCP error.
+     *            in the underlying protocol, such as a TCP error.
      * @see #setReceiveBufferSize(int)
      * @since 1.4
      */
diff --git a/jdk/src/share/classes/java/net/Socket.java b/jdk/src/share/classes/java/net/Socket.java
index d4f28e9..e0635c1 100644
--- a/jdk/src/share/classes/java/net/Socket.java
+++ b/jdk/src/share/classes/java/net/Socket.java
@@ -924,7 +924,8 @@
     }
 
     /**
-     * Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm).
+     * Enable/disable {@link SocketOptions#TCP_NODELAY TCP_NODELAY}
+     * (disable/enable Nagle's algorithm).
      *
      * @param on <code>true</code> to enable TCP_NODELAY,
      * <code>false</code> to disable.
@@ -943,9 +944,10 @@
     }
 
     /**
-     * Tests if TCP_NODELAY is enabled.
+     * Tests if {@link SocketOptions#TCP_NODELAY TCP_NODELAY} is enabled.
      *
-     * @return a <code>boolean</code> indicating whether or not TCP_NODELAY is enabled.
+     * @return a <code>boolean</code> indicating whether or not
+     *         {@link SocketOptions#TCP_NODELAY TCP_NODELAY} is enabled.
      * @exception SocketException if there is an error
      * in the underlying protocol, such as a TCP error.
      * @since   JDK1.1
@@ -958,8 +960,9 @@
     }
 
     /**
-     * Enable/disable SO_LINGER with the specified linger time in seconds.
-     * The maximum timeout value is platform specific.
+     * Enable/disable {@link SocketOptions#SO_LINGER SO_LINGER} with the
+     * specified linger time in seconds. The maximum timeout value is platform
+     * specific.
      *
      * The setting only affects socket close.
      *
@@ -987,12 +990,13 @@
     }
 
     /**
-     * Returns setting for SO_LINGER. -1 returns implies that the
+     * Returns setting for {@link SocketOptions#SO_LINGER SO_LINGER}.
+     * -1 returns implies that the
      * option is disabled.
      *
      * The setting only affects socket close.
      *
-     * @return the setting for SO_LINGER.
+     * @return the setting for {@link SocketOptions#SO_LINGER SO_LINGER}.
      * @exception SocketException if there is an error
      * in the underlying protocol, such as a TCP error.
      * @since   JDK1.1
@@ -1027,7 +1031,8 @@
     }
 
     /**
-     * Enable/disable OOBINLINE (receipt of TCP urgent data)
+     * Enable/disable {@link SocketOptions#SO_OOBINLINE SO_OOBINLINE}
+     * (receipt of TCP urgent data)
      *
      * By default, this option is disabled and TCP urgent data received on a
      * socket is silently discarded. If the user wishes to receive urgent data, then
@@ -1039,8 +1044,9 @@
      * and there is no capability to distinguish between normal data and urgent
      * data unless provided by a higher level protocol.
      *
-     * @param on <code>true</code> to enable OOBINLINE,
-     * <code>false</code> to disable.
+     * @param on <code>true</code> to enable
+     *           {@link SocketOptions#SO_OOBINLINE SO_OOBINLINE},
+     *           <code>false</code> to disable.
      *
      * @exception SocketException if there is an error
      * in the underlying protocol, such as a TCP error.
@@ -1056,9 +1062,11 @@
     }
 
     /**
-     * Tests if OOBINLINE is enabled.
+     * Tests if {@link SocketOptions#SO_OOBINLINE SO_OOBINLINE} is enabled.
      *
-     * @return a <code>boolean</code> indicating whether or not OOBINLINE is enabled.
+     * @return a <code>boolean</code> indicating whether or not
+     *         {@link SocketOptions#SO_OOBINLINE SO_OOBINLINE}is enabled.
+     *
      * @exception SocketException if there is an error
      * in the underlying protocol, such as a TCP error.
      * @since   1.4
@@ -1071,15 +1079,16 @@
     }
 
     /**
-     *  Enable/disable SO_TIMEOUT with the specified timeout, in
-     *  milliseconds.  With this option set to a non-zero timeout,
-     *  a read() call on the InputStream associated with this Socket
-     *  will block for only this amount of time.  If the timeout expires,
-     *  a <B>java.net.SocketTimeoutException</B> is raised, though the
+     *  Enable/disable {@link SocketOptions#SO_TIMEOUT SO_TIMEOUT}
+     *  with the specified timeout, in milliseconds. With this option set
+     *  to a non-zero timeout, a read() call on the InputStream associated with
+     *  this Socket will block for only this amount of time.  If the timeout
+     *  expires, a <B>java.net.SocketTimeoutException</B> is raised, though the
      *  Socket is still valid. The option <B>must</B> be enabled
      *  prior to entering the blocking operation to have effect. The
      *  timeout must be > 0.
      *  A timeout of zero is interpreted as an infinite timeout.
+     *
      * @param timeout the specified timeout, in milliseconds.
      * @exception SocketException if there is an error
      * in the underlying protocol, such as a TCP error.
@@ -1096,11 +1105,13 @@
     }
 
     /**
-     * Returns setting for SO_TIMEOUT.  0 returns implies that the
-     * option is disabled (i.e., timeout of infinity).
-     * @return the setting for SO_TIMEOUT
+     * Returns setting for {@link SocketOptions#SO_TIMEOUT SO_TIMEOUT}.
+     * 0 returns implies that the option is disabled (i.e., timeout of infinity).
+     *
+     * @return the setting for {@link SocketOptions#SO_TIMEOUT SO_TIMEOUT}
      * @exception SocketException if there is an error
      * in the underlying protocol, such as a TCP error.
+     *
      * @since   JDK1.1
      * @see #setSoTimeout(int)
      */
@@ -1117,14 +1128,15 @@
     }
 
     /**
-     * Sets the SO_SNDBUF option to the specified value for this
-     * <tt>Socket</tt>. The SO_SNDBUF option is used by the platform's
-     * networking code as a hint for the size to set
-     * the underlying network I/O buffers.
+     * Sets the {@link SocketOptions#SO_SNDBUF SO_SNDBUF} option to the
+     * specified value for this <tt>Socket</tt>.
+     * The {@link SocketOptions#SO_SNDBUF SO_SNDBUF} option is used by the
+     * platform's networking code as a hint for the size to set the underlying
+     * network I/O buffers.
      *
-     * <p>Because SO_SNDBUF is a hint, applications that want to
-     * verify what size the buffers were set to should call
-     * {@link #getSendBufferSize()}.
+     * <p>Because {@link SocketOptions#SO_SNDBUF SO_SNDBUF} is a hint,
+     * applications that want to verify what size the buffers were set to
+     * should call {@link #getSendBufferSize()}.
      *
      * @exception SocketException if there is an error
      * in the underlying protocol, such as a TCP error.
@@ -1149,10 +1161,11 @@
     }
 
     /**
-     * Get value of the SO_SNDBUF option for this <tt>Socket</tt>,
-     * that is the buffer size used by the platform
+     * Get value of the {@link SocketOptions#SO_SNDBUF SO_SNDBUF} option
+     * for this <tt>Socket</tt>, that is the buffer size used by the platform
      * for output on this <tt>Socket</tt>.
-     * @return the value of the SO_SNDBUF option for this <tt>Socket</tt>.
+     * @return the value of the {@link SocketOptions#SO_SNDBUF SO_SNDBUF}
+     *         option for this <tt>Socket</tt>.
      *
      * @exception SocketException if there is an error
      * in the underlying protocol, such as a TCP error.
@@ -1172,25 +1185,26 @@
     }
 
     /**
-     * Sets the SO_RCVBUF option to the specified value for this
-     * <tt>Socket</tt>. The SO_RCVBUF option is used by the platform's
-     * networking code as a hint for the size to set
+     * Sets the {@link SocketOptions#SO_RCVBUF SO_RCVBUF} option to the
+     * specified value for this <tt>Socket</tt>. The
+     * {@link SocketOptions#SO_RCVBUF SO_RCVBUF} option is
+     * used by the platform's networking code as a hint for the size to set
      * the underlying network I/O buffers.
      *
      * <p>Increasing the receive buffer size can increase the performance of
      * network I/O for high-volume connection, while decreasing it can
      * help reduce the backlog of incoming data.
      *
-     * <p>Because SO_RCVBUF is a hint, applications that want to
-     * verify what size the buffers were set to should call
-     * {@link #getReceiveBufferSize()}.
+     * <p>Because {@link SocketOptions#SO_RCVBUF SO_RCVBUF} is a hint,
+     * applications that want to verify what size the buffers were set to
+     * should call {@link #getReceiveBufferSize()}.
      *
-     * <p>The value of SO_RCVBUF is also used to set the TCP receive window
-     * that is advertized to the remote peer. Generally, the window size
-     * can be modified at any time when a socket is connected. However, if
-     * a receive window larger than 64K is required then this must be requested
-     * <B>before</B> the socket is connected to the remote peer. There are two
-     * cases to be aware of:<p>
+     * <p>The value of {@link SocketOptions#SO_RCVBUF SO_RCVBUF} is also used
+     * to set the TCP receive window that is advertized to the remote peer.
+     * Generally, the window size can be modified at any time when a socket is
+     * connected. However, if a receive window larger than 64K is required then
+     * this must be requested <B>before</B> the socket is connected to the
+     * remote peer. There are two cases to be aware of:<p>
      * <ol>
      * <li>For sockets accepted from a ServerSocket, this must be done by calling
      * {@link ServerSocket#setReceiveBufferSize(int)} before the ServerSocket
@@ -1221,11 +1235,12 @@
     }
 
     /**
-     * Gets the value of the SO_RCVBUF option for this <tt>Socket</tt>,
-     * that is the buffer size used by the platform for
-     * input on this <tt>Socket</tt>.
+     * Gets the value of the {@link SocketOptions#SO_RCVBUF SO_RCVBUF} option
+     * for this <tt>Socket</tt>, that is the buffer size used by the platform
+     * for input on this <tt>Socket</tt>.
      *
-     * @return the value of the SO_RCVBUF option for this <tt>Socket</tt>.
+     * @return the value of the {@link SocketOptions#SO_RCVBUF SO_RCVBUF}
+     *         option for this <tt>Socket</tt>.
      * @exception SocketException if there is an error
      * in the underlying protocol, such as a TCP error.
      * @see #setReceiveBufferSize(int)
@@ -1244,9 +1259,9 @@
     }
 
     /**
-     * Enable/disable SO_KEEPALIVE.
+     * Enable/disable {@link SocketOptions#SO_KEEPALIVE SO_KEEPALIVE}.
      *
-     * @param on     whether or not to have socket keep alive turned on.
+     * @param on  whether or not to have socket keep alive turned on.
      * @exception SocketException if there is an error
      * in the underlying protocol, such as a TCP error.
      * @since 1.3
@@ -1259,9 +1274,10 @@
     }
 
     /**
-     * Tests if SO_KEEPALIVE is enabled.
+     * Tests if {@link SocketOptions#SO_KEEPALIVE SO_KEEPALIVE} is enabled.
      *
-     * @return a <code>boolean</code> indicating whether or not SO_KEEPALIVE is enabled.
+     * @return a <code>boolean</code> indicating whether or not
+     *         {@link SocketOptions#SO_KEEPALIVE SO_KEEPALIVE} is enabled.
      * @exception SocketException if there is an error
      * in the underlying protocol, such as a TCP error.
      * @since   1.3
@@ -1317,6 +1333,7 @@
      * traffic class or type-of-service
      * @since 1.4
      * @see #getTrafficClass
+     * @see SocketOptions#IP_TOS
      */
     public void setTrafficClass(int tc) throws SocketException {
         if (tc < 0 || tc > 255)
@@ -1341,13 +1358,15 @@
      * traffic class or type-of-service value.
      * @since 1.4
      * @see #setTrafficClass(int)
+     * @see SocketOptions#IP_TOS
      */
     public int getTrafficClass() throws SocketException {
         return ((Integer) (getImpl().getOption(SocketOptions.IP_TOS))).intValue();
     }
 
     /**
-     * Enable/disable the SO_REUSEADDR socket option.
+     * Enable/disable the {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR}
+     * socket option.
      * <p>
      * When a TCP connection is closed the connection may remain
      * in a timeout state for a period of time after the connection
@@ -1358,22 +1377,22 @@
      * <tt>SocketAddress</tt> if there is a connection in the
      * timeout state involving the socket address or port.
      * <p>
-     * Enabling <tt>SO_REUSEADDR</tt> prior to binding the socket
-     * using {@link #bind(SocketAddress)} allows the socket to be
-     * bound even though a previous connection is in a timeout
+     * Enabling {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR}
+     * prior to binding the socket using {@link #bind(SocketAddress)} allows
+     * the socket to be bound even though a previous connection is in a timeout
      * state.
      * <p>
      * When a <tt>Socket</tt> is created the initial setting
-     * of <tt>SO_REUSEADDR</tt> is disabled.
+     * of {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is disabled.
      * <p>
-     * The behaviour when <tt>SO_REUSEADDR</tt> is enabled or
-     * disabled after a socket is bound (See {@link #isBound()})
+     * The behaviour when {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is
+     * enabled or disabled after a socket is bound (See {@link #isBound()})
      * is not defined.
      *
      * @param on  whether to enable or disable the socket option
      * @exception SocketException if an error occurs enabling or
-     *            disabling the <tt>SO_RESUEADDR</tt> socket option,
-     *            or the socket is closed.
+     *            disabling the {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR}
+     *            socket option, or the socket is closed.
      * @since 1.4
      * @see #getReuseAddress()
      * @see #bind(SocketAddress)
@@ -1387,9 +1406,10 @@
     }
 
     /**
-     * Tests if SO_REUSEADDR is enabled.
+     * Tests if {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is enabled.
      *
-     * @return a <code>boolean</code> indicating whether or not SO_REUSEADDR is enabled.
+     * @return a <code>boolean</code> indicating whether or not
+     *         {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is enabled.
      * @exception SocketException if there is an error
      * in the underlying protocol, such as a TCP error.
      * @since   1.4
diff --git a/jdk/src/share/classes/java/nio/charset/Charset.java b/jdk/src/share/classes/java/nio/charset/Charset.java
index 2d3f020..9451c53 100644
--- a/jdk/src/share/classes/java/nio/charset/Charset.java
+++ b/jdk/src/share/classes/java/nio/charset/Charset.java
@@ -427,46 +427,38 @@
     }
 
     /* The extended set of charsets */
-    private static Object extendedProviderLock = new Object();
-    private static boolean extendedProviderProbed = false;
-    private static CharsetProvider extendedProvider = null;
-
-    private static void probeExtendedProvider() {
-        AccessController.doPrivileged(new PrivilegedAction<Object>() {
-                public Object run() {
-                    try {
-                        Class<?> epc
-                            = Class.forName("sun.nio.cs.ext.ExtendedCharsets");
-                        extendedProvider = (CharsetProvider)epc.newInstance();
-                    } catch (ClassNotFoundException x) {
-                        // Extended charsets not available
-                        // (charsets.jar not present)
-                    } catch (InstantiationException x) {
-                        throw new Error(x);
-                    } catch (IllegalAccessException x) {
-                        throw new Error(x);
-                    }
-                    return null;
-                }
-            });
+    private static class ExtendedProviderHolder {
+        static final CharsetProvider extendedProvider = extendedProvider();
+        // returns ExtendedProvider, if installed
+        private static CharsetProvider extendedProvider() {
+            return AccessController.doPrivileged(
+                       new PrivilegedAction<CharsetProvider>() {
+                           public CharsetProvider run() {
+                                try {
+                                    Class<?> epc
+                                        = Class.forName("sun.nio.cs.ext.ExtendedCharsets");
+                                    return (CharsetProvider)epc.newInstance();
+                                } catch (ClassNotFoundException x) {
+                                    // Extended charsets not available
+                                    // (charsets.jar not present)
+                                } catch (InstantiationException |
+                                         IllegalAccessException x) {
+                                  throw new Error(x);
+                                }
+                                return null;
+                            }
+                        });
+        }
     }
 
     private static Charset lookupExtendedCharset(String charsetName) {
-        CharsetProvider ecp = null;
-        synchronized (extendedProviderLock) {
-            if (!extendedProviderProbed) {
-                probeExtendedProvider();
-                extendedProviderProbed = true;
-            }
-            ecp = extendedProvider;
-        }
+        CharsetProvider ecp = ExtendedProviderHolder.extendedProvider;
         return (ecp != null) ? ecp.charsetForName(charsetName) : null;
     }
 
     private static Charset lookup(String charsetName) {
         if (charsetName == null)
             throw new IllegalArgumentException("Null charset name");
-
         Object[] a;
         if ((a = cache1) != null && charsetName.equals(a[0]))
             return (Charset)a[1];
@@ -483,7 +475,6 @@
             cache1 = a;
             return (Charset)a[1];
         }
-
         Charset cs;
         if ((cs = standardProvider.charsetForName(charsetName)) != null ||
             (cs = lookupExtendedCharset(charsetName))           != null ||
@@ -589,6 +580,9 @@
                         new TreeMap<String,Charset>(
                             ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER);
                     put(standardProvider.charsets(), m);
+                    CharsetProvider ecp = ExtendedProviderHolder.extendedProvider;
+                    if (ecp != null)
+                        put(ecp.charsets(), m);
                     for (Iterator<CharsetProvider> i = providers(); i.hasNext();) {
                         CharsetProvider cp = i.next();
                         put(cp.charsets(), m);
diff --git a/jdk/src/share/classes/java/time/Clock.java b/jdk/src/share/classes/java/time/Clock.java
index c0be4b0..cd90822 100644
--- a/jdk/src/share/classes/java/time/Clock.java
+++ b/jdk/src/share/classes/java/time/Clock.java
@@ -103,7 +103,7 @@
  * system clock This may use {@link System#currentTimeMillis()}, or a higher
  * resolution clock if one is available.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This abstract class must be implemented with care to ensure other operate correctly.
  * All implementations that can be instantiated must be final, immutable and thread-safe.
  * <p>
@@ -112,13 +112,23 @@
  * obtain the time from a central time server across the network. Obviously, in this case the
  * lookup could fail, and so the method is permitted to throw an exception.
  * <p>
- * The returned instants from {@code Clock} work on a time-scale that ignores leap seconds.
- * If the implementation wraps a source that provides leap second information, then a mechanism
- * should be used to "smooth" the leap second, such as UTC-SLS.
+ * The returned instants from {@code Clock} work on a time-scale that ignores leap seconds,
+ * as described in {@link Instant}. If the implementation wraps a source that provides leap
+ * second information, then a mechanism should be used to "smooth" the leap second.
+ * The Java Time-Scale mandates the use of UTC-SLS, however clock implementations may choose
+ * how accurate they are with the time-scale so long as they document how they work.
+ * Implementations are therefore not required to actually perform the UTC-SLS slew or to
+ * otherwise be aware of leap seconds.
  * <p>
  * Implementations should implement {@code Serializable} wherever possible and must
  * document whether or not they do support serialization.
  *
+ * @implNote
+ * The clock implementation provided here is based on {@link System#currentTimeMillis()}.
+ * That method provides little to no guarantee about the accuracy of the clock.
+ * Applications requiring a more accurate clock must implement this abstract class
+ * themselves using a different external clock, such as an NTP server.
+ *
  * @since 1.8
  */
 public abstract class Clock {
@@ -370,7 +380,7 @@
     /**
      * Gets the current millisecond instant of the clock.
      * <p>
-     * This returns the millisecond-based instant, measured from 1970-01-01T00:00 UTC.
+     * This returns the millisecond-based instant, measured from 1970-01-01T00:00Z (UTC).
      * This is equivalent to the definition of {@link System#currentTimeMillis()}.
      * <p>
      * Most applications should avoid this method and use {@link Instant} to represent
@@ -381,7 +391,7 @@
      * The default implementation currently calls {@link #instant}.
      *
      * @return the current millisecond instant from this clock, measured from
-     *  the Java epoch of 1970-01-01T00:00 UTC, not null
+     *  the Java epoch of 1970-01-01T00:00Z (UTC), not null
      * @throws DateTimeException if the instant cannot be obtained, not thrown by most implementations
      */
     public long millis() {
diff --git a/jdk/src/share/classes/java/time/DateTimeException.java b/jdk/src/share/classes/java/time/DateTimeException.java
index e5e9efa..c2549fe 100644
--- a/jdk/src/share/classes/java/time/DateTimeException.java
+++ b/jdk/src/share/classes/java/time/DateTimeException.java
@@ -67,7 +67,7 @@
  * This exception is used to indicate problems with creating, querying
  * and manipulating date-time objects.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is intended for use in a single thread.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/DayOfWeek.java b/jdk/src/share/classes/java/time/DayOfWeek.java
index 767058b..d2a6f5a 100644
--- a/jdk/src/share/classes/java/time/DayOfWeek.java
+++ b/jdk/src/share/classes/java/time/DayOfWeek.java
@@ -100,7 +100,7 @@
  * As such, this enum may be used by any calendar system that has the day-of-week
  * concept defined exactly equivalent to the ISO calendar system.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This is an immutable and thread-safe enum.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/Duration.java b/jdk/src/share/classes/java/time/Duration.java
index 73c04fd..52b225e 100644
--- a/jdk/src/share/classes/java/time/Duration.java
+++ b/jdk/src/share/classes/java/time/Duration.java
@@ -118,7 +118,7 @@
  * most applications.
  * See {@link Instant} for a discussion as to the meaning of the second and time-scales.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/Instant.java b/jdk/src/share/classes/java/time/Instant.java
index bacdba0..6dc2464 100644
--- a/jdk/src/share/classes/java/time/Instant.java
+++ b/jdk/src/share/classes/java/time/Instant.java
@@ -142,47 +142,60 @@
  * introduce other changes.
  * <p>
  * Given the complexity of accurate timekeeping described above, this Java API defines
- * its own time-scale with a simplification. The Java time-scale is defined as follows:
+ * its own time-scale, the <i>Java Time-Scale</i>.
+ * <p>
+ * The Java Time-Scale divides each calendar day into exactly 86400
+ * subdivisions, known as seconds.  These seconds may differ from the
+ * SI second.  It closely matches the de facto international civil time
+ * scale, the definition of which changes from time to time.
+ * <p>
+ * The Java Time-Scale has slightly different definitions for different
+ * segments of the time-line, each based on the consensus international
+ * time scale that is used as the basis for civil time. Whenever the
+ * internationally-agreed time scale is modified or replaced, a new
+ * segment of the Java Time-Scale must be defined for it.  Each segment
+ * must meet these requirements:
  * <p><ul>
- * <li>midday will always be exactly as defined by the agreed international civil time</li>
- * <li>other times during the day will be broadly in line with the agreed international civil time</li>
- * <li>the day will be divided into exactly 86400 subdivisions, referred to as "seconds"</li>
- * <li>the Java "second" may differ from an SI second</li>
- * <li>a well-defined algorithm must be specified to map each second in the accurate agreed
- *  international civil time to each "second" in this time-scale</li>
+ * <li>the Java Time-Scale shall closely match the underlying international
+ *  civil time scale;</li>
+ * <li>the Java Time-Scale shall exactly match the international civil
+ *  time scale at noon each day;</li>
+ * <li>the Java Time-Scale shall have a precisely-defined relationship to
+ *  the international civil time scale.</li>
  * </ul><p>
- * Agreed international civil time is the base time-scale agreed by international convention,
- * which in 2012 is UTC (with leap-seconds).
+ * There are currently, as of 2013, two segments in the Java time-scale.
  * <p>
- * In 2012, the definition of the Java time-scale is the same as UTC for all days except
- * those where a leap-second occurs. On days where a leap-second does occur, the time-scale
- * effectively eliminates the leap-second, maintaining the fiction of 86400 seconds in the day.
- * The approved well-defined algorithm to eliminate leap-seconds is specified as
+ * For the segment from 1972-11-03 (exact boundary discussed below) until
+ * further notice, the consensus international time scale is UTC (with
+ * leap seconds).  In this segment, the Java Time-Scale is identical to
  * <a href="http://www.cl.cam.ac.uk/~mgk25/time/utc-sls/">UTC-SLS</a>.
+ * This is identical to UTC on days that do not have a leap second.
+ * On days that do have a leap second, the leap second is spread equally
+ * over the last 1000 seconds of the day, maintaining the appearance of
+ * exactly 86400 seconds per day.
  * <p>
- * UTC-SLS is a simple algorithm that smoothes the leap-second over the last 1000 seconds of
- * the day, making each of the last 1000 seconds 1/1000th longer or shorter than an SI second.
- * Implementations built on an accurate leap-second aware time source should use UTC-SLS.
- * Use of a different algorithm risks confusion and misinterpretation of instants around a
- * leap-second and is discouraged.
+ * For the segment prior to 1972-11-03, extending back arbitrarily far,
+ * the consensus international time scale is defined to be UT1, applied
+ * proleptically, which is equivalent to the (mean) solar time on the
+ * prime meridian (Greenwich). In this segment, the Java Time-Scale is
+ * identical to the consensus international time scale. The exact
+ * boundary between the two segments is the instant where UT1 = UTC
+ * between 1972-11-03T00:00 and 1972-11-04T12:00.
  * <p>
- * The main benefit of always dividing the day into 86400 subdivisions is that it matches the
- * expectations of most users of the API. The alternative is to force every user to understand
- * what a leap second is and to force them to have special logic to handle them.
- * Most applications do not have access to a clock that is accurate enough to record leap-seconds.
- * Most applications also do not have a problem with a second being a very small amount longer or
- * shorter than a real SI second during a leap-second.
- * <p>
- * One final problem is the definition of the agreed international civil time before the
- * introduction of modern UTC in 1972. This includes the Java epoch of {@code 1970-01-01}.
- * It is intended that instants before 1972 be interpreted based on the solar day divided
- * into 86400 subdivisions, as per the principles of UT1.
+ * Implementations of the Java time-scale using the JSR-310 API are not
+ * required to provide any clock that is sub-second accurate, or that
+ * progresses monotonically or smoothly. Implementations are therefore
+ * not required to actually perform the UTC-SLS slew or to otherwise be
+ * aware of leap seconds. JSR-310 does, however, require that
+ * implementations must document the approach they use when defining a
+ * clock representing the current instant.
+ * See {@link Clock} for details on the available clocks.
  * <p>
  * The Java time-scale is used for all date-time classes.
  * This includes {@code Instant}, {@code LocalDate}, {@code LocalTime}, {@code OffsetDateTime},
  * {@code ZonedDateTime} and {@code Duration}.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
@@ -1030,16 +1043,16 @@
     }
 
     /**
-     * Calculates the period between this instant and another instant in
-     * terms of the specified unit.
+     * Calculates the amount of time until another instant in terms of the specified unit.
      * <p>
-     * This calculates the period between two instants in terms of a single unit.
+     * This calculates the amount of time between two {@code Instant}
+     * objects in terms of a single {@code TemporalUnit}.
      * The start and end points are {@code this} and the specified instant.
      * The result will be negative if the end is before the start.
      * The calculation returns a whole number, representing the number of
      * complete units between the two instants.
      * The {@code Temporal} passed to this method must be an {@code Instant}.
-     * For example, the period in days between two dates can be calculated
+     * For example, the amount in days between two dates can be calculated
      * using {@code startInstant.periodUntil(endInstant, SECONDS)}.
      * <p>
      * There are two equivalent ways of using this method.
@@ -1064,10 +1077,10 @@
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param endInstant  the end date, which must be a {@code LocalDate}, not null
-     * @param unit  the unit to measure the period in, not null
-     * @return the amount of the period between this date and the end date
-     * @throws DateTimeException if the period cannot be calculated
+     * @param endInstant  the end date, which must be an {@code Instant}, not null
+     * @param unit  the unit to measure the amount in, not null
+     * @return the amount of time between this instant and the end instant
+     * @throws DateTimeException if the amount cannot be calculated
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
@@ -1075,7 +1088,7 @@
     public long periodUntil(Temporal endInstant, TemporalUnit unit) {
         if (endInstant instanceof Instant == false) {
             Objects.requireNonNull(endInstant, "endInstant");
-            throw new DateTimeException("Unable to calculate period between objects of two different types");
+            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
         }
         Instant end = (Instant) endInstant;
         if (unit instanceof ChronoUnit) {
diff --git a/jdk/src/share/classes/java/time/LocalDate.java b/jdk/src/share/classes/java/time/LocalDate.java
index cb1219b..ede6d83 100644
--- a/jdk/src/share/classes/java/time/LocalDate.java
+++ b/jdk/src/share/classes/java/time/LocalDate.java
@@ -121,7 +121,7 @@
  * However, any application that makes use of historical dates, and requires them
  * to be accurate will find the ISO-8601 approach unsuitable.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
@@ -1489,19 +1489,19 @@
     }
 
     /**
-     * Calculates the period between this date and another date in
-     * terms of the specified unit.
+     * Calculates the amount of time until another date in terms of the specified unit.
      * <p>
-     * This calculates the period between two dates in terms of a single unit.
+     * This calculates the amount of time between two {@code LocalDate}
+     * objects in terms of a single {@code TemporalUnit}.
      * The start and end points are {@code this} and the specified date.
      * The result will be negative if the end is before the start.
      * The {@code Temporal} passed to this method must be a {@code LocalDate}.
-     * For example, the period in days between two dates can be calculated
+     * For example, the amount in days between two dates can be calculated
      * using {@code startDate.periodUntil(endDate, DAYS)}.
      * <p>
      * The calculation returns a whole number, representing the number of
      * complete units between the two dates.
-     * For example, the period in months between 2012-06-15 and 2012-08-14
+     * For example, the amount in months between 2012-06-15 and 2012-08-14
      * will only be one month as it is one day short of two months.
      * <p>
      * There are two equivalent ways of using this method.
@@ -1527,9 +1527,9 @@
      * This instance is immutable and unaffected by this method call.
      *
      * @param endDate  the end date, which must be a {@code LocalDate}, not null
-     * @param unit  the unit to measure the period in, not null
-     * @return the amount of the period between this date and the end date
-     * @throws DateTimeException if the period cannot be calculated
+     * @param unit  the unit to measure the amount in, not null
+     * @return the amount of time between this date and the end date
+     * @throws DateTimeException if the amount cannot be calculated
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
@@ -1538,7 +1538,7 @@
         Objects.requireNonNull(unit, "unit");
         if (endDate instanceof LocalDate == false) {
             Objects.requireNonNull(endDate, "endDate");
-            throw new DateTimeException("Unable to calculate period between objects of two different types");
+            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
         }
         LocalDate end = (LocalDate) endDate;
         if (unit instanceof ChronoUnit) {
diff --git a/jdk/src/share/classes/java/time/LocalDateTime.java b/jdk/src/share/classes/java/time/LocalDateTime.java
index 2921d39..6e6c87b 100644
--- a/jdk/src/share/classes/java/time/LocalDateTime.java
+++ b/jdk/src/share/classes/java/time/LocalDateTime.java
@@ -119,7 +119,7 @@
  * However, any application that makes use of historical dates, and requires them
  * to be accurate will find the ISO-8601 approach unsuitable.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
@@ -1562,19 +1562,19 @@
     }
 
     /**
-     * Calculates the period between this date-time and another date-time in
-     * terms of the specified unit.
+     * Calculates the amount of time until another date-time in terms of the specified unit.
      * <p>
-     * This calculates the period between two date-times in terms of a single unit.
+     * This calculates the amount of time between two {@code LocalDateTime}
+     * objects in terms of a single {@code TemporalUnit}.
      * The start and end points are {@code this} and the specified date-time.
      * The result will be negative if the end is before the start.
      * The {@code Temporal} passed to this method must be a {@code LocalDateTime}.
-     * For example, the period in days between two date-times can be calculated
+     * For example, the amount in days between two date-times can be calculated
      * using {@code startDateTime.periodUntil(endDateTime, DAYS)}.
      * <p>
      * The calculation returns a whole number, representing the number of
      * complete units between the two date-times.
-     * For example, the period in months between 2012-06-15T00:00 and 2012-08-14T23:59
+     * For example, the amount in months between 2012-06-15T00:00 and 2012-08-14T23:59
      * will only be one month as it is one minute short of two months.
      * <p>
      * There are two equivalent ways of using this method.
@@ -1602,9 +1602,9 @@
      * This instance is immutable and unaffected by this method call.
      *
      * @param endDateTime  the end date-time, which must be a {@code LocalDateTime}, not null
-     * @param unit  the unit to measure the period in, not null
-     * @return the amount of the period between this date-time and the end date-time
-     * @throws DateTimeException if the period cannot be calculated
+     * @param unit  the unit to measure the amount in, not null
+     * @return the amount of time between this date-time and the end date-time
+     * @throws DateTimeException if the amount cannot be calculated
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
@@ -1612,7 +1612,7 @@
     public long periodUntil(Temporal endDateTime, TemporalUnit unit) {
         if (endDateTime instanceof LocalDateTime == false) {
             Objects.requireNonNull(endDateTime, "endDateTime");
-            throw new DateTimeException("Unable to calculate period between objects of two different types");
+            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
         }
         LocalDateTime end = (LocalDateTime) endDateTime;
         if (unit instanceof ChronoUnit) {
diff --git a/jdk/src/share/classes/java/time/LocalTime.java b/jdk/src/share/classes/java/time/LocalTime.java
index 1e909f8..41b1a92 100644
--- a/jdk/src/share/classes/java/time/LocalTime.java
+++ b/jdk/src/share/classes/java/time/LocalTime.java
@@ -109,7 +109,7 @@
  * in most of the world. This API assumes that all calendar systems use the same
  * representation, this class, for time-of-day.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
@@ -974,9 +974,6 @@
      *  Returns a {@code LocalTime} with the specified number of half-days added.
      *  This is equivalent to {@link #plusHours(long)} with the amount
      *  multiplied by 12.
-     * <li>{@code DAYS} -
-     *  Returns a {@code LocalTime} with the specified number of days added.
-     *  This returns {@code this} time.
      * </ul>
      * <p>
      * All other {@code ChronoUnit} instances will throw an {@code UnsupportedTemporalTypeException}.
@@ -1007,7 +1004,6 @@
                 case MINUTES: return plusMinutes(amountToAdd);
                 case HOURS: return plusHours(amountToAdd);
                 case HALF_DAYS: return plusHours((amountToAdd % 2) * 12);
-                case DAYS: return this;
             }
             throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName());
         }
@@ -1291,19 +1287,19 @@
     }
 
     /**
-     * Calculates the period between this time and another time in
-     * terms of the specified unit.
+     * Calculates the amount of time until another time in terms of the specified unit.
      * <p>
-     * This calculates the period between two times in terms of a single unit.
+     * This calculates the amount of time between two {@code LocalTime}
+     * objects in terms of a single {@code TemporalUnit}.
      * The start and end points are {@code this} and the specified time.
      * The result will be negative if the end is before the start.
      * The {@code Temporal} passed to this method must be a {@code LocalTime}.
-     * For example, the period in hours between two times can be calculated
+     * For example, the amount in hours between two times can be calculated
      * using {@code startTime.periodUntil(endTime, HOURS)}.
      * <p>
      * The calculation returns a whole number, representing the number of
      * complete units between the two times.
-     * For example, the period in hours between 11:30 and 13:29 will only
+     * For example, the amount in hours between 11:30 and 13:29 will only
      * be one hour as it is one minute short of two hours.
      * <p>
      * There are two equivalent ways of using this method.
@@ -1329,9 +1325,9 @@
      * This instance is immutable and unaffected by this method call.
      *
      * @param endTime  the end time, which must be a {@code LocalTime}, not null
-     * @param unit  the unit to measure the period in, not null
-     * @return the amount of the period between this time and the end time
-     * @throws DateTimeException if the period cannot be calculated
+     * @param unit  the unit to measure the amount in, not null
+     * @return the amount of time between this time and the end time
+     * @throws DateTimeException if the amount cannot be calculated
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
@@ -1339,7 +1335,7 @@
     public long periodUntil(Temporal endTime, TemporalUnit unit) {
         if (endTime instanceof LocalTime == false) {
             Objects.requireNonNull(endTime, "endTime");
-            throw new DateTimeException("Unable to calculate period between objects of two different types");
+            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
         }
         LocalTime end = (LocalTime) endTime;
         if (unit instanceof ChronoUnit) {
diff --git a/jdk/src/share/classes/java/time/Month.java b/jdk/src/share/classes/java/time/Month.java
index 175d051..272e8f9 100644
--- a/jdk/src/share/classes/java/time/Month.java
+++ b/jdk/src/share/classes/java/time/Month.java
@@ -97,7 +97,7 @@
  * As such, this enum may be used by any calendar system that has the month-of-year
  * concept defined exactly equivalent to the ISO-8601 calendar system.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This is an immutable and thread-safe enum.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/MonthDay.java b/jdk/src/share/classes/java/time/MonthDay.java
index 276e869..4204ef7 100644
--- a/jdk/src/share/classes/java/time/MonthDay.java
+++ b/jdk/src/share/classes/java/time/MonthDay.java
@@ -111,7 +111,7 @@
  * However, any application that makes use of historical dates, and requires them
  * to be accurate will find the ISO-8601 approach unsuitable.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/OffsetDateTime.java b/jdk/src/share/classes/java/time/OffsetDateTime.java
index aa4c728..b053085 100644
--- a/jdk/src/share/classes/java/time/OffsetDateTime.java
+++ b/jdk/src/share/classes/java/time/OffsetDateTime.java
@@ -111,7 +111,7 @@
  * in simpler applications. This class may be used when modeling date-time concepts in
  * more detail, or when communicating to a database or in a network protocol.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
@@ -1521,10 +1521,10 @@
     }
 
     /**
-     * Calculates the period between this date-time and another date-time in
-     * terms of the specified unit.
+     * Calculates the amount of time until another date-time in terms of the specified unit.
      * <p>
-     * This calculates the period between two date-times in terms of a single unit.
+     * This calculates the amount of time between two {@code OffsetDateTime}
+     * objects in terms of a single {@code TemporalUnit}.
      * The start and end points are {@code this} and the specified date-time.
      * The result will be negative if the end is before the start.
      * For example, the period in days between two date-times can be calculated
@@ -1564,9 +1564,9 @@
      * This instance is immutable and unaffected by this method call.
      *
      * @param endDateTime  the end date-time, which must be an {@code OffsetDateTime}, not null
-     * @param unit  the unit to measure the period in, not null
-     * @return the amount of the period between this date-time and the end date-time
-     * @throws DateTimeException if the period cannot be calculated
+     * @param unit  the unit to measure the amount in, not null
+     * @return the amount of time between this date-time and the end date-time
+     * @throws DateTimeException if the amount cannot be calculated
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
@@ -1574,7 +1574,7 @@
     public long periodUntil(Temporal endDateTime, TemporalUnit unit) {
         if (endDateTime instanceof OffsetDateTime == false) {
             Objects.requireNonNull(endDateTime, "endDateTime");
-            throw new DateTimeException("Unable to calculate period between objects of two different types");
+            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
         }
         if (unit instanceof ChronoUnit) {
             OffsetDateTime end = (OffsetDateTime) endDateTime;
diff --git a/jdk/src/share/classes/java/time/OffsetTime.java b/jdk/src/share/classes/java/time/OffsetTime.java
index c6afcb2..ff99069 100644
--- a/jdk/src/share/classes/java/time/OffsetTime.java
+++ b/jdk/src/share/classes/java/time/OffsetTime.java
@@ -102,7 +102,7 @@
  * For example, the value "13:45.30.123456789+02:00" can be stored
  * in an {@code OffsetTime}.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
@@ -1077,10 +1077,10 @@
     }
 
     /**
-     * Calculates the period between this time and another time in
-     * terms of the specified unit.
+     * Calculates the amount of time until another time in terms of the specified unit.
      * <p>
-     * This calculates the period between two times in terms of a single unit.
+     * This calculates the amount of time between two {@code OffsetTime}
+     * objects in terms of a single {@code TemporalUnit}.
      * The start and end points are {@code this} and the specified time.
      * The result will be negative if the end is before the start.
      * For example, the period in hours between two times can be calculated
@@ -1118,9 +1118,9 @@
      * This instance is immutable and unaffected by this method call.
      *
      * @param endTime  the end time, which must be an {@code OffsetTime}, not null
-     * @param unit  the unit to measure the period in, not null
-     * @return the amount of the period between this time and the end time
-     * @throws DateTimeException if the period cannot be calculated
+     * @param unit  the unit to measure the amount in, not null
+     * @return the amount of time between this time and the end time
+     * @throws DateTimeException if the amount cannot be calculated
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
@@ -1128,7 +1128,7 @@
     public long periodUntil(Temporal endTime, TemporalUnit unit) {
         if (endTime instanceof OffsetTime == false) {
             Objects.requireNonNull(endTime, "endTime");
-            throw new DateTimeException("Unable to calculate period between objects of two different types");
+            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
         }
         if (unit instanceof ChronoUnit) {
             OffsetTime end = (OffsetTime) endTime;
diff --git a/jdk/src/share/classes/java/time/Period.java b/jdk/src/share/classes/java/time/Period.java
index 85980d9..b2748f0 100644
--- a/jdk/src/share/classes/java/time/Period.java
+++ b/jdk/src/share/classes/java/time/Period.java
@@ -119,7 +119,7 @@
  * The months and years fields may be {@linkplain #normalized() normalized}.
  * The normalization assumes a 12 month year, so is not appropriate for all calendar systems.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/Ser.java b/jdk/src/share/classes/java/time/Ser.java
index 401a7cd..6071989 100644
--- a/jdk/src/share/classes/java/time/Ser.java
+++ b/jdk/src/share/classes/java/time/Ser.java
@@ -66,7 +66,7 @@
 /**
  * The shared serialization delegate for this package.
  *
- * <h3>Implementation notes</h3>
+ * @implNote
  * This class wraps the object being serialized, and takes a byte representing the type of the class to
  * be serialized.  This byte can also be used for versioning the serialization format.  In this case another
  * byte flag would be used in order to specify an alternative version of the type format.
diff --git a/jdk/src/share/classes/java/time/Year.java b/jdk/src/share/classes/java/time/Year.java
index 2ef92b5..c2d9974 100644
--- a/jdk/src/share/classes/java/time/Year.java
+++ b/jdk/src/share/classes/java/time/Year.java
@@ -115,7 +115,7 @@
  * However, any application that makes use of historical dates, and requires them
  * to be accurate will find the ISO-8601 approach unsuitable.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
@@ -813,10 +813,10 @@
     }
 
     /**
-     * Calculates the period between this year and another year in
-     * terms of the specified unit.
+     * Calculates the amount of time until another year in terms of the specified unit.
      * <p>
-     * This calculates the period between two years in terms of a single unit.
+     * This calculates the amount of time between two {@code Year}
+     * objects in terms of a single {@code TemporalUnit}.
      * The start and end points are {@code this} and the specified year.
      * The result will be negative if the end is before the start.
      * The {@code Temporal} passed to this method must be a {@code Year}.
@@ -851,9 +851,9 @@
      * This instance is immutable and unaffected by this method call.
      *
      * @param endYear  the end year, which must be a {@code Year}, not null
-     * @param unit  the unit to measure the period in, not null
-     * @return the amount of the period between this year and the end year
-     * @throws DateTimeException if the period cannot be calculated
+     * @param unit  the unit to measure the amount in, not null
+     * @return the amount of time between this year and the end year
+     * @throws DateTimeException if the amount cannot be calculated
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
@@ -861,7 +861,7 @@
     public long periodUntil(Temporal endYear, TemporalUnit unit) {
         if (endYear instanceof Year == false) {
             Objects.requireNonNull(endYear, "endYear");
-            throw new DateTimeException("Unable to calculate period between objects of two different types");
+            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
         }
         Year end = (Year) endYear;
         if (unit instanceof ChronoUnit) {
diff --git a/jdk/src/share/classes/java/time/YearMonth.java b/jdk/src/share/classes/java/time/YearMonth.java
index 312a36c..855774e 100644
--- a/jdk/src/share/classes/java/time/YearMonth.java
+++ b/jdk/src/share/classes/java/time/YearMonth.java
@@ -110,7 +110,7 @@
  * However, any application that makes use of historical dates, and requires them
  * to be accurate will find the ISO-8601 approach unsuitable.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
@@ -944,10 +944,10 @@
     }
 
     /**
-     * Calculates the period between this year-month and another year-month in
-     * terms of the specified unit.
+     * Calculates the amount of time until another year-month in terms of the specified unit.
      * <p>
-     * This calculates the period between two year-months in terms of a single unit.
+     * This calculates the amount of time between two {@code YearMonth}
+     * objects in terms of a single {@code TemporalUnit}.
      * The start and end points are {@code this} and the specified year-month.
      * The result will be negative if the end is before the start.
      * The {@code Temporal} passed to this method must be a {@code YearMonth}.
@@ -982,9 +982,9 @@
      * This instance is immutable and unaffected by this method call.
      *
      * @param endYearMonth  the end year-month, which must be a {@code YearMonth}, not null
-     * @param unit  the unit to measure the period in, not null
-     * @return the amount of the period between this year-month and the end year-month
-     * @throws DateTimeException if the period cannot be calculated
+     * @param unit  the unit to measure the amount in, not null
+     * @return the amount of time between this year-month and the end year-month
+     * @throws DateTimeException if the amount cannot be calculated
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
@@ -992,7 +992,7 @@
     public long periodUntil(Temporal endYearMonth, TemporalUnit unit) {
         if (endYearMonth instanceof YearMonth == false) {
             Objects.requireNonNull(endYearMonth, "endYearMonth");
-            throw new DateTimeException("Unable to calculate period between objects of two different types");
+            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
         }
         YearMonth end = (YearMonth) endYearMonth;
         if (unit instanceof ChronoUnit) {
diff --git a/jdk/src/share/classes/java/time/ZoneId.java b/jdk/src/share/classes/java/time/ZoneId.java
index 38a2a7c..026f73e 100644
--- a/jdk/src/share/classes/java/time/ZoneId.java
+++ b/jdk/src/share/classes/java/time/ZoneId.java
@@ -157,7 +157,7 @@
  * This approach is designed to allow a {@link ZonedDateTime} to be loaded and
  * queried, but not modified, on a Java Runtime with incomplete time-zone information.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This abstract class has two implementations, both of which are immutable and thread-safe.
  * One implementation models region-based IDs, the other is {@code ZoneOffset} modelling
  * offset-based IDs. This difference is visible in serialization.
diff --git a/jdk/src/share/classes/java/time/ZoneOffset.java b/jdk/src/share/classes/java/time/ZoneOffset.java
index 00f5dce..4bbc4e4 100644
--- a/jdk/src/share/classes/java/time/ZoneOffset.java
+++ b/jdk/src/share/classes/java/time/ZoneOffset.java
@@ -114,7 +114,7 @@
  * Implementations may choose to cache certain common offsets, however
  * applications must not rely on such caching.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/ZoneRegion.java b/jdk/src/share/classes/java/time/ZoneRegion.java
index 912ee04..af6a540 100644
--- a/jdk/src/share/classes/java/time/ZoneRegion.java
+++ b/jdk/src/share/classes/java/time/ZoneRegion.java
@@ -83,7 +83,7 @@
  * By contrast, the region identifier is well-defined and long-lived.
  * This separation also allows rules to be shared between regions if appropriate.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/ZonedDateTime.java b/jdk/src/share/classes/java/time/ZonedDateTime.java
index f5115c6..e7ed555 100644
--- a/jdk/src/share/classes/java/time/ZonedDateTime.java
+++ b/jdk/src/share/classes/java/time/ZonedDateTime.java
@@ -142,7 +142,7 @@
  * a vital, but secondary, piece of information, used to ensure that the class
  * represents an instant, especially during a daylight savings overlap.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * A {@code ZonedDateTime} holds state equivalent to three separate objects,
  * a {@code LocalDateTime}, a {@code ZoneId} and the resolved {@code ZoneOffset}.
  * The offset and local date-time are used to define an instant when necessary.
@@ -1983,10 +1983,10 @@
     }
 
     /**
-     * Calculates the period between this date-time and another date-time in
-     * terms of the specified unit.
+     * Calculates the amount of time until another date-time in terms of the specified unit.
      * <p>
-     * This calculates the period between two date-times in terms of a single unit.
+     * This calculates the amount of time between two {@code ZonedDateTime}
+     * objects in terms of a single {@code TemporalUnit}.
      * The start and end points are {@code this} and the specified date-time.
      * The result will be negative if the end is before the start.
      * For example, the period in days between two date-times can be calculated
@@ -2040,9 +2040,9 @@
      * This instance is immutable and unaffected by this method call.
      *
      * @param endDateTime  the end date-time, which must be a {@code ZonedDateTime}, not null
-     * @param unit  the unit to measure the period in, not null
-     * @return the amount of the period between this date-time and the end date-time
-     * @throws DateTimeException if the period cannot be calculated
+     * @param unit  the unit to measure the amount in, not null
+     * @return the amount of time between this date-time and the end date-time
+     * @throws DateTimeException if the amount cannot be calculated
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
@@ -2050,7 +2050,7 @@
     public long periodUntil(Temporal endDateTime, TemporalUnit unit) {
         if (endDateTime instanceof ZonedDateTime == false) {
             Objects.requireNonNull(endDateTime, "endDateTime");
-            throw new DateTimeException("Unable to calculate period between objects of two different types");
+            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
         }
         if (unit instanceof ChronoUnit) {
             ZonedDateTime end = (ZonedDateTime) endDateTime;
diff --git a/jdk/src/share/classes/java/time/chrono/ChronoDateImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoDateImpl.java
index 26203fa..14e2bf5 100644
--- a/jdk/src/share/classes/java/time/chrono/ChronoDateImpl.java
+++ b/jdk/src/share/classes/java/time/chrono/ChronoDateImpl.java
@@ -130,7 +130,7 @@
  * The subclass must function according to the {@code Chronology} class description and must provide its
  * {@link java.time.chrono.Chronology#getId() chronlogy ID} and {@link Chronology#getCalendarType() calendar type}. </p>
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This abstract class must be implemented with care to ensure other classes operate correctly.
  * All implementations that can be instantiated must be final, immutable and thread-safe.
  * Subclasses should be Serializable wherever possible.
@@ -325,11 +325,11 @@
         Objects.requireNonNull(endDateTime, "endDateTime");
         Objects.requireNonNull(unit, "unit");
         if (endDateTime instanceof ChronoLocalDate == false) {
-            throw new DateTimeException("Unable to calculate period between objects of two different types");
+            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
         }
         ChronoLocalDate<?> end = (ChronoLocalDate<?>) endDateTime;
         if (getChronology().equals(end.getChronology()) == false) {
-            throw new DateTimeException("Unable to calculate period between two different chronologies");
+            throw new DateTimeException("Unable to calculate amount as objects have different chronologies");
         }
         if (unit instanceof ChronoUnit) {
             switch ((ChronoUnit) unit) {
diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java
index 4f648c9..31c0826 100644
--- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java
+++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java
@@ -234,7 +234,7 @@
  * Use {@link TemporalAccessor} if read-only access is required, or use {@link Temporal}
  * if read-write access is required.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This interface must be implemented with care to ensure other classes operate correctly.
  * All implementations that can be instantiated must be final, immutable and thread-safe.
  * Subclasses should be Serializable wherever possible.
@@ -257,6 +257,7 @@
      * This allows dates in different calendar systems to be compared based
      * on the position of the date on the local time-line.
      * The underlying comparison is equivalent to comparing the epoch-day.
+     * @return a comparator that compares in time-line order ignoring the chronology
      *
      * @see #isAfter
      * @see #isBefore
@@ -510,17 +511,17 @@
     }
 
     /**
-     * Calculates the period between this date and another date in
-     * terms of the specified unit.
+     * Calculates the amount of time until another date in terms of the specified unit.
      * <p>
-     * This calculates the period between two dates in terms of a single unit.
+     * This calculates the amount of time between two {@code ChronoLocalDate}
+     * objects in terms of a single {@code TemporalUnit}.
      * The start and end points are {@code this} and the specified date.
      * The result will be negative if the end is before the start.
      * The {@code Temporal} passed to this method must be a
      * {@code ChronoLocalDate} in the same chronology.
      * The calculation returns a whole number, representing the number of
      * complete units between the two dates.
-     * For example, the period in days between two dates can be calculated
+     * For example, the amount in days between two dates can be calculated
      * using {@code startDate.periodUntil(endDate, DAYS)}.
      * <p>
      * There are two equivalent ways of using this method.
@@ -548,9 +549,9 @@
      *
      * @param endDate  the end date, which must be a {@code ChronoLocalDate}
      *  in the same chronology, not null
-     * @param unit  the unit to measure the period in, not null
-     * @return the amount of the period between this date and the end date
-     * @throws DateTimeException if the period cannot be calculated
+     * @param unit  the unit to measure the amount in, not null
+     * @return the amount of time between this date and the end date
+     * @throws DateTimeException if the amount cannot be calculated
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override  // override for Javadoc
diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java
index d706db1..f0a893a 100644
--- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java
+++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java
@@ -106,7 +106,7 @@
  * Ensure that the discussion in {@code ChronoLocalDate} has been read and understood
  * before using this interface.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This interface must be implemented with care to ensure other classes operate correctly.
  * All implementations that can be instantiated must be final, immutable and thread-safe.
  * Subclasses should be Serializable wherever possible.
@@ -127,6 +127,8 @@
      * on the position of the date-time on the local time-line.
      * The underlying comparison is equivalent to comparing the epoch-day and nano-of-day.
      *
+     * @return a comparator that compares in time-line order ignoring the chronology
+     *
      * @see #isAfter
      * @see #isBefore
      * @see #isEqual
diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java
index fd6e7c0..1f7195b 100644
--- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java
+++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java
@@ -92,7 +92,7 @@
  * It does not store or represent a time-zone. For example, the value
  * "2nd October 2007 at 13:45.30.123456789" can be stored in an {@code ChronoLocalDateTime}.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @param <D> the concrete type for the date of this date-time
@@ -353,12 +353,12 @@
     @Override
     public long periodUntil(Temporal endDateTime, TemporalUnit unit) {
         if (endDateTime instanceof ChronoLocalDateTime == false) {
-            throw new DateTimeException("Unable to calculate period between objects of two different types");
+            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
         }
         @SuppressWarnings("unchecked")
         ChronoLocalDateTime<D> end = (ChronoLocalDateTime<D>) endDateTime;
         if (toLocalDate().getChronology().equals(end.toLocalDate().getChronology()) == false) {
-            throw new DateTimeException("Unable to calculate period between two different chronologies");
+            throw new DateTimeException("Unable to calculate amount as objects have different chronologies");
         }
         if (unit instanceof ChronoUnit) {
             ChronoUnit f = (ChronoUnit) unit;
diff --git a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java
index 4307c10..d838a36 100644
--- a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java
+++ b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java
@@ -107,7 +107,7 @@
  * Ensure that the discussion in {@code ChronoLocalDate} has been read and understood
  * before using this interface.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This interface must be implemented with care to ensure other classes operate correctly.
  * All implementations that can be instantiated must be final, immutable and thread-safe.
  * Subclasses should be Serializable wherever possible.
@@ -128,6 +128,8 @@
      * on the position of the date-time on the instant time-line.
      * The underlying comparison is equivalent to comparing the epoch-second and nano-of-second.
      *
+     * @return a comparator that compares in time-line order ignoring the chronology
+     *
      * @see #isAfter
      * @see #isBefore
      * @see #isEqual
diff --git a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java
index 0061eeb..835ec93 100644
--- a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java
+++ b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java
@@ -95,7 +95,7 @@
  * the local time-line overlaps, typically as a result of the end of daylight time.
  * Information about the local-time can be obtained using methods on the time-zone.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @param <D> the concrete type for the date of this date-time
@@ -287,12 +287,12 @@
     @Override
     public long periodUntil(Temporal endDateTime, TemporalUnit unit) {
         if (endDateTime instanceof ChronoZonedDateTime == false) {
-            throw new DateTimeException("Unable to calculate period between objects of two different types");
+            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
         }
         @SuppressWarnings("unchecked")
         ChronoZonedDateTime<D> end = (ChronoZonedDateTime<D>) endDateTime;
         if (toLocalDate().getChronology().equals(end.toLocalDate().getChronology()) == false) {
-            throw new DateTimeException("Unable to calculate period between two different chronologies");
+            throw new DateTimeException("Unable to calculate amount as objects have different chronologies");
         }
         if (unit instanceof ChronoUnit) {
             end = end.withZoneSameInstant(offset);
diff --git a/jdk/src/share/classes/java/time/chrono/Chronology.java b/jdk/src/share/classes/java/time/chrono/Chronology.java
index 6c61c32e..e5daae7 100644
--- a/jdk/src/share/classes/java/time/chrono/Chronology.java
+++ b/jdk/src/share/classes/java/time/chrono/Chronology.java
@@ -176,7 +176,7 @@
  * CLDR specification then the calendar type is the concatenation of the
  * CLDR type and, if applicable, the CLDR variant,
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class must be implemented with care to ensure other classes operate correctly.
  * All implementations that can be instantiated must be final, immutable and thread-safe.
  * Subclasses should be Serializable wherever possible.
@@ -338,16 +338,13 @@
      * <p>
      * The {@code Locale} class also supports an extension mechanism that
      * can be used to identify a calendar system. The mechanism is a form
-     * of key-value pairs, where the calendar system has the key "ca"
-     * and an optional variant key "cv".
+     * of key-value pairs, where the calendar system has the key "ca".
      * For example, the locale "en-JP-u-ca-japanese" represents the English
      * language as used in Japan with the Japanese calendar system.
      * <p>
      * This method finds the desired calendar system by in a manner equivalent
      * to passing "ca" to {@link Locale#getUnicodeLocaleType(String)}.
      * If the "ca" key is not present, then {@code IsoChronology} is returned.
-     * The variant, if present, is appended to the "ca" value separated by  "-"
-     * and the concatenated value is used to find the calendar system by type.
      * <p>
      * Note that the behavior of this method differs from the older
      * {@link java.util.Calendar#getInstance(Locale)} method.
@@ -374,10 +371,6 @@
         if (type == null || "iso".equals(type) || "iso8601".equals(type)) {
             return IsoChronology.INSTANCE;
         }
-        String variant = locale.getUnicodeLocaleType("cv");
-        if (variant != null && !variant.isEmpty()) {
-            type = type + '-' + variant;
-        }
         // Not pre-defined; lookup by the type
         do {
             Chronology chrono = CHRONOS_BY_TYPE.get(type);
@@ -563,7 +556,7 @@
      * and the variant, if applicable, is appended separated by "-".
      * The calendar type is used to lookup the {@code Chronology} using {@link #of(String)}.
      *
-     * @return the calendar system type, null if the calendar is not defined
+     * @return the calendar system type, null if the calendar is not defined by CLDR/LDML
      * @see #getId()
      */
     public abstract String getCalendarType();
diff --git a/jdk/src/share/classes/java/time/chrono/Era.java b/jdk/src/share/classes/java/time/chrono/Era.java
index a26953e..330346d 100644
--- a/jdk/src/share/classes/java/time/chrono/Era.java
+++ b/jdk/src/share/classes/java/time/chrono/Era.java
@@ -93,7 +93,7 @@
  * <p>
  * Instances of {@code Era} may be compared using the {@code ==} operator.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This interface must be implemented with care to ensure other classes operate correctly.
  * All implementations must be singletons - final, immutable and thread-safe.
  * It is recommended to use an enum whenever possible.
diff --git a/jdk/src/share/classes/java/time/chrono/HijrahChronology.java b/jdk/src/share/classes/java/time/chrono/HijrahChronology.java
index 5d53855..63dfc1c 100644
--- a/jdk/src/share/classes/java/time/chrono/HijrahChronology.java
+++ b/jdk/src/share/classes/java/time/chrono/HijrahChronology.java
@@ -133,9 +133,10 @@
  *      Chronology chrono = Chronology.ofLocale(locale);
  * </pre>
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
- * <h3>Implementation Note for Hijrah Calendar Variant Configuration</h3>
+ *
+ * @implNote
  * Each Hijrah variant is configured individually. Each variant is defined by a
  * property resource that defines the {@code ID}, the {@code calendar type},
  * the start of the calendar, the alignment with the
@@ -230,6 +231,11 @@
      */
     public static final HijrahChronology INSTANCE;
     /**
+     * Flag to indicate the initialization of configuration data is complete.
+     * @see #checkCalendarInit()
+     */
+    private volatile boolean initComplete;
+    /**
      * Array of epoch days indexed by Hijrah Epoch month.
      * Computed by {@link #loadCalendarData}.
      */
@@ -285,7 +291,8 @@
     private static final String PROP_TYPE_SUFFIX = ".type";
 
     /**
-     * Name data.
+     * Static initialization of the predefined calendars found in the
+     * lib/calendars.properties file.
      */
     static {
         try {
@@ -299,8 +306,7 @@
             // Register it by its aliases
             Chronology.registerChrono(INSTANCE, "Hijrah");
             Chronology.registerChrono(INSTANCE, "islamic");
-
-        } catch (Exception ex) {
+        } catch (DateTimeException ex) {
             // Absence of Hijrah calendar is fatal to initializing this class.
             PlatformLogger logger = PlatformLogger.getLogger("java.time.chrono");
             logger.severe("Unable to initialize Hijrah calendar: Hijrah-umalqura", ex);
@@ -327,7 +333,7 @@
                     // Create and register the variant
                     HijrahChronology chrono = new HijrahChronology(id);
                     Chronology.registerChrono(chrono);
-                } catch (Exception ex) {
+                } catch (DateTimeException ex) {
                     // Log error and continue
                     PlatformLogger logger = PlatformLogger.getLogger("java.time.chrono");
                     logger.severe("Unable to initialize Hijrah calendar: " + id, ex);
@@ -343,22 +349,39 @@
      * The property names are {@code "calendar.hijrah." + id}
      * and  {@code "calendar.hijrah." + id + ".type"}
      * @param id the id of the calendar
-     * @throws Exception if the resource can not be accessed or
-     *    the format is invalid
+     * @throws DateTimeException if the calendar type is missing from the properties file.
+     * @throws IllegalArgumentException if the id is empty
      */
-    private HijrahChronology(String id) throws Exception {
+    private HijrahChronology(String id) throws DateTimeException {
         if (id.isEmpty()) {
             throw new IllegalArgumentException("calendar id is empty");
         }
+        String propName = PROP_PREFIX + id + PROP_TYPE_SUFFIX;
+        String calType = calendarProperties.getProperty(propName);
+        if (calType == null || calType.isEmpty()) {
+            throw new DateTimeException("calendarType is missing or empty for: " + propName);
+        }
         this.typeId = id;
-        this.calendarType = calendarProperties.getProperty(PROP_PREFIX + id + PROP_TYPE_SUFFIX);
+        this.calendarType = calType;
+    }
 
-        try {
-            String resource = calendarProperties.getProperty(PROP_PREFIX + id);
-            Objects.requireNonNull(resource, "Resource missing for calendar");
-            loadCalendarData(resource);
-        } catch (Exception ex) {
-            throw new Exception("Unable to initialize HijrahCalendar: " + id, ex);
+    /**
+     * Check and ensure that the calendar data has been initialized.
+     * The initialization check is performed at the boundary between
+     * public and package methods.  If a public calls another public method
+     * a check is not necessary in the caller.
+     * The constructors of HijrahDate call {@link #getEpochDay} or
+     * {@link #getHijrahDateInfo} so every call from HijrahDate to a
+     * HijrahChronology via package private methods has been checked.
+     *
+     * @throws DateTimeException if the calendar data configuration is
+     *     malformed or IOExceptions occur loading the data
+     */
+    private void checkCalendarInit() {
+        // Keep this short so it can be inlined for performance
+        if (initComplete == false) {
+            loadCalendarData();
+            initComplete = true;
         }
     }
 
@@ -509,6 +532,7 @@
     //-----------------------------------------------------------------------
     @Override
     public boolean isLeapYear(long prolepticYear) {
+        checkCalendarInit();
         int epochMonth = yearToEpochMonth((int) prolepticYear);
         if (epochMonth < 0 || epochMonth > maxEpochDay) {
             throw new DateTimeException("Hijrah date out of range");
@@ -543,6 +567,7 @@
     //-----------------------------------------------------------------------
     @Override
     public ValueRange range(ChronoField field) {
+        checkCalendarInit();
         if (field instanceof ChronoField) {
             ChronoField f = field;
             switch (f) {
@@ -595,6 +620,7 @@
      * @return int[0] = YEAR, int[1] = MONTH, int[2] = DATE
      */
     int[] getHijrahDateInfo(int epochDay) {
+        checkCalendarInit();    // ensure that the chronology is initialized
         if (epochDay < minEpochDay || epochDay >= maxEpochDay) {
             throw new DateTimeException("Hijrah date out of range");
         }
@@ -621,6 +647,7 @@
      * @return the epoch day
      */
     long getEpochDay(int prolepticYear, int monthOfYear, int dayOfMonth) {
+        checkCalendarInit();    // ensure that the chronology is initialized
         checkValidMonth(monthOfYear);
         int epochMonth = yearToEpochMonth(prolepticYear) + (monthOfYear - 1);
         if (epochMonth < 0 || epochMonth >= hijrahEpochMonthStartDays.length) {
@@ -846,84 +873,90 @@
     }
 
     /**
-     * Loads and processes the Hijrah calendar properties file.
+     * Loads and processes the Hijrah calendar properties file for this calendarType.
      * The starting Hijrah date and the corresponding ISO date are
      * extracted and used to calculate the epochDate offset.
      * The version number is identified and ignored.
      * Everything else is the data for a year with containing the length of each
      * of 12 months.
      *
-     * @param resourceName  containing the properties defining the calendar, not null
-     * @throws IllegalArgumentException  if any of the values are malformed
-     * @throws NumberFormatException  if numbers, including properties that should
-     *      be years are invalid
-     * @throws IOException  if access to the property resource fails.
+     * @throws DateTimeException if initialization of the calendar data from the
+     *     resource fails
      */
-    private void loadCalendarData(String resourceName)  throws Exception {
-        Properties props = readConfigProperties(resourceName);
+    private void loadCalendarData() {
+        try {
+            String resourceName = calendarProperties.getProperty(PROP_PREFIX + typeId);
+            Objects.requireNonNull(resourceName, "Resource missing for calendar: " + PROP_PREFIX + typeId);
+            Properties props = readConfigProperties(resourceName);
 
-        Map<Integer, int[]> years = new HashMap<>();
-        int minYear = Integer.MAX_VALUE;
-        int maxYear = Integer.MIN_VALUE;
-        String id = null;
-        String type = null;
-        String version = null;
-        int isoStart = 0;
-        for (Map.Entry<Object, Object> entry : props.entrySet()) {
-            String key = (String) entry.getKey();
-            switch (key) {
-                case KEY_ID:
-                    id = (String)entry.getValue();
-                    break;
-                case KEY_TYPE:
-                    type = (String)entry.getValue();
-                    break;
-                case KEY_VERSION:
-                    version = (String)entry.getValue();
-                    break;
-                case KEY_ISO_START: {
-                    int[] ymd = parseYMD((String) entry.getValue());
-                    isoStart = (int) LocalDate.of(ymd[0], ymd[1], ymd[2]).toEpochDay();
-                    break;
-                }
-                default:
-                    try {
-                        // Everything else is either a year or invalid
-                        int year = Integer.valueOf(key);
-                        int[] months = parseMonths((String) entry.getValue());
-                        years.put(year, months);
-                        maxYear = Math.max(maxYear, year);
-                        minYear = Math.min(minYear, year);
-                    } catch (NumberFormatException nfe) {
-                        throw new IllegalArgumentException("bad key: " + key);
+            Map<Integer, int[]> years = new HashMap<>();
+            int minYear = Integer.MAX_VALUE;
+            int maxYear = Integer.MIN_VALUE;
+            String id = null;
+            String type = null;
+            String version = null;
+            int isoStart = 0;
+            for (Map.Entry<Object, Object> entry : props.entrySet()) {
+                String key = (String) entry.getKey();
+                switch (key) {
+                    case KEY_ID:
+                        id = (String)entry.getValue();
+                        break;
+                    case KEY_TYPE:
+                        type = (String)entry.getValue();
+                        break;
+                    case KEY_VERSION:
+                        version = (String)entry.getValue();
+                        break;
+                    case KEY_ISO_START: {
+                        int[] ymd = parseYMD((String) entry.getValue());
+                        isoStart = (int) LocalDate.of(ymd[0], ymd[1], ymd[2]).toEpochDay();
+                        break;
                     }
+                    default:
+                        try {
+                            // Everything else is either a year or invalid
+                            int year = Integer.valueOf(key);
+                            int[] months = parseMonths((String) entry.getValue());
+                            years.put(year, months);
+                            maxYear = Math.max(maxYear, year);
+                            minYear = Math.min(minYear, year);
+                        } catch (NumberFormatException nfe) {
+                            throw new IllegalArgumentException("bad key: " + key);
+                        }
+                }
             }
-        }
 
-        if (!getId().equals(id)) {
-            throw new IllegalArgumentException("Configuration is for a different calendar: " + id);
-        }
-        if (!getCalendarType().equals(type)) {
-            throw new IllegalArgumentException("Configuration is for a different calendar type: " + type);
-        }
-        if (version == null || version.isEmpty()) {
-            throw new IllegalArgumentException("Configuration does not contain a version");
-        }
-        if (isoStart == 0) {
-            throw new IllegalArgumentException("Configuration does not contain a ISO start date");
-        }
+            if (!getId().equals(id)) {
+                throw new IllegalArgumentException("Configuration is for a different calendar: " + id);
+            }
+            if (!getCalendarType().equals(type)) {
+                throw new IllegalArgumentException("Configuration is for a different calendar type: " + type);
+            }
+            if (version == null || version.isEmpty()) {
+                throw new IllegalArgumentException("Configuration does not contain a version");
+            }
+            if (isoStart == 0) {
+                throw new IllegalArgumentException("Configuration does not contain a ISO start date");
+            }
 
-        // Now create and validate the array of epochDays indexed by epochMonth
-        hijrahStartEpochMonth = minYear * 12;
-        minEpochDay = isoStart;
-        hijrahEpochMonthStartDays = createEpochMonths(minEpochDay, minYear, maxYear, years);
-        maxEpochDay = hijrahEpochMonthStartDays[hijrahEpochMonthStartDays.length - 1];
+            // Now create and validate the array of epochDays indexed by epochMonth
+            hijrahStartEpochMonth = minYear * 12;
+            minEpochDay = isoStart;
+            hijrahEpochMonthStartDays = createEpochMonths(minEpochDay, minYear, maxYear, years);
+            maxEpochDay = hijrahEpochMonthStartDays[hijrahEpochMonthStartDays.length - 1];
 
-        // Compute the min and max year length in days.
-        for (int year = minYear; year < maxYear; year++) {
-            int length = getYearLength(year);
-            minYearLength = Math.min(minYearLength, length);
-            maxYearLength = Math.max(maxYearLength, length);
+            // Compute the min and max year length in days.
+            for (int year = minYear; year < maxYear; year++) {
+                int length = getYearLength(year);
+                minYearLength = Math.min(minYearLength, length);
+                maxYearLength = Math.max(maxYearLength, length);
+            }
+        } catch (Exception ex) {
+            // Log error and throw a DateTimeException
+            PlatformLogger logger = PlatformLogger.getLogger("java.time.chrono");
+            logger.severe("Unable to initialize Hijrah calendar proxy: " + typeId, ex);
+            throw new DateTimeException("Unable to initialize HijrahCalendar: " + typeId, ex);
         }
     }
 
diff --git a/jdk/src/share/classes/java/time/chrono/HijrahDate.java b/jdk/src/share/classes/java/time/chrono/HijrahDate.java
index fc9bd5b..3c01e94 100644
--- a/jdk/src/share/classes/java/time/chrono/HijrahDate.java
+++ b/jdk/src/share/classes/java/time/chrono/HijrahDate.java
@@ -102,7 +102,7 @@
  * to create new HijrahDate instances.
  * Alternatively, the {@link #withVariant} method can be used to convert
  * to a new HijrahChronology.
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/chrono/HijrahEra.java b/jdk/src/share/classes/java/time/chrono/HijrahEra.java
index 66622b5..1e99d60 100644
--- a/jdk/src/share/classes/java/time/chrono/HijrahEra.java
+++ b/jdk/src/share/classes/java/time/chrono/HijrahEra.java
@@ -81,7 +81,7 @@
  * <b>Do not use {@code ordinal()} to obtain the numeric representation of {@code HijrahEra}.
  * Use {@code getValue()} instead.</b>
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This is an immutable and thread-safe enum.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/chrono/IsoChronology.java b/jdk/src/share/classes/java/time/chrono/IsoChronology.java
index 3624e8d..66b0dc1 100644
--- a/jdk/src/share/classes/java/time/chrono/IsoChronology.java
+++ b/jdk/src/share/classes/java/time/chrono/IsoChronology.java
@@ -121,7 +121,7 @@
  * <li>leap-year - Leap years occur every 4 years, except where the year is divisble by 100 and not divisble by 400.
  * </ul><p>
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
@@ -588,7 +588,12 @@
         int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR));
         int dom = DAY_OF_MONTH.checkValidIntValue(fieldValues.remove(DAY_OF_MONTH));
         if (resolverStyle == ResolverStyle.SMART) {  // previous valid
-            dom = Math.min(dom, Month.of(moy).length(Year.isLeap(y)));
+            if (moy == 4 || moy == 6 || moy == 9 || moy == 11) {
+                dom = Math.min(dom, 30);
+            } else if (moy == 2) {
+                dom = Math.min(dom, Month.FEBRUARY.length(Year.isLeap(y)));
+
+            }
         }
         return LocalDate.of(y, moy, dom);
     }
diff --git a/jdk/src/share/classes/java/time/chrono/IsoEra.java b/jdk/src/share/classes/java/time/chrono/IsoEra.java
index 445aa45..15fa2e4 100644
--- a/jdk/src/share/classes/java/time/chrono/IsoEra.java
+++ b/jdk/src/share/classes/java/time/chrono/IsoEra.java
@@ -97,7 +97,7 @@
  * <b>Do not use {@code ordinal()} to obtain the numeric representation of {@code IsoEra}.
  * Use {@code getValue()} instead.</b>
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This is an immutable and thread-safe enum.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/chrono/JapaneseChronology.java b/jdk/src/share/classes/java/time/chrono/JapaneseChronology.java
index 1d07a36..1aead71 100644
--- a/jdk/src/share/classes/java/time/chrono/JapaneseChronology.java
+++ b/jdk/src/share/classes/java/time/chrono/JapaneseChronology.java
@@ -85,7 +85,7 @@
  * Only Meiji (1865-04-07 - 1868-09-07) and later eras are supported.
  * Older eras are handled as an unknown era where the year-of-era is the ISO year.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
@@ -197,7 +197,7 @@
      */
     @Override
     public JapaneseDate dateYearDay(Era era, int yearOfEra, int dayOfYear) {
-        return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear);
+        return JapaneseDate.ofYearDay((JapaneseEra) era, yearOfEra, dayOfYear);
     }
 
     /**
@@ -251,16 +251,19 @@
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public ChronoLocalDateTime<JapaneseDate> localDateTime(TemporalAccessor temporal) {
         return (ChronoLocalDateTime<JapaneseDate>)super.localDateTime(temporal);
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public ChronoZonedDateTime<JapaneseDate> zonedDateTime(TemporalAccessor temporal) {
         return (ChronoZonedDateTime<JapaneseDate>)super.zonedDateTime(temporal);
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public ChronoZonedDateTime<JapaneseDate> zonedDateTime(Instant instant, ZoneId zone) {
         return (ChronoZonedDateTime<JapaneseDate>)super.zonedDateTime(instant, zone);
     }
@@ -286,19 +289,27 @@
         if (era instanceof JapaneseEra == false) {
             throw new ClassCastException("Era must be JapaneseEra");
         }
+
+        if (era == JapaneseEra.SEIREKI) {
+            JapaneseEra nextEra = JapaneseEra.values()[1];
+            int nextEraYear = nextEra.getPrivateEra().getSinceDate().getYear();
+            if (yearOfEra >= nextEraYear || yearOfEra < Year.MIN_VALUE) {
+                throw new DateTimeException("Invalid yearOfEra value");
+            }
+            return yearOfEra;
+        }
+
         JapaneseEra jera = (JapaneseEra) era;
         int gregorianYear = jera.getPrivateEra().getSinceDate().getYear() + yearOfEra - 1;
         if (yearOfEra == 1) {
             return gregorianYear;
         }
-        LocalGregorianCalendar.Date jdate = JCAL.newCalendarDate(null);
-        jdate.setEra(jera.getPrivateEra()).setDate(yearOfEra, 1, 1);
-        if (!JapaneseChronology.JCAL.validate(jdate)) {
-            throw new DateTimeException("Invalid yearOfEra value");
-        }
-        JCAL.normalize(jdate);
-        if (jdate.getNormalizedYear() == gregorianYear) {
-            return gregorianYear;
+        if (gregorianYear >= Year.MIN_VALUE && gregorianYear <= Year.MAX_VALUE) {
+            LocalGregorianCalendar.Date jdate = JCAL.newCalendarDate(null);
+            jdate.setEra(jera.getPrivateEra()).setDate(yearOfEra, 1, 1);
+            if (JapaneseChronology.JCAL.validate(jdate)) {
+                return gregorianYear;
+            }
         }
         throw new DateTimeException("Invalid yearOfEra value");
     }
@@ -322,13 +333,20 @@
 
     @Override
     public List<Era> eras() {
-        return Arrays.asList(JapaneseEra.values());
+        return Arrays.<Era>asList(JapaneseEra.values());
+    }
+
+    JapaneseEra getCurrentEra() {
+        // Assume that the last JapaneseEra is the current one.
+        JapaneseEra[] eras = JapaneseEra.values();
+        return eras[eras.length - 1];
     }
 
     //-----------------------------------------------------------------------
     @Override
     public ValueRange range(ChronoField field) {
         switch (field) {
+            case YEAR:
             case DAY_OF_MONTH:
             case DAY_OF_WEEK:
             case MICRO_OF_DAY:
@@ -345,27 +363,23 @@
             case NANO_OF_SECOND:
             case CLOCK_HOUR_OF_DAY:
             case CLOCK_HOUR_OF_AMPM:
-            case EPOCH_DAY:  // TODO: if year is restricted, then so is epoch-day
+            case EPOCH_DAY:
+            case PROLEPTIC_MONTH:
+            case MONTH_OF_YEAR:
                 return field.range();
+            case ERA:
+                return ValueRange.of(JapaneseEra.SEIREKI.getValue(),
+                                     getCurrentEra().getValue());
         }
         Calendar jcal = Calendar.getInstance(LOCALE);
         int fieldIndex;
         switch (field) {
-            case ERA:
-                return ValueRange.of(JapaneseEra.SEIREKI.getValue(),
-                        jcal.getMaximum(Calendar.ERA) - JapaneseEra.ERA_OFFSET);
-            case YEAR:
-            case YEAR_OF_ERA:
-                // TODO: this is not right
+            case YEAR_OF_ERA: {
+                int startYear = getCurrentEra().getPrivateEra().getSinceDate().getYear();
                 return ValueRange.of(Year.MIN_VALUE, jcal.getGreatestMinimum(Calendar.YEAR),
-                        jcal.getLeastMaximum(Calendar.YEAR), Year.MAX_VALUE);
-            case PROLEPTIC_MONTH:
-                // TODO: should be the range of months bound by the valid range of years
-                return ValueRange.of((jcal.getGreatestMinimum(Calendar.YEAR) - 1) * 12,
-                        (jcal.getLeastMaximum(Calendar.YEAR)) * 12);
-            case MONTH_OF_YEAR:
-                return ValueRange.of(jcal.getMinimum(Calendar.MONTH) + 1, jcal.getGreatestMinimum(Calendar.MONTH) + 1,
-                        jcal.getLeastMaximum(Calendar.MONTH) + 1, jcal.getMaximum(Calendar.MONTH) + 1);
+                        jcal.getLeastMaximum(Calendar.YEAR) + 1, // +1 due to the different definitions
+                        Year.MAX_VALUE - startYear);
+            }
             case DAY_OF_YEAR:
                 fieldIndex = Calendar.DAY_OF_YEAR;
                 break;
diff --git a/jdk/src/share/classes/java/time/chrono/JapaneseDate.java b/jdk/src/share/classes/java/time/chrono/JapaneseDate.java
index 7ba7fd3..646315b 100644
--- a/jdk/src/share/classes/java/time/chrono/JapaneseDate.java
+++ b/jdk/src/share/classes/java/time/chrono/JapaneseDate.java
@@ -83,6 +83,7 @@
 import java.util.Calendar;
 import java.util.Objects;
 
+import sun.util.calendar.CalendarDate;
 import sun.util.calendar.LocalGregorianCalendar;
 
 /**
@@ -101,7 +102,7 @@
  * Calling {@code japaneseDate.get(ERA)} will return 2, corresponding to
  * {@code JapaneseChronology.ERA_HEISEI}.<br>
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
@@ -234,6 +235,24 @@
         return of(prolepticYear, date.getMonthValue(), date.getDayOfMonth());
     }
 
+    static JapaneseDate ofYearDay(JapaneseEra era, int yearOfEra, int dayOfYear) {
+        CalendarDate firstDay = era.getPrivateEra().getSinceDate();
+        LocalGregorianCalendar.Date jdate = JapaneseChronology.JCAL.newCalendarDate(null);
+        jdate.setEra(era.getPrivateEra());
+        if (yearOfEra == 1) {
+            jdate.setDate(yearOfEra, firstDay.getMonth(), firstDay.getDayOfMonth() + dayOfYear - 1);
+        } else {
+            jdate.setDate(yearOfEra, 1, dayOfYear);
+        }
+        JapaneseChronology.JCAL.normalize(jdate);
+        if (era.getPrivateEra() != jdate.getEra() || yearOfEra != jdate.getYear()) {
+            throw new DateTimeException("Invalid parameters");
+        }
+        LocalDate localdate = LocalDate.of(jdate.getNormalizedYear(),
+                                      jdate.getMonth(), jdate.getDayOfMonth());
+        return new JapaneseDate(era, yearOfEra, localdate);
+    }
+
     /**
      * Obtains a {@code JapaneseDate} representing a date in the Japanese calendar
      * system from the era, year-of-era, month-of-year and day-of-month fields.
diff --git a/jdk/src/share/classes/java/time/chrono/JapaneseEra.java b/jdk/src/share/classes/java/time/chrono/JapaneseEra.java
index f89de19..1763579 100644
--- a/jdk/src/share/classes/java/time/chrono/JapaneseEra.java
+++ b/jdk/src/share/classes/java/time/chrono/JapaneseEra.java
@@ -91,7 +91,7 @@
  * and the year of era of Seireki is proleptic Gregorian year.
  * (The Julian to Gregorian transition is not supported.)
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/chrono/MinguoChronology.java b/jdk/src/share/classes/java/time/chrono/MinguoChronology.java
index f977b49..1c9c2e3 100644
--- a/jdk/src/share/classes/java/time/chrono/MinguoChronology.java
+++ b/jdk/src/share/classes/java/time/chrono/MinguoChronology.java
@@ -95,7 +95,7 @@
  *  are never out of step.
  * </ul><p>
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/chrono/MinguoDate.java b/jdk/src/share/classes/java/time/chrono/MinguoDate.java
index 07ce800..b6a5582 100644
--- a/jdk/src/share/classes/java/time/chrono/MinguoDate.java
+++ b/jdk/src/share/classes/java/time/chrono/MinguoDate.java
@@ -89,7 +89,7 @@
  * This calendar system is primarily used in the Republic of China, often known as Taiwan.
  * Dates are aligned such that {@code 0001-01-01 (Minguo)} is {@code 1912-01-01 (ISO)}.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/chrono/MinguoEra.java b/jdk/src/share/classes/java/time/chrono/MinguoEra.java
index 0563515..edf1ad5 100644
--- a/jdk/src/share/classes/java/time/chrono/MinguoEra.java
+++ b/jdk/src/share/classes/java/time/chrono/MinguoEra.java
@@ -102,7 +102,7 @@
  * <b>Do not use {@code ordinal()} to obtain the numeric representation of {@code MinguoEra}.
  * Use {@code getValue()} instead.</b>
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This is an immutable and thread-safe enum.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/chrono/Ser.java b/jdk/src/share/classes/java/time/chrono/Ser.java
index 5fec32d..ff59aec 100644
--- a/jdk/src/share/classes/java/time/chrono/Ser.java
+++ b/jdk/src/share/classes/java/time/chrono/Ser.java
@@ -68,7 +68,7 @@
 /**
  * The shared serialization delegate for this package.
  *
- * <h3>Implementation notes</h3>
+ * @implNote
  * This class wraps the object being serialized, and takes a byte representing the type of the class to
  * be serialized.  This byte can also be used for versioning the serialization format.  In this case another
  * byte flag would be used in order to specify an alternative version of the type format.
diff --git a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistChronology.java b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistChronology.java
index aee7435..27c98a6 100644
--- a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistChronology.java
+++ b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistChronology.java
@@ -96,7 +96,7 @@
  *  are never out of step.
  * </ul><p>
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java
index b879a14..973c7b8 100644
--- a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java
+++ b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java
@@ -89,7 +89,7 @@
  * This calendar system is primarily used in Thailand.
  * Dates are aligned such that {@code 2484-01-01 (Buddhist)} is {@code 1941-01-01 (ISO)}.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistEra.java b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistEra.java
index d1fb55f..d91eb81 100644
--- a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistEra.java
+++ b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistEra.java
@@ -102,7 +102,7 @@
  * <b>Do not use {@code ordinal()} to obtain the numeric representation of {@code ThaiBuddhistEra}.
  * Use {@code getValue()} instead.</b>
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This is an immutable and thread-safe enum.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/format/DateTimeFormatter.java b/jdk/src/share/classes/java/time/format/DateTimeFormatter.java
index 5c6bb23..158c741 100644
--- a/jdk/src/share/classes/java/time/format/DateTimeFormatter.java
+++ b/jdk/src/share/classes/java/time/format/DateTimeFormatter.java
@@ -77,6 +77,7 @@
 import java.text.ParseException;
 import java.text.ParsePosition;
 import java.time.DateTimeException;
+import java.time.Period;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.chrono.Chronology;
@@ -121,7 +122,7 @@
  * </pre></blockquote>
  * <p>
  * In addition to the format, formatters can be created with desired Locale,
- * Chronology, ZoneId, and formatting symbols.
+ * Chronology, ZoneId, and DecimalStyle.
  * <p>
  * The {@link #withLocale withLocale} method returns a new formatter that
  * overrides the locale. The locale affects some aspects of formatting and
@@ -138,8 +139,8 @@
  * with the requested ZoneId before formatting. During parsing the ZoneId is
  * applied before the value is returned.
  * <p>
- * The {@link #withSymbols withSymbols} method returns a new formatter that
- * overrides the {@link DateTimeFormatSymbols}. The symbols are used for
+ * The {@link #withDecimalStyle withDecimalStyle} method returns a new formatter that
+ * overrides the {@link DecimalStyle}. The DecimalStyle symbols are used for
  * formatting and parsing.
  * <p>
  * Some applications may need to use the older {@link Format java.text.Format}
@@ -417,7 +418,65 @@
  * that you want to output directly to ensure that future changes do not break
  * your application.
  *
- * <h3>Specification for implementors</h3>
+ * <h3 id="resolving">Resolving</h3>
+ * Parsing is implemented as a two-phase operation.
+ * First, the text is parsed using the layout defined by the formatter, producing
+ * a {@code Map} of field to value, a {@code ZoneId} and a {@code Chronology}.
+ * Second, the parsed data is <em>resolved</em>, by validating, combining and
+ * simplifying the various fields into more useful ones.
+ * <p>
+ * Five parsing methods are supplied by this class.
+ * Four of these perform both the parse and resolve phases.
+ * The fifth method, {@link #parseUnresolved(CharSequence, ParsePosition)},
+ * only performs the first phase, leaving the result unresolved.
+ * As such, it is essentially a low-level operation.
+ * <p>
+ * The resolve phase is controlled by two parameters, set on this class.
+ * <p>
+ * The {@link ResolverStyle} is an enum that offers three different approaches,
+ * strict, smart and lenient. The smart option is the default.
+ * It can be set using {@link #withResolverStyle(ResolverStyle)}.
+ * <p>
+ * The {@link #withResolverFields(TemporalField...)} parameter allows the
+ * set of fields that will be resolved to be filtered before resolving starts.
+ * For example, if the formatter has parsed a year, month, day-of-month
+ * and day-of-year, then there are two approaches to resolve a date:
+ * (year + month + day-of-month) and (year + day-of-year).
+ * The resolver fields allows one of the two approaches to be selected.
+ * If no resolver fields are set then both approaches must result in the same date.
+ * <p>
+ * Resolving separate fields to form a complete date and time is a complex
+ * process with behaviour distributed across a number of classes.
+ * It follows these steps:
+ * <ol>
+ * <li>The chronology is determined.
+ * The chronology of the result is either the chronology that was parsed,
+ * or if no chronology was parsed, it is the chronology set on this class,
+ * or if that is null, it is {@code IsoChronology}.
+ * <li>The {@code ChronoField} date fields are resolved.
+ * This is achieved using {@link Chronology#resolveDate(Map, ResolverStyle)}.
+ * Documentation about field resolution is located in the implementation
+ * of {@code Chronology}.
+ * <li>The {@code ChronoField} time fields are resolved.
+ * This is documented on {@link ChronoField} and is the same for all chronologies.
+ * <li>Any fields that are not {@code ChronoField} are processed.
+ * This is achieved using {@link TemporalField#resolve(TemporalAccessor, long, ResolverStyle)}.
+ * Documentation about field resolution is located in the implementation
+ * of {@code TemporalField}.
+ * <li>The {@code ChronoField} date and time fields are re-resolved.
+ * This allows fields in step four to produce {@code ChronoField} values
+ * and have them be processed into dates and times.
+ * <li>A {@code LocalTime} is formed if there is at least an hour-of-day available.
+ * This involves providing default values for minute, second and fraction of second.
+ * <li>Any remaining unresolved fields are cross-checked against any
+ * date and/or time that was resolved. Thus, an earlier stage would resolve
+ * (year + month + day-of-month) to a date, and this stage would check that
+ * day-of-week was valid for the date.
+ * <li>If an {@linkplain #parsedExcessDays() excess number of days}
+ * was parsed then it is added to the date if a date is available.
+ * </ol>
+ *
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
@@ -435,7 +494,7 @@
     /**
      * The symbols to use for formatting, not null.
      */
-    private final DateTimeFormatSymbols symbols;
+    private final DecimalStyle decimalStyle;
     /**
      * The resolver style to use, not null.
      */
@@ -1040,6 +1099,11 @@
      * <p>
      * This returns an immutable formatter capable of formatting and parsing
      * the ISO-8601 instant format.
+     * When formatting, the second-of-minute is always output.
+     * The nano-of-second outputs zero, three, six or nine digits digits as necessary.
+     * When parsing, time to at least the seconds field is required.
+     * Fractional seconds from zero to nine are parsed.
+     * The localized decimal style is not used.
      * <p>
      * This is a special case formatter intended to allow a human readable form
      * of an {@link java.time.Instant}. The {@code Instant} class is designed to
@@ -1201,25 +1265,117 @@
                 .toFormatter(ResolverStyle.SMART, IsoChronology.INSTANCE);
     }
 
+    //-----------------------------------------------------------------------
+    /**
+     * A query that provides access to the excess days that were parsed.
+     * <p>
+     * This returns a singleton {@linkplain TemporalQuery query} that provides
+     * access to additional information from the parse. The query always returns
+     * a non-null period, with a zero period returned instead of null.
+     * <p>
+     * There are two situations where this query may return a non-zero period.
+     * <p><ul>
+     * <li>If the {@code ResolverStyle} is {@code LENIENT} and a time is parsed
+     *  without a date, then the complete result of the parse consists of a
+     *  {@code LocalTime} and an excess {@code Period} in days.
+     * <p>
+     * <li>If the {@code ResolverStyle} is {@code SMART} and a time is parsed
+     *  without a date where the time is 24:00:00, then the complete result of
+     *  the parse consists of a {@code LocalTime} of 00:00:00 and an excess
+     *  {@code Period} of one day.
+     * </ul>
+     * <p>
+     * In both cases, if a complete {@code ChronoLocalDateTime} or {@code Instant}
+     * is parsed, then the excess days are added to the date part.
+     * As a result, this query will return a zero period.
+     * <p>
+     * The {@code SMART} behaviour handles the common "end of day" 24:00 value.
+     * Processing in {@code LENIENT} mode also produces the same result:
+     * <pre>
+     *  Text to parse        Parsed object                         Excess days
+     *  "2012-12-03T00:00"   LocalDateTime.of(2012, 12, 3, 0, 0)   ZERO
+     *  "2012-12-03T24:00"   LocalDateTime.of(2012, 12, 4, 0, 0)   ZERO
+     *  "00:00"              LocalTime.of(0, 0)                    ZERO
+     *  "24:00"              LocalTime.of(0, 0)                    Period.ofDays(1)
+     * </pre>
+     * The query can be used as follows:
+     * <pre>
+     *  TemporalAccessor parsed = formatter.parse(str);
+     *  LocalTime time = parsed.query(LocalTime::from);
+     *  Period extraDays = parsed.query(DateTimeFormatter.parsedExcessDays());
+     * </pre>
+     */
+    public static final TemporalQuery<Period> parsedExcessDays() {
+        return PARSED_EXCESS_DAYS;
+    }
+    private static final TemporalQuery<Period> PARSED_EXCESS_DAYS = t -> {
+        if (t instanceof Parsed) {
+            return ((Parsed) t).excessDays;
+        } else {
+            return Period.ZERO;
+        }
+    };
+
+    /**
+     * A query that provides access to whether a leap-second was parsed.
+     * <p>
+     * This returns a singleton {@linkplain TemporalQuery query} that provides
+     * access to additional information from the parse. The query always returns
+     * a non-null boolean, true if parsing saw a leap-second, false if not.
+     * <p>
+     * Instant parsing handles the special "leap second" time of '23:59:60'.
+     * Leap seconds occur at '23:59:60' in the UTC time-zone, but at other
+     * local times in different time-zones. To avoid this potential ambiguity,
+     * the handling of leap-seconds is limited to
+     * {@link DateTimeFormatterBuilder#appendInstant()}, as that method
+     * always parses the instant with the UTC zone offset.
+     * <p>
+     * If the time '23:59:60' is received, then a simple conversion is applied,
+     * replacing the second-of-minute of 60 with 59. This query can be used
+     * on the parse result to determine if the leap-second adjustment was made.
+     * The query will return one second of excess if it did adjust to remove
+     * the leap-second, and zero if not. Note that applying a leap-second
+     * smoothing mechanism, such as UTC-SLS, is the responsibility of the
+     * application, as follows:
+     * <pre>
+     *  TemporalAccessor parsed = formatter.parse(str);
+     *  Instant instant = parsed.query(Instant::from);
+     *  if (parsed.query(DateTimeFormatter.parsedLeapSecond())) {
+     *    // validate leap-second is correct and apply correct smoothing
+     *  }
+     * </pre>
+     */
+    public static final TemporalQuery<Boolean> parsedLeapSecond() {
+        return PARSED_LEAP_SECOND;
+    }
+    private static final TemporalQuery<Boolean> PARSED_LEAP_SECOND = t -> {
+        if (t instanceof Parsed) {
+            return ((Parsed) t).leapSecond;
+        } else {
+            return Boolean.FALSE;
+        }
+    };
+
+    //-----------------------------------------------------------------------
     /**
      * Constructor.
      *
      * @param printerParser  the printer/parser to use, not null
      * @param locale  the locale to use, not null
-     * @param symbols  the symbols to use, not null
+     * @param decimalStyle  the DecimalStyle to use, not null
      * @param resolverStyle  the resolver style to use, not null
      * @param resolverFields  the fields to use during resolving, null for all fields
      * @param chrono  the chronology to use, null for no override
      * @param zone  the zone to use, null for no override
      */
     DateTimeFormatter(CompositePrinterParser printerParser,
-            Locale locale, DateTimeFormatSymbols symbols,
+            Locale locale, DecimalStyle decimalStyle,
             ResolverStyle resolverStyle, Set<TemporalField> resolverFields,
             Chronology chrono, ZoneId zone) {
         this.printerParser = Objects.requireNonNull(printerParser, "printerParser");
         this.resolverFields = resolverFields;
         this.locale = Objects.requireNonNull(locale, "locale");
-        this.symbols = Objects.requireNonNull(symbols, "symbols");
+        this.decimalStyle = Objects.requireNonNull(decimalStyle, "decimalStyle");
         this.resolverStyle = Objects.requireNonNull(resolverStyle, "resolverStyle");
         this.chrono = chrono;
         this.zone = zone;
@@ -1253,32 +1409,32 @@
         if (this.locale.equals(locale)) {
             return this;
         }
-        return new DateTimeFormatter(printerParser, locale, symbols, resolverStyle, resolverFields, chrono, zone);
+        return new DateTimeFormatter(printerParser, locale, decimalStyle, resolverStyle, resolverFields, chrono, zone);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Gets the set of symbols to be used during formatting.
+     * Gets the DecimalStyle to be used during formatting.
      *
      * @return the locale of this formatter, not null
      */
-    public DateTimeFormatSymbols getSymbols() {
-        return symbols;
+    public DecimalStyle getDecimalStyle() {
+        return decimalStyle;
     }
 
     /**
-     * Returns a copy of this formatter with a new set of symbols.
+     * Returns a copy of this formatter with a new DecimalStyle.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param symbols  the new symbols, not null
-     * @return a formatter based on this formatter with the requested symbols, not null
+     * @param decimalStyle  the new DecimalStyle, not null
+     * @return a formatter based on this formatter with the requested DecimalStyle, not null
      */
-    public DateTimeFormatter withSymbols(DateTimeFormatSymbols symbols) {
-        if (this.symbols.equals(symbols)) {
+    public DateTimeFormatter withDecimalStyle(DecimalStyle decimalStyle) {
+        if (this.decimalStyle.equals(decimalStyle)) {
             return this;
         }
-        return new DateTimeFormatter(printerParser, locale, symbols, resolverStyle, resolverFields, chrono, zone);
+        return new DateTimeFormatter(printerParser, locale, decimalStyle, resolverStyle, resolverFields, chrono, zone);
     }
 
     //-----------------------------------------------------------------------
@@ -1332,7 +1488,7 @@
         if (Objects.equals(this.chrono, chrono)) {
             return this;
         }
-        return new DateTimeFormatter(printerParser, locale, symbols, resolverStyle, resolverFields, chrono, zone);
+        return new DateTimeFormatter(printerParser, locale, decimalStyle, resolverStyle, resolverFields, chrono, zone);
     }
 
     //-----------------------------------------------------------------------
@@ -1389,7 +1545,7 @@
         if (Objects.equals(this.zone, zone)) {
             return this;
         }
-        return new DateTimeFormatter(printerParser, locale, symbols, resolverStyle, resolverFields, chrono, zone);
+        return new DateTimeFormatter(printerParser, locale, decimalStyle, resolverStyle, resolverFields, chrono, zone);
     }
 
     //-----------------------------------------------------------------------
@@ -1431,7 +1587,7 @@
         if (Objects.equals(this.resolverStyle, resolverStyle)) {
             return this;
         }
-        return new DateTimeFormatter(printerParser, locale, symbols, resolverStyle, resolverFields, chrono, zone);
+        return new DateTimeFormatter(printerParser, locale, decimalStyle, resolverStyle, resolverFields, chrono, zone);
     }
 
     //-----------------------------------------------------------------------
@@ -1495,7 +1651,7 @@
             return this;
         }
         fields = Collections.unmodifiableSet(fields);
-        return new DateTimeFormatter(printerParser, locale, symbols, resolverStyle, fields, chrono, zone);
+        return new DateTimeFormatter(printerParser, locale, decimalStyle, resolverStyle, fields, chrono, zone);
     }
 
     /**
@@ -1543,7 +1699,7 @@
             return this;
         }
         resolverFields = Collections.unmodifiableSet(new HashSet<>(resolverFields));
-        return new DateTimeFormatter(printerParser, locale, symbols, resolverStyle, resolverFields, chrono, zone);
+        return new DateTimeFormatter(printerParser, locale, decimalStyle, resolverStyle, resolverFields, chrono, zone);
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/src/share/classes/java/time/format/DateTimeFormatterBuilder.java b/jdk/src/share/classes/java/time/format/DateTimeFormatterBuilder.java
index d209f5c..cec0784 100644
--- a/jdk/src/share/classes/java/time/format/DateTimeFormatterBuilder.java
+++ b/jdk/src/share/classes/java/time/format/DateTimeFormatterBuilder.java
@@ -77,6 +77,7 @@
 import java.math.RoundingMode;
 import java.text.ParsePosition;
 import java.time.DateTimeException;
+import java.time.Duration;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
@@ -142,7 +143,7 @@
  * can be used, see {@link #appendPattern(String)}.
  * In practice, this simply parses the pattern and calls other methods on the builder.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is a mutable builder intended for use from a single thread.
  *
  * @since 1.8
@@ -187,6 +188,44 @@
     private int valueParserIndex = -1;
 
     /**
+     * Gets the formatting pattern for date and time styles for a locale and chronology.
+     * The locale and chronology are used to lookup the locale specific format
+     * for the requested dateStyle and/or timeStyle.
+     *
+     * @param dateStyle  the FormatStyle for the date
+     * @param timeStyle  the FormatStyle for the time
+     * @param chrono  the Chronology, non-null
+     * @param locale  the locale, non-null
+     * @return the locale and Chronology specific formatting pattern
+     * @throws IllegalArgumentException if both dateStyle and timeStyle are null
+     */
+    public static String getLocalizedDateTimePattern(FormatStyle dateStyle, FormatStyle timeStyle,
+            Chronology chrono, Locale locale) {
+        Objects.requireNonNull(locale, "locale");
+        Objects.requireNonNull(chrono, "chrono");
+        if (dateStyle == null && timeStyle == null) {
+            throw new IllegalArgumentException("Either dateStyle or timeStyle must be non-null");
+        }
+        LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased().getLocaleResources(locale);
+        String pattern = lr.getJavaTimeDateTimePattern(
+                convertStyle(timeStyle), convertStyle(dateStyle), chrono.getCalendarType());
+        return pattern;
+    }
+
+    /**
+     * Converts the given FormatStyle to the java.text.DateFormat style.
+     *
+     * @param style  the FormatStyle style
+     * @return the int style, or -1 if style is null, indicating un-required
+     */
+    private static int convertStyle(FormatStyle style) {
+        if (style == null) {
+            return -1;
+        }
+        return style.ordinal();  // indices happen to align
+    }
+
+    /**
      * Constructs a new instance of the builder.
      */
     public DateTimeFormatterBuilder() {
@@ -344,7 +383,7 @@
      */
     public DateTimeFormatterBuilder appendValue(TemporalField field) {
         Objects.requireNonNull(field, "field");
-        active.valueParserIndex = appendInternal(new NumberPrinterParser(field, 1, 19, SignStyle.NORMAL));
+        appendValue(new NumberPrinterParser(field, 1, 19, SignStyle.NORMAL));
         return this;
     }
 
@@ -360,15 +399,15 @@
      * If the value of the field is negative then an exception is thrown during formatting.
      * <p>
      * This method supports a special technique of parsing known as 'adjacent value parsing'.
-     * This technique solves the problem where a variable length value is followed by one or more
+     * This technique solves the problem where a value, variable or fixed width, is followed by one or more
      * fixed length values. The standard parser is greedy, and thus it would normally
      * steal the digits that are needed by the fixed width value parsers that follow the
      * variable width one.
      * <p>
      * No action is required to initiate 'adjacent value parsing'.
-     * When a call to {@code appendValue} with a variable width is made, the builder
+     * When a call to {@code appendValue} is made, the builder
      * enters adjacent value parsing setup mode. If the immediately subsequent method
-     * call or calls on the same builder are to this method, then the parser will reserve
+     * call or calls on the same builder are for a fixed width value, then the parser will reserve
      * space so that the fixed width values can be parsed.
      * <p>
      * For example, consider {@code builder.appendValue(YEAR).appendValue(MONTH_OF_YEAR, 2);}
@@ -381,7 +420,7 @@
      * nothing for the month.
      * <p>
      * Adjacent value parsing applies to each set of fixed width not-negative values in the parser
-     * that immediately follow any kind of variable width value.
+     * that immediately follow any kind of value, variable or fixed width.
      * Calling any other append method will end the setup of adjacent value parsing.
      * Thus, in the unlikely event that you need to avoid adjacent value parsing behavior,
      * simply add the {@code appendValue} to another {@code DateTimeFormatterBuilder}
@@ -402,7 +441,8 @@
             throw new IllegalArgumentException("The width must be from 1 to 19 inclusive but was " + width);
         }
         NumberPrinterParser pp = new NumberPrinterParser(field, width, width, SignStyle.NOT_NEGATIVE);
-        return appendFixedWidth(width, pp);
+        appendValue(pp);
+        return this;
     }
 
     /**
@@ -420,8 +460,10 @@
      * This behavior can be affected by 'adjacent value parsing'.
      * See {@link #appendValue(java.time.temporal.TemporalField, int)} for full details.
      * <p>
-     * In strict parsing mode, the minimum number of parsed digits is {@code minWidth}.
-     * In lenient parsing mode, the minimum number of parsed digits is one.
+     * In strict parsing mode, the minimum number of parsed digits is {@code minWidth}
+     * and the maximum is {@code maxWidth}.
+     * In lenient parsing mode, the minimum number of parsed digits is one
+     * and the maximum is 19 (except as limited by adjacent value parsing).
      * <p>
      * If this method is invoked with equal minimum and maximum widths and a sign style of
      * {@code NOT_NEGATIVE} then it delegates to {@code appendValue(TemporalField,int)}.
@@ -452,17 +494,13 @@
                     maxWidth + " < " + minWidth);
         }
         NumberPrinterParser pp = new NumberPrinterParser(field, minWidth, maxWidth, signStyle);
-        if (minWidth == maxWidth) {
-            appendInternal(pp);
-        } else {
-            active.valueParserIndex = appendInternal(pp);
-        }
+        appendValue(pp);
         return this;
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Appends the reduced value of a date-time field to the formatter.
+     * Appends the reduced value of a date-time field with fixed width to the formatter.
      * <p>
      * This is typically used for formatting and parsing a two digit year.
      * The {@code width} is the printed and parsed width.
@@ -471,51 +509,116 @@
      * For formatting, the width is used to determine the number of characters to format.
      * The rightmost characters are output to match the width, left padding with zero.
      * <p>
-     * For parsing, exactly the number of characters specified by the width are parsed.
-     * This is incomplete information however, so the base value is used to complete the parse.
-     * The base value is the first valid value in a range of ten to the power of width.
+     * For strict parsing, the number of characters allowed by the width are parsed.
+     * For lenient parsing, the number of characters must be at least 1 and less than 10.
+     * If the number of digits parsed is equal to {@code width} and the value is positive,
+     * the value of the field is computed to be the first number greater than
+     * or equal to the {@code baseValue} with the same least significant characters,
+     * otherwise the value parsed is the field value.
+     * This allows a reduced value to be entered for values in range of the baseValue
+     * and width and absolute values can be entered for values outside the range.
      * <p>
      * For example, a base value of {@code 1980} and a width of {@code 2} will have
      * valid values from {@code 1980} to {@code 2079}.
      * During parsing, the text {@code "12"} will result in the value {@code 2012} as that
-     * is the value within the range where the last two digits are "12".
-     * <p>
-     * This is a fixed width parser operating using 'adjacent value parsing'.
-     * See {@link #appendValue(java.time.temporal.TemporalField, int)} for full details.
+     * is the value within the range where the last two characters are "12".
+     * Compare with lenient parsing the text {@code "1915"} that will result in the
+     * value {@code 1915}.
      *
      * @param field  the field to append, not null
-     * @param width  the width of the printed and parsed field, from 1 to 18
+     * @param width  the field width of the printed and parsed field, from 1 to 10
+     * @param baseValue  the base value of the range of valid values
+     * @return this, for chaining, not null
+     * @throws IllegalArgumentException if the width or base value is invalid
+     * @see #appendValueReduced(java.time.temporal.TemporalField, int, int, int)
+     */
+    public DateTimeFormatterBuilder appendValueReduced(TemporalField field,
+            int width, int baseValue) {
+        return appendValueReduced(field, width, width, baseValue);
+    }
+
+    /**
+     * Appends the reduced value of a date-time field with a flexible width to the formatter.
+     * <p>
+     * This is typically used for formatting and parsing a two digit year
+     * but allowing for the year value to be up to maxWidth.
+     * <p>
+     * For formatting, the {@code width} and {@code maxWidth} are used to
+     * determine the number of characters to format.
+     * If the value of the field is within the range of the {@code baseValue} using
+     * {@code width} characters then the reduced value is formatted otherwise the value is
+     * truncated to fit {@code maxWidth}.
+     * The rightmost characters are output to match the width, left padding with zero.
+     * <p>
+     * For strict parsing, the number of characters allowed by {@code width} to {@code maxWidth} are parsed.
+     * For lenient parsing, the number of characters must be at least 1 and less than 10.
+     * If the number of digits parsed is equal to {@code width} and the value is positive,
+     * the value of the field is computed to be the first number greater than
+     * or equal to the {@code baseValue} with the same least significant characters,
+     * otherwise the value parsed is the field value.
+     * This allows a reduced value to be entered for values in range of the baseValue
+     * and width and absolute values can be entered for values outside the range.
+     * <p>
+     * For example, a base value of {@code 1980} and a width of {@code 2} will have
+     * valid values from {@code 1980} to {@code 2079}.
+     * During parsing, the text {@code "12"} will result in the value {@code 2012} as that
+     * is the value within the range where the last two characters are "12".
+     * Compare with parsing the text {@code "1915"} that will result in the
+     * value {@code 1915}.
+     *
+     * @param field  the field to append, not null
+     * @param width  the field width of the printed and parsed field, from 1 to 10
+     * @param maxWidth  the maximum field width of the printed field, from 1 to 10
      * @param baseValue  the base value of the range of valid values
      * @return this, for chaining, not null
      * @throws IllegalArgumentException if the width or base value is invalid
      */
-    public DateTimeFormatterBuilder appendValueReduced(
-            TemporalField field, int width, int baseValue) {
+    public DateTimeFormatterBuilder appendValueReduced(TemporalField field,
+            int width, int maxWidth, int baseValue) {
         Objects.requireNonNull(field, "field");
-        ReducedPrinterParser pp = new ReducedPrinterParser(field, width, baseValue);
-        appendFixedWidth(width, pp);
+        ReducedPrinterParser pp = new ReducedPrinterParser(field, width, maxWidth, baseValue);
+        appendValue(pp);
         return this;
     }
 
     /**
-     * Appends a fixed width printer-parser.
+     * Appends a fixed or variable width printer-parser handling adjacent value mode.
+     * If a PrinterParser is not active then the new PrinterParser becomes
+     * the active PrinterParser.
+     * Otherwise, the active PrinterParser is modified depending on the new PrinterParser.
+     * If the new PrinterParser is fixed width and has sign style {@code NOT_NEGATIVE}
+     * then its width is added to the active PP and
+     * the new PrinterParser is forced to be fixed width.
+     * If the new PrinterParser is variable width, the active PrinterParser is changed
+     * to be fixed width and the new PrinterParser becomes the active PP.
      *
-     * @param width  the width
      * @param pp  the printer-parser, not null
      * @return this, for chaining, not null
      */
-    private DateTimeFormatterBuilder appendFixedWidth(int width, NumberPrinterParser pp) {
+    private DateTimeFormatterBuilder appendValue(NumberPrinterParser pp) {
         if (active.valueParserIndex >= 0) {
+            final int activeValueParser = active.valueParserIndex;
+
             // adjacent parsing mode, update setting in previous parsers
-            NumberPrinterParser basePP = (NumberPrinterParser) active.printerParsers.get(active.valueParserIndex);
-            basePP = basePP.withSubsequentWidth(width);
-            int activeValueParser = active.valueParserIndex;
-            active.printerParsers.set(active.valueParserIndex, basePP);
-            appendInternal(pp.withFixedWidth());
-            active.valueParserIndex = activeValueParser;
+            NumberPrinterParser basePP = (NumberPrinterParser) active.printerParsers.get(activeValueParser);
+            if (pp.minWidth == pp.maxWidth && pp.signStyle == SignStyle.NOT_NEGATIVE) {
+                // Append the width to the subsequentWidth of the active parser
+                basePP = basePP.withSubsequentWidth(pp.maxWidth);
+                // Append the new parser as a fixed width
+                appendInternal(pp.withFixedWidth());
+                // Retain the previous active parser
+                active.valueParserIndex = activeValueParser;
+            } else {
+                // Modify the active parser to be fixed width
+                basePP = basePP.withFixedWidth();
+                // The new parser becomes the mew active parser
+                active.valueParserIndex = appendInternal(pp);
+            }
+            // Replace the modified parser with the updated one
+            active.printerParsers.set(activeValueParser, basePP);
         } else {
-            // not adjacent parsing
-            appendInternal(pp);
+            // The new Parser becomes the active parser
+            active.valueParserIndex = appendInternal(pp);
         }
         return this;
     }
@@ -657,11 +760,24 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Appends an instant using ISO-8601 to the formatter.
+     * Appends an instant using ISO-8601 to the formatter, formatting fractional
+     * digits in groups of three.
      * <p>
      * Instants have a fixed output format.
-     * They are converted to a date-time with a zone-offset of UTC and printed
+     * They are converted to a date-time with a zone-offset of UTC and formatted
      * using the standard ISO-8601 format.
+     * With this method, formatting nano-of-second outputs zero, three, six
+     * or nine digits digits as necessary.
+     * The localized decimal style is not used.
+     * <p>
+     * The instant is obtained using {@link ChronoField#INSTANT_SECONDS INSTANT_SECONDS}
+     * and optionally (@code NANO_OF_SECOND). The value of {@code INSTANT_SECONDS}
+     * may be outside the maximum range of {@code LocalDateTime}.
+     * <p>
+     * The {@linkplain ResolverStyle resolver style} has no effect on instant parsing.
+     * The end-of-day time of '24:00' is handled as midnight at the start of the following day.
+     * The leap-second time of '23:59:59' is handled to some degree, see
+     * {@link DateTimeFormatter#parsedLeapSecond()} for full details.
      * <p>
      * An alternative to this method is to format/parse the instant as a single
      * epoch-seconds value. That is achieved using {@code appendValue(INSTANT_SECONDS)}.
@@ -669,11 +785,55 @@
      * @return this, for chaining, not null
      */
     public DateTimeFormatterBuilder appendInstant() {
-        appendInternal(new InstantPrinterParser());
+        appendInternal(new InstantPrinterParser(-2));
         return this;
     }
 
     /**
+     * Appends an instant using ISO-8601 to the formatter with control over
+     * the number of fractional digits.
+     * <p>
+     * Instants have a fixed output format, although this method provides some
+     * control over the fractional digits. They are converted to a date-time
+     * with a zone-offset of UTC and printed using the standard ISO-8601 format.
+     * The localized decimal style is not used.
+     * <p>
+     * The {@code fractionalDigits} parameter allows the output of the fractional
+     * second to be controlled. Specifying zero will cause no fractional digits
+     * to be output. From 1 to 9 will output an increasing number of digits, using
+     * zero right-padding if necessary. The special value -1 is used to output as
+     * many digits as necessary to avoid any trailing zeroes.
+     * <p>
+     * When parsing in strict mode, the number of parsed digits must match the
+     * fractional digits. When parsing in lenient mode, any number of fractional
+     * digits from zero to nine are accepted.
+     * <p>
+     * The instant is obtained using {@link ChronoField#INSTANT_SECONDS INSTANT_SECONDS}
+     * and optionally (@code NANO_OF_SECOND). The value of {@code INSTANT_SECONDS}
+     * may be outside the maximum range of {@code LocalDateTime}.
+     * <p>
+     * The {@linkplain ResolverStyle resolver style} has no effect on instant parsing.
+     * The end-of-day time of '24:00' is handled as midnight at the start of the following day.
+     * The leap-second time of '23:59:59' is handled to some degree, see
+     * {@link DateTimeFormatter#parsedLeapSecond()} for full details.
+     * <p>
+     * An alternative to this method is to format/parse the instant as a single
+     * epoch-seconds value. That is achieved using {@code appendValue(INSTANT_SECONDS)}.
+     *
+     * @param fractionalDigits  the number of fractional second digits to format with,
+     *  from 0 to 9, or -1 to use as many digits as necessary
+     * @return this, for chaining, not null
+     */
+    public DateTimeFormatterBuilder appendInstant(int fractionalDigits) {
+        if (fractionalDigits < -1 || fractionalDigits > 9) {
+            throw new IllegalArgumentException("The fractional digits must be from -1 to 9 inclusive but was " + fractionalDigits);
+        }
+        appendInternal(new InstantPrinterParser(fractionalDigits));
+        return this;
+    }
+
+    //-----------------------------------------------------------------------
+    /**
      * Appends the zone offset, such as '+01:00', to the formatter.
      * <p>
      * This appends an instruction to format/parse the offset ID to the builder.
@@ -1049,7 +1209,7 @@
      * <p>
      * The calendar system name will be output during a format.
      * If the chronology cannot be obtained then an exception will be thrown.
-     * The calendar system name is obtained from the formatting symbols.
+     * The calendar system name is obtained from the Chronology.
      *
      * @param textStyle  the text style to use, not null
      * @return this, for chaining, not null
@@ -1838,7 +1998,7 @@
      * using the default locale.
      * <p>
      * This will create a formatter with the {@linkplain Locale#getDefault(Locale.Category) default FORMAT locale}.
-     * Numbers will be printed and parsed using the standard non-localized set of symbols.
+     * Numbers will be printed and parsed using the standard DecimalStyle.
      * The resolver style will be {@link ResolverStyle#SMART SMART}.
      * <p>
      * Calling this method will end any open optional sections by repeatedly
@@ -1858,7 +2018,7 @@
      * using the specified locale.
      * <p>
      * This will create a formatter with the specified locale.
-     * Numbers will be printed and parsed using the standard non-localized set of symbols.
+     * Numbers will be printed and parsed using the standard DecimalStyle.
      * The resolver style will be {@link ResolverStyle#SMART SMART}.
      * <p>
      * Calling this method will end any open optional sections by repeatedly
@@ -1898,7 +2058,7 @@
             optionalEnd();
         }
         CompositePrinterParser pp = new CompositePrinterParser(printerParsers, false);
-        return new DateTimeFormatter(pp, locale, DateTimeFormatSymbols.STANDARD,
+        return new DateTimeFormatter(pp, locale, DecimalStyle.STANDARD,
                 resolverStyle, null, chrono, null);
     }
 
@@ -1921,7 +2081,7 @@
      * for the next parser. If an error occurs, the returned index will be negative
      * and will have the error position encoded using the complement operator.
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * This interface must be implemented with care to ensure other classes operate correctly.
      * All implementations that can be instantiated must be final, immutable and thread-safe.
      * <p>
@@ -2282,24 +2442,25 @@
         /**
          * Array of 10 to the power of n.
          */
-        static final int[] EXCEED_POINTS = new int[] {
-            0,
-            10,
-            100,
-            1000,
-            10000,
-            100000,
-            1000000,
-            10000000,
-            100000000,
-            1000000000,
+        static final long[] EXCEED_POINTS = new long[] {
+            0L,
+            10L,
+            100L,
+            1000L,
+            10000L,
+            100000L,
+            1000000L,
+            10000000L,
+            100000000L,
+            1000000000L,
+            10000000000L,
         };
 
         final TemporalField field;
         final int minWidth;
-        private final int maxWidth;
+        final int maxWidth;
         private final SignStyle signStyle;
-        private final int subsequentWidth;
+        final int subsequentWidth;
 
         /**
          * Constructor.
@@ -2328,7 +2489,7 @@
          * @param subsequentWidth  the width of subsequent non-negative numbers, 0 or greater,
          *  -1 if fixed width due to active adjacent parsing
          */
-        private NumberPrinterParser(TemporalField field, int minWidth, int maxWidth, SignStyle signStyle, int subsequentWidth) {
+        protected NumberPrinterParser(TemporalField field, int minWidth, int maxWidth, SignStyle signStyle, int subsequentWidth) {
             // validated by caller
             this.field = field;
             this.minWidth = minWidth;
@@ -2343,6 +2504,9 @@
          * @return a new updated printer-parser, not null
          */
         NumberPrinterParser withFixedWidth() {
+            if (subsequentWidth == -1) {
+                return this;
+            }
             return new NumberPrinterParser(field, minWidth, maxWidth, signStyle, -1);
         }
 
@@ -2363,24 +2527,24 @@
                 return false;
             }
             long value = getValue(valueLong);
-            DateTimeFormatSymbols symbols = context.getSymbols();
+            DecimalStyle decimalStyle = context.getDecimalStyle();
             String str = (value == Long.MIN_VALUE ? "9223372036854775808" : Long.toString(Math.abs(value)));
             if (str.length() > maxWidth) {
                 throw new DateTimeException("Field " + field.getName() +
                     " cannot be printed as the value " + value +
                     " exceeds the maximum print width of " + maxWidth);
             }
-            str = symbols.convertNumberToI18N(str);
+            str = decimalStyle.convertNumberToI18N(str);
 
             if (value >= 0) {
                 switch (signStyle) {
                     case EXCEEDS_PAD:
                         if (minWidth < 19 && value >= EXCEED_POINTS[minWidth]) {
-                            buf.append(symbols.getPositiveSign());
+                            buf.append(decimalStyle.getPositiveSign());
                         }
                         break;
                     case ALWAYS:
-                        buf.append(symbols.getPositiveSign());
+                        buf.append(decimalStyle.getPositiveSign());
                         break;
                 }
             } else {
@@ -2388,7 +2552,7 @@
                     case NORMAL:
                     case EXCEEDS_PAD:
                     case ALWAYS:
-                        buf.append(symbols.getNegativeSign());
+                        buf.append(decimalStyle.getNegativeSign());
                         break;
                     case NOT_NEGATIVE:
                         throw new DateTimeException("Field " + field.getName() +
@@ -2397,7 +2561,7 @@
                 }
             }
             for (int i = 0; i < minWidth - str.length(); i++) {
-                buf.append(symbols.getZeroDigit());
+                buf.append(decimalStyle.getZeroDigit());
             }
             buf.append(str);
             return true;
@@ -2426,13 +2590,13 @@
             char sign = text.charAt(position);  // IOOBE if invalid position
             boolean negative = false;
             boolean positive = false;
-            if (sign == context.getSymbols().getPositiveSign()) {
+            if (sign == context.getDecimalStyle().getPositiveSign()) {
                 if (signStyle.parse(true, context.isStrict(), minWidth == maxWidth) == false) {
                     return ~position;
                 }
                 positive = true;
                 position++;
-            } else if (sign == context.getSymbols().getNegativeSign()) {
+            } else if (sign == context.getDecimalStyle().getNegativeSign()) {
                 if (signStyle.parse(false, context.isStrict(), minWidth == maxWidth) == false) {
                     return ~position;
                 }
@@ -2448,7 +2612,7 @@
             if (minEndPos > length) {
                 return ~position;
             }
-            int effMaxWidth = maxWidth + Math.max(subsequentWidth, 0);
+            int effMaxWidth = (context.isStrict() || isFixedWidth() ? maxWidth : 9) + Math.max(subsequentWidth, 0);
             long total = 0;
             BigInteger totalBig = null;
             int pos = position;
@@ -2456,7 +2620,7 @@
                 int maxEndPos = Math.min(pos + effMaxWidth, length);
                 while (pos < maxEndPos) {
                     char ch = text.charAt(pos++);
-                    int digit = context.getSymbols().convertToDigit(ch);
+                    int digit = context.getDecimalStyle().convertToDigit(ch);
                     if (digit < 0) {
                         pos--;
                         if (pos < minEndPos) {
@@ -2550,62 +2714,110 @@
      */
     static final class ReducedPrinterParser extends NumberPrinterParser {
         private final int baseValue;
-        private final int range;
 
         /**
          * Constructor.
          *
          * @param field  the field to format, validated not null
-         * @param width  the field width, from 1 to 18
+         * @param minWidth  the minimum field width, from 1 to 10
+         * @param maxWidth  the maximum field width, from 1 to 10
          * @param baseValue  the base value
          */
-        ReducedPrinterParser(TemporalField field, int width, int baseValue) {
-            super(field, width, width, SignStyle.NOT_NEGATIVE);
-            if (width < 1 || width > 18) {
-                throw new IllegalArgumentException("The width must be from 1 to 18 inclusive but was " + width);
+        ReducedPrinterParser(TemporalField field, int minWidth, int maxWidth,
+                int baseValue) {
+            this(field, minWidth, maxWidth, baseValue, 0);
+            if (minWidth < 1 || minWidth > 10) {
+                throw new IllegalArgumentException("The minWidth must be from 1 to 10 inclusive but was " + minWidth);
+            }
+            if (maxWidth < 1 || maxWidth > 10) {
+                throw new IllegalArgumentException("The maxWidth must be from 1 to 10 inclusive but was " + minWidth);
+            }
+            if (maxWidth < minWidth) {
+                throw new IllegalArgumentException("Maximum width must exceed or equal the minimum width but " +
+                        maxWidth + " < " + minWidth);
             }
             if (field.range().isValidValue(baseValue) == false) {
                 throw new IllegalArgumentException("The base value must be within the range of the field");
             }
-            this.baseValue = baseValue;
-            this.range = EXCEED_POINTS[width];
-            if ((((long) baseValue) + range) > Integer.MAX_VALUE) {
+            if ((((long) baseValue) + EXCEED_POINTS[maxWidth]) > Integer.MAX_VALUE) {
                 throw new DateTimeException("Unable to add printer-parser as the range exceeds the capacity of an int");
             }
         }
 
+        /**
+         * Constructor.
+         * The arguments have already been checked.
+         *
+         * @param field  the field to format, validated not null
+         * @param minWidth  the minimum field width, from 1 to 10
+         * @param maxWidth  the maximum field width, from 1 to 10
+         * @param baseValue  the base value
+         * @param subsequentWidth the subsequentWidth for this instance
+         */
+        private ReducedPrinterParser(TemporalField field, int minWidth, int maxWidth,
+                int baseValue, int subsequentWidth) {
+            super(field, minWidth, maxWidth, SignStyle.NOT_NEGATIVE, subsequentWidth);
+            this.baseValue = baseValue;
+        }
+
         @Override
         long getValue(long value) {
-            return Math.abs(value % range);
+            long absValue = Math.abs(value);
+            if (value >= baseValue && value < baseValue + EXCEED_POINTS[minWidth]) {
+                // Use the reduced value if it fits in minWidth
+                return absValue % EXCEED_POINTS[minWidth];
+            }
+            // Otherwise truncate to fit in maxWidth
+            return absValue % EXCEED_POINTS[maxWidth];
         }
 
         @Override
         int setValue(DateTimeParseContext context, long value, int errorPos, int successPos) {
-            int lastPart = baseValue % range;
-            if (baseValue > 0) {
-                value = baseValue - lastPart + value;
-            } else {
-                value = baseValue - lastPart - value;
-            }
-            if (value < baseValue) {
-                value += range;
+            int parseLen = successPos - errorPos;
+            if (parseLen == minWidth && value >= 0) {
+                long range = EXCEED_POINTS[minWidth];
+                long lastPart = baseValue % range;
+                long basePart = baseValue - lastPart;
+                if (baseValue > 0) {
+                    value = basePart + value;
+                } else {
+                    value = basePart - value;
+                }
+                if (basePart != 0 && value < baseValue) {
+                    value += range;
+                }
             }
             return context.setParsedField(field, value, errorPos, successPos);
         }
 
+        /**
+         * Returns a new instance with fixed width flag set.
+         *
+         * @return a new updated printer-parser, not null
+         */
         @Override
-        NumberPrinterParser withFixedWidth() {
-            return this;
+        ReducedPrinterParser withFixedWidth() {
+            if (subsequentWidth == -1) {
+                return this;
+            }
+            return new ReducedPrinterParser(field, minWidth, maxWidth, baseValue, -1);
         }
 
+        /**
+         * Returns a new instance with an updated subsequent width.
+         *
+         * @param subsequentWidth  the width of subsequent non-negative numbers, 0 or greater
+         * @return a new updated printer-parser, not null
+         */
         @Override
-        boolean isFixedWidth() {
-            return true;
+        ReducedPrinterParser withSubsequentWidth(int subsequentWidth) {
+            return new ReducedPrinterParser(field, minWidth, maxWidth, baseValue,
+                    this.subsequentWidth + subsequentWidth);
         }
 
         @Override
         public String toString() {
-            return "ReducedValue(" + field.getName() + "," + minWidth + "," + baseValue + ")";
+            return "ReducedValue(" + field.getName() + "," + minWidth + "," + maxWidth + "," + baseValue + ")";
         }
     }
 
@@ -2654,24 +2866,24 @@
             if (value == null) {
                 return false;
             }
-            DateTimeFormatSymbols symbols = context.getSymbols();
+            DecimalStyle decimalStyle = context.getDecimalStyle();
             BigDecimal fraction = convertToFraction(value);
             if (fraction.scale() == 0) {  // scale is zero if value is zero
                 if (minWidth > 0) {
                     if (decimalPoint) {
-                        buf.append(symbols.getDecimalSeparator());
+                        buf.append(decimalStyle.getDecimalSeparator());
                     }
                     for (int i = 0; i < minWidth; i++) {
-                        buf.append(symbols.getZeroDigit());
+                        buf.append(decimalStyle.getZeroDigit());
                     }
                 }
             } else {
                 int outputScale = Math.min(Math.max(fraction.scale(), minWidth), maxWidth);
                 fraction = fraction.setScale(outputScale, RoundingMode.FLOOR);
                 String str = fraction.toPlainString().substring(2);
-                str = symbols.convertNumberToI18N(str);
+                str = decimalStyle.convertNumberToI18N(str);
                 if (decimalPoint) {
-                    buf.append(symbols.getDecimalSeparator());
+                    buf.append(decimalStyle.getDecimalSeparator());
                 }
                 buf.append(str);
             }
@@ -2688,7 +2900,7 @@
                 return (effectiveMin > 0 ? ~position : position);
             }
             if (decimalPoint) {
-                if (text.charAt(position) != context.getSymbols().getDecimalSeparator()) {
+                if (text.charAt(position) != context.getDecimalStyle().getDecimalSeparator()) {
                     // valid if whole field is optional, invalid if minimum width
                     return (effectiveMin > 0 ? ~position : position);
                 }
@@ -2703,7 +2915,7 @@
             int pos = position;
             while (pos < maxEndPos) {
                 char ch = text.charAt(pos++);
-                int digit = context.getSymbols().convertToDigit(ch);
+                int digit = context.getDecimalStyle().convertToDigit(ch);
                 if (digit < 0) {
                     if (pos < minEndPos) {
                         return ~position;  // need at least min width digits
@@ -2883,43 +3095,50 @@
         // seconds per day = 86400
         private static final long SECONDS_PER_10000_YEARS = 146097L * 25L * 86400L;
         private static final long SECONDS_0000_TO_1970 = ((146097L * 5L) - (30L * 365L + 7L)) * 86400L;
-        private static final CompositePrinterParser PARSER = new DateTimeFormatterBuilder()
-                    .parseCaseInsensitive()
-                    .append(DateTimeFormatter.ISO_LOCAL_DATE).appendLiteral('T')
-                    .append(DateTimeFormatter.ISO_LOCAL_TIME).appendLiteral('Z')
-                    .toFormatter().toPrinterParser(false);
+        private final int fractionalDigits;
 
-        InstantPrinterParser() {
+        InstantPrinterParser(int fractionalDigits) {
+            this.fractionalDigits = fractionalDigits;
         }
 
         @Override
         public boolean format(DateTimePrintContext context, StringBuilder buf) {
             // use INSTANT_SECONDS, thus this code is not bound by Instant.MAX
             Long inSecs = context.getValue(INSTANT_SECONDS);
-            Long inNanos = context.getValue(NANO_OF_SECOND);
-            if (inSecs == null || inNanos == null) {
+            Long inNanos = null;
+            if (context.getTemporal().isSupported(NANO_OF_SECOND)) {
+                inNanos = context.getTemporal().getLong(NANO_OF_SECOND);
+            }
+            if (inSecs == null) {
                 return false;
             }
             long inSec = inSecs;
-            int inNano = NANO_OF_SECOND.checkValidIntValue(inNanos);
+            int inNano = NANO_OF_SECOND.checkValidIntValue(inNanos != null ? inNanos : 0);
+            // format mostly using LocalDateTime.toString
             if (inSec >= -SECONDS_0000_TO_1970) {
                 // current era
                 long zeroSecs = inSec - SECONDS_PER_10000_YEARS + SECONDS_0000_TO_1970;
                 long hi = Math.floorDiv(zeroSecs, SECONDS_PER_10000_YEARS) + 1;
                 long lo = Math.floorMod(zeroSecs, SECONDS_PER_10000_YEARS);
-                LocalDateTime ldt = LocalDateTime.ofEpochSecond(lo - SECONDS_0000_TO_1970, inNano, ZoneOffset.UTC);
+                LocalDateTime ldt = LocalDateTime.ofEpochSecond(lo - SECONDS_0000_TO_1970, 0, ZoneOffset.UTC);
                 if (hi > 0) {
                     buf.append('+').append(hi);
                 }
-                buf.append(ldt).append('Z');
+                buf.append(ldt);
+                if (ldt.getSecond() == 0) {
+                    buf.append(":00");
+                }
             } else {
                 // before current era
                 long zeroSecs = inSec + SECONDS_0000_TO_1970;
                 long hi = zeroSecs / SECONDS_PER_10000_YEARS;
                 long lo = zeroSecs % SECONDS_PER_10000_YEARS;
-                LocalDateTime ldt = LocalDateTime.ofEpochSecond(lo - SECONDS_0000_TO_1970, inNano, ZoneOffset.UTC);
+                LocalDateTime ldt = LocalDateTime.ofEpochSecond(lo - SECONDS_0000_TO_1970, 0, ZoneOffset.UTC);
                 int pos = buf.length();
-                buf.append(ldt).append('Z');
+                buf.append(ldt);
+                if (ldt.getSecond() == 0) {
+                    buf.append(":00");
+                }
                 if (hi < 0) {
                     if (ldt.getYear() == -10_000) {
                         buf.replace(pos, pos + 2, Long.toString(hi - 1));
@@ -2930,14 +3149,38 @@
                     }
                 }
             }
+            // add fraction
+            if ((fractionalDigits < 0 && inNano > 0) || fractionalDigits > 0) {
+                buf.append('.');
+                int div = 100_000_000;
+                for (int i = 0; ((fractionalDigits == -1 && inNano > 0) ||
+                                    (fractionalDigits == -2 && (inNano > 0 || (i % 3) != 0)) ||
+                                    i < fractionalDigits); i++) {
+                    int digit = inNano / div;
+                    buf.append((char) (digit + '0'));
+                    inNano = inNano - (digit * div);
+                    div = div / 10;
+                }
+            }
+            buf.append('Z');
             return true;
         }
 
         @Override
         public int parse(DateTimeParseContext context, CharSequence text, int position) {
             // new context to avoid overwriting fields like year/month/day
+            int minDigits = (fractionalDigits < 0 ? 0 : fractionalDigits);
+            int maxDigits = (fractionalDigits < 0 ? 9 : fractionalDigits);
+            CompositePrinterParser parser = new DateTimeFormatterBuilder()
+                    .append(DateTimeFormatter.ISO_LOCAL_DATE).appendLiteral('T')
+                    .appendValue(HOUR_OF_DAY, 2).appendLiteral(':')
+                    .appendValue(MINUTE_OF_HOUR, 2).appendLiteral(':')
+                    .appendValue(SECOND_OF_MINUTE, 2)
+                    .appendFraction(NANO_OF_SECOND, minDigits, maxDigits, true)
+                    .appendLiteral('Z')
+                    .toFormatter().toPrinterParser(false);
             DateTimeParseContext newContext = context.copy();
-            int pos = PARSER.parse(newContext, text, position);
+            int pos = parser.parse(newContext, text, position);
             if (pos < 0) {
                 return pos;
             }
@@ -2952,10 +3195,18 @@
             Long nanoVal = newContext.getParsed(NANO_OF_SECOND);
             int sec = (secVal != null ? secVal.intValue() : 0);
             int nano = (nanoVal != null ? nanoVal.intValue() : 0);
+            int days = 0;
+            if (hour == 24 && min == 0 && sec == 0 && nano == 0) {
+                hour = 0;
+                days = 1;
+            } else if (hour == 23 && min == 59 && sec == 60) {
+                context.setParsedLeapSecond();
+                sec = 59;
+            }
             int year = (int) yearParsed % 10_000;
             long instantSecs;
             try {
-                LocalDateTime ldt = LocalDateTime.of(year, month, day, hour, min, sec, 0);
+                LocalDateTime ldt = LocalDateTime.of(year, month, day, hour, min, sec, 0).plusDays(days);
                 instantSecs = ldt.toEpochSecond(ZoneOffset.UTC);
                 instantSecs += Math.multiplyExact(yearParsed / 10_000L, SECONDS_PER_10000_YEARS);
             } catch (RuntimeException ex) {
@@ -4017,9 +4268,7 @@
             String key = chrono.getId() + '|' + locale.toString() + '|' + dateStyle + timeStyle;
             DateTimeFormatter formatter = FORMATTER_CACHE.get(key);
             if (formatter == null) {
-                LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased().getLocaleResources(locale);
-                String pattern = lr.getJavaTimeDateTimePattern(
-                        convertStyle(timeStyle), convertStyle(dateStyle), chrono.getCalendarType());
+                String pattern = getLocalizedDateTimePattern(dateStyle, timeStyle, chrono, locale);
                 formatter = new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter(locale);
                 DateTimeFormatter old = FORMATTER_CACHE.putIfAbsent(key, formatter);
                 if (old != null) {
@@ -4029,19 +4278,6 @@
             return formatter;
         }
 
-        /**
-         * Converts the given FormatStyle to the java.text.DateFormat style.
-         *
-         * @param style  the FormatStyle style
-         * @return the int style, or -1 if style is null, indicating unrequired
-         */
-        private int convertStyle(FormatStyle style) {
-            if (style == null) {
-                return -1;
-            }
-            return style.ordinal();  // indices happen to align
-        }
-
         @Override
         public String toString() {
             return "Localized(" + (dateStyle != null ? dateStyle : "") + "," +
@@ -4096,7 +4332,7 @@
                 case 'Y':
                     field = weekDef.weekBasedYear();
                     if (count == 2) {
-                        return new ReducedPrinterParser(field, 2, 2000);
+                        return new ReducedPrinterParser(field, 2, 2, 2000, 0);
                     } else {
                         return new NumberPrinterParser(field, count, 19,
                                 (count < 4) ? SignStyle.NORMAL : SignStyle.EXCEEDS_PAD, -1);
diff --git a/jdk/src/share/classes/java/time/format/DateTimeParseContext.java b/jdk/src/share/classes/java/time/format/DateTimeParseContext.java
index f2e3ff3..f72ef7b 100644
--- a/jdk/src/share/classes/java/time/format/DateTimeParseContext.java
+++ b/jdk/src/share/classes/java/time/format/DateTimeParseContext.java
@@ -61,6 +61,7 @@
  */
 package java.time.format;
 
+import java.time.Duration;
 import java.time.ZoneId;
 import java.time.chrono.Chronology;
 import java.time.chrono.IsoChronology;
@@ -79,7 +80,7 @@
  * Once parsing is complete, the {@link #toParsed()} is used to obtain the data.
  * It contains a method to resolve  the separate parsed fields into meaningful values.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is a mutable context intended for use from a single thread.
  * Usage of the class is thread-safe within standard parsing as a new instance of this class
  * is automatically created for each parse and parsing is single-threaded
@@ -118,9 +119,13 @@
 
     /**
      * Creates a copy of this context.
+     * This retains the case sensitive and strict flags.
      */
     DateTimeParseContext copy() {
-        return new DateTimeParseContext(formatter);
+        DateTimeParseContext newContext = new DateTimeParseContext(formatter);
+        newContext.caseSensitive = caseSensitive;
+        newContext.strict = strict;
+        return newContext;
     }
 
     //-----------------------------------------------------------------------
@@ -128,7 +133,7 @@
      * Gets the locale.
      * <p>
      * This locale is used to control localization in the parse except
-     * where localization is controlled by the symbols.
+     * where localization is controlled by the DecimalStyle.
      *
      * @return the locale, not null
      */
@@ -137,14 +142,14 @@
     }
 
     /**
-     * Gets the formatting symbols.
+     * Gets the DecimalStyle.
      * <p>
-     * The symbols control the localization of numeric parsing.
+     * The DecimalStyle controls the numeric parsing.
      *
-     * @return the formatting symbols, not null
+     * @return the DecimalStyle, not null
      */
-    DateTimeFormatSymbols getSymbols() {
-        return formatter.getSymbols();
+    DecimalStyle getDecimalStyle() {
+        return formatter.getDecimalStyle();
     }
 
     /**
@@ -370,6 +375,13 @@
         currentParsed().zone = zone;
     }
 
+    /**
+     * Stores the parsed leap second.
+     */
+    void setParsedLeapSecond() {
+        currentParsed().leapSecond = true;
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Returns a string version of the context for debugging.
diff --git a/jdk/src/share/classes/java/time/format/DateTimeParseException.java b/jdk/src/share/classes/java/time/format/DateTimeParseException.java
index 37b72a2..d02ed15 100644
--- a/jdk/src/share/classes/java/time/format/DateTimeParseException.java
+++ b/jdk/src/share/classes/java/time/format/DateTimeParseException.java
@@ -68,7 +68,7 @@
  * <p>
  * This exception includes the text being parsed and the error index.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is intended for use in a single thread.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/format/DateTimePrintContext.java b/jdk/src/share/classes/java/time/format/DateTimePrintContext.java
index 8124fc8..3e3f90f 100644
--- a/jdk/src/share/classes/java/time/format/DateTimePrintContext.java
+++ b/jdk/src/share/classes/java/time/format/DateTimePrintContext.java
@@ -85,7 +85,7 @@
  * <p>
  * This class provides a single wrapper to items used in the format.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is a mutable context intended for use from a single thread.
  * Usage of the class is thread-safe within standard printing as the framework creates
  * a new instance of the class for each format and printing is single-threaded.
@@ -234,7 +234,7 @@
      * Gets the locale.
      * <p>
      * This locale is used to control localization in the format output except
-     * where localization is controlled by the symbols.
+     * where localization is controlled by the DecimalStyle.
      *
      * @return the locale, not null
      */
@@ -243,14 +243,14 @@
     }
 
     /**
-     * Gets the formatting symbols.
+     * Gets the DecimalStyle.
      * <p>
-     * The symbols control the localization of numeric output.
+     * The DecimalStyle controls the localization of numeric output.
      *
-     * @return the formatting symbols, not null
+     * @return the DecimalStyle, not null
      */
-    DateTimeFormatSymbols getSymbols() {
-        return formatter.getSymbols();
+    DecimalStyle getDecimalStyle() {
+        return formatter.getDecimalStyle();
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/src/share/classes/java/time/format/DateTimeTextProvider.java b/jdk/src/share/classes/java/time/format/DateTimeTextProvider.java
index 7262c5b..4e1bd4a 100644
--- a/jdk/src/share/classes/java/time/format/DateTimeTextProvider.java
+++ b/jdk/src/share/classes/java/time/format/DateTimeTextProvider.java
@@ -94,7 +94,7 @@
 /**
  * A provider to obtain the textual form of a date-time field.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * Implementations must be thread-safe.
  * Implementations should cache the textual information.
  *
diff --git a/jdk/src/share/classes/java/time/format/DateTimeFormatSymbols.java b/jdk/src/share/classes/java/time/format/DecimalStyle.java
similarity index 82%
rename from jdk/src/share/classes/java/time/format/DateTimeFormatSymbols.java
rename to jdk/src/share/classes/java/time/format/DecimalStyle.java
index 0bfe844..8143037 100644
--- a/jdk/src/share/classes/java/time/format/DateTimeFormatSymbols.java
+++ b/jdk/src/share/classes/java/time/format/DecimalStyle.java
@@ -62,34 +62,38 @@
 package java.time.format;
 
 import java.text.DecimalFormatSymbols;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
 import java.util.Locale;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
 /**
- * Localized symbols used in date and time formatting.
+ * Localized decimal style used in date and time formatting.
  * <p>
  * A significant part of dealing with dates and times is the localization.
  * This class acts as a central point for accessing the information.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
  */
-public final class DateTimeFormatSymbols {
+public final class DecimalStyle {
 
     /**
-     * The standard set of non-localized symbols.
+     * The standard set of non-localized decimal style symbols.
      * <p>
      * This uses standard ASCII characters for zero, positive, negative and a dot for the decimal point.
      */
-    public static final DateTimeFormatSymbols STANDARD = new DateTimeFormatSymbols('0', '+', '-', '.');
+    public static final DecimalStyle STANDARD = new DecimalStyle('0', '+', '-', '.');
     /**
-     * The cache of symbols instances.
+     * The cache of DecimalStyle instances.
      */
-    private static final ConcurrentMap<Locale, DateTimeFormatSymbols> CACHE = new ConcurrentHashMap<>(16, 0.75f, 2);
+    private static final ConcurrentMap<Locale, DecimalStyle> CACHE = new ConcurrentHashMap<>(16, 0.75f, 2);
 
     /**
      * The zero digit.
@@ -114,17 +118,20 @@
      * <p>
      * The locale 'en_US' will always be present.
      *
-     * @return an array of locales for which localization is supported
+     * @return a Set of Locales for which localization is supported
      */
-    public static Locale[] getAvailableLocales() {
-        return DecimalFormatSymbols.getAvailableLocales();
+    public static Set<Locale> getAvailableLocales() {
+        Locale[] l = DecimalFormatSymbols.getAvailableLocales();
+        Set<Locale> locales = new HashSet<>(l.length);
+        Collections.addAll(locales, l);
+        return locales;
     }
 
     /**
-     * Obtains symbols for the default
+     * Obtains the DecimalStyle for the default
      * {@link java.util.Locale.Category#FORMAT FORMAT} locale.
      * <p>
-     * This method provides access to locale sensitive symbols.
+     * This method provides access to locale sensitive decimal style symbols.
      * <p>
      * This is equivalent to calling
      * {@link #of(Locale)
@@ -133,21 +140,21 @@
      * @see java.util.Locale.Category#FORMAT
      * @return the info, not null
      */
-    public static DateTimeFormatSymbols ofDefaultLocale() {
+    public static DecimalStyle ofDefaultLocale() {
         return of(Locale.getDefault(Locale.Category.FORMAT));
     }
 
     /**
-     * Obtains symbols for the specified locale.
+     * Obtains the DecimalStyle for the specified locale.
      * <p>
-     * This method provides access to locale sensitive symbols.
+     * This method provides access to locale sensitive decimal style symbols.
      *
      * @param locale  the locale, not null
      * @return the info, not null
      */
-    public static DateTimeFormatSymbols of(Locale locale) {
+    public static DecimalStyle of(Locale locale) {
         Objects.requireNonNull(locale, "locale");
-        DateTimeFormatSymbols info = CACHE.get(locale);
+        DecimalStyle info = CACHE.get(locale);
         if (info == null) {
             info = create(locale);
             CACHE.putIfAbsent(locale, info);
@@ -156,7 +163,7 @@
         return info;
     }
 
-    private static DateTimeFormatSymbols create(Locale locale) {
+    private static DecimalStyle create(Locale locale) {
         DecimalFormatSymbols oldSymbols = DecimalFormatSymbols.getInstance(locale);
         char zeroDigit = oldSymbols.getZeroDigit();
         char positiveSign = '+';
@@ -165,7 +172,7 @@
         if (zeroDigit == '0' && negativeSign == '-' && decimalSeparator == '.') {
             return STANDARD;
         }
-        return new DateTimeFormatSymbols(zeroDigit, positiveSign, negativeSign, decimalSeparator);
+        return new DecimalStyle(zeroDigit, positiveSign, negativeSign, decimalSeparator);
     }
 
     //-----------------------------------------------------------------------
@@ -177,7 +184,7 @@
      * @param negativeSignChar  the character to use for the negative sign
      * @param decimalPointChar  the character to use for the decimal point
      */
-    private DateTimeFormatSymbols(char zeroChar, char positiveSignChar, char negativeSignChar, char decimalPointChar) {
+    private DecimalStyle(char zeroChar, char positiveSignChar, char negativeSignChar, char decimalPointChar) {
         this.zeroDigit = zeroChar;
         this.positiveSign = positiveSignChar;
         this.negativeSign = negativeSignChar;
@@ -207,11 +214,11 @@
      * @return  a copy with a new character that represents zero, not null
 
      */
-    public DateTimeFormatSymbols withZeroDigit(char zeroDigit) {
+    public DecimalStyle withZeroDigit(char zeroDigit) {
         if (zeroDigit == this.zeroDigit) {
             return this;
         }
-        return new DateTimeFormatSymbols(zeroDigit, positiveSign, negativeSign, decimalSeparator);
+        return new DecimalStyle(zeroDigit, positiveSign, negativeSign, decimalSeparator);
     }
 
     //-----------------------------------------------------------------------
@@ -236,11 +243,11 @@
      * @param positiveSign  the character for the positive sign
      * @return  a copy with a new character that represents the positive sign, not null
      */
-    public DateTimeFormatSymbols withPositiveSign(char positiveSign) {
+    public DecimalStyle withPositiveSign(char positiveSign) {
         if (positiveSign == this.positiveSign) {
             return this;
         }
-        return new DateTimeFormatSymbols(zeroDigit, positiveSign, negativeSign, decimalSeparator);
+        return new DecimalStyle(zeroDigit, positiveSign, negativeSign, decimalSeparator);
     }
 
     //-----------------------------------------------------------------------
@@ -265,11 +272,11 @@
      * @param negativeSign  the character for the negative sign
      * @return  a copy with a new character that represents the negative sign, not null
      */
-    public DateTimeFormatSymbols withNegativeSign(char negativeSign) {
+    public DecimalStyle withNegativeSign(char negativeSign) {
         if (negativeSign == this.negativeSign) {
             return this;
         }
-        return new DateTimeFormatSymbols(zeroDigit, positiveSign, negativeSign, decimalSeparator);
+        return new DecimalStyle(zeroDigit, positiveSign, negativeSign, decimalSeparator);
     }
 
     //-----------------------------------------------------------------------
@@ -294,11 +301,11 @@
      * @param decimalSeparator  the character for the decimal point
      * @return  a copy with a new character that represents the decimal point, not null
      */
-    public DateTimeFormatSymbols withDecimalSeparator(char decimalSeparator) {
+    public DecimalStyle withDecimalSeparator(char decimalSeparator) {
         if (decimalSeparator == this.decimalSeparator) {
             return this;
         }
-        return new DateTimeFormatSymbols(zeroDigit, positiveSign, negativeSign, decimalSeparator);
+        return new DecimalStyle(zeroDigit, positiveSign, negativeSign, decimalSeparator);
     }
 
     //-----------------------------------------------------------------------
@@ -333,7 +340,7 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Checks if these symbols equal another set of symbols.
+     * Checks if this DecimalStyle is equal another DecimalStyle.
      *
      * @param obj  the object to check, null returns false
      * @return true if this is equal to the other date
@@ -343,8 +350,8 @@
         if (this == obj) {
             return true;
         }
-        if (obj instanceof DateTimeFormatSymbols) {
-            DateTimeFormatSymbols other = (DateTimeFormatSymbols) obj;
+        if (obj instanceof DecimalStyle) {
+            DecimalStyle other = (DecimalStyle) obj;
             return (zeroDigit == other.zeroDigit && positiveSign == other.positiveSign &&
                     negativeSign == other.negativeSign && decimalSeparator == other.decimalSeparator);
         }
@@ -352,7 +359,7 @@
     }
 
     /**
-     * A hash code for these symbols.
+     * A hash code for this DecimalStyle.
      *
      * @return a suitable hash code
      */
@@ -363,13 +370,13 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a string describing these symbols.
+     * Returns a string describing this DecimalStyle.
      *
      * @return a string description, not null
      */
     @Override
     public String toString() {
-        return "Symbols[" + zeroDigit + positiveSign + negativeSign + decimalSeparator + "]";
+        return "DecimalStyle[" + zeroDigit + positiveSign + negativeSign + decimalSeparator + "]";
     }
 
 }
diff --git a/jdk/src/share/classes/java/time/format/FormatStyle.java b/jdk/src/share/classes/java/time/format/FormatStyle.java
index 0be538e..a5c8229 100644
--- a/jdk/src/share/classes/java/time/format/FormatStyle.java
+++ b/jdk/src/share/classes/java/time/format/FormatStyle.java
@@ -67,7 +67,7 @@
  * These styles are used when obtaining a date-time style from configuration.
  * See {@link DateTimeFormatter} and {@link DateTimeFormatterBuilder} for usage.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This is an immutable and thread-safe enum.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/format/Parsed.java b/jdk/src/share/classes/java/time/format/Parsed.java
index a35fab1..b0a7fe8 100644
--- a/jdk/src/share/classes/java/time/format/Parsed.java
+++ b/jdk/src/share/classes/java/time/format/Parsed.java
@@ -80,6 +80,7 @@
 import java.time.DateTimeException;
 import java.time.LocalDate;
 import java.time.LocalTime;
+import java.time.Period;
 import java.time.ZoneId;
 import java.time.chrono.ChronoLocalDate;
 import java.time.chrono.Chronology;
@@ -105,7 +106,7 @@
  * Once parsing is completed, this class can be used as the resultant {@code TemporalAccessor}.
  * In most cases, it is only exposed once the fields have been resolved.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is a mutable context intended for use from a single thread.
  * Usage of the class is thread-safe within standard parsing as a new instance of this class
  * is automatically created for each parse and parsing is single-threaded
@@ -128,6 +129,10 @@
      */
     Chronology chrono;
     /**
+     * Whether a leap-second is parsed.
+     */
+    boolean leapSecond;
+    /**
      * The effective chronology.
      */
     Chronology effectiveChrono;
@@ -143,6 +148,10 @@
      * The resolved time.
      */
     private LocalTime time;
+    /**
+     * The excess period from time-only parsing.
+     */
+    Period excessDays = Period.ZERO;
 
     /**
      * Creates an instance.
@@ -159,6 +168,7 @@
         cloned.fieldValues.putAll(this.fieldValues);
         cloned.zone = this.zone;
         cloned.chrono = this.chrono;
+        cloned.leapSecond = this.leapSecond;
         return cloned;
     }
 
@@ -232,6 +242,7 @@
         resolveFields();
         resolveTimeLenient();
         crossCheck();
+        resolvePeriod();
         return this;
     }
 
@@ -308,36 +319,72 @@
     private void resolveTimeFields() {
         // simplify fields
         if (fieldValues.containsKey(CLOCK_HOUR_OF_DAY)) {
+            // lenient allows anything, smart allows 0-24, strict allows 1-24
             long ch = fieldValues.remove(CLOCK_HOUR_OF_DAY);
+            if (resolverStyle == ResolverStyle.STRICT || (resolverStyle == ResolverStyle.SMART && ch != 0)) {
+                CLOCK_HOUR_OF_DAY.checkValidValue(ch);
+            }
             updateCheckConflict(CLOCK_HOUR_OF_DAY, HOUR_OF_DAY, ch == 24 ? 0 : ch);
         }
         if (fieldValues.containsKey(CLOCK_HOUR_OF_AMPM)) {
+            // lenient allows anything, smart allows 0-12, strict allows 1-12
             long ch = fieldValues.remove(CLOCK_HOUR_OF_AMPM);
+            if (resolverStyle == ResolverStyle.STRICT || (resolverStyle == ResolverStyle.SMART && ch != 0)) {
+                CLOCK_HOUR_OF_AMPM.checkValidValue(ch);
+            }
             updateCheckConflict(CLOCK_HOUR_OF_AMPM, HOUR_OF_AMPM, ch == 12 ? 0 : ch);
         }
         if (fieldValues.containsKey(AMPM_OF_DAY) && fieldValues.containsKey(HOUR_OF_AMPM)) {
             long ap = fieldValues.remove(AMPM_OF_DAY);
             long hap = fieldValues.remove(HOUR_OF_AMPM);
-            updateCheckConflict(AMPM_OF_DAY, HOUR_OF_DAY, ap * 12 + hap);
+            if (resolverStyle == ResolverStyle.LENIENT) {
+                updateCheckConflict(AMPM_OF_DAY, HOUR_OF_DAY, Math.addExact(Math.multiplyExact(ap, 12), hap));
+            } else {  // STRICT or SMART
+                AMPM_OF_DAY.checkValidValue(ap);
+                HOUR_OF_AMPM.checkValidValue(ap);
+                updateCheckConflict(AMPM_OF_DAY, HOUR_OF_DAY, ap * 12 + hap);
+            }
+        }
+        if (fieldValues.containsKey(NANO_OF_DAY)) {
+            long nod = fieldValues.remove(NANO_OF_DAY);
+            if (resolverStyle != ResolverStyle.LENIENT) {
+                NANO_OF_DAY.checkValidValue(nod);
+            }
+            updateCheckConflict(NANO_OF_DAY, HOUR_OF_DAY, nod / 3600_000_000_000L);
+            updateCheckConflict(NANO_OF_DAY, MINUTE_OF_HOUR, (nod / 60_000_000_000L) % 60);
+            updateCheckConflict(NANO_OF_DAY, SECOND_OF_MINUTE, (nod / 1_000_000_000L) % 60);
+            updateCheckConflict(NANO_OF_DAY, NANO_OF_SECOND, nod % 1_000_000_000L);
         }
         if (fieldValues.containsKey(MICRO_OF_DAY)) {
             long cod = fieldValues.remove(MICRO_OF_DAY);
+            if (resolverStyle != ResolverStyle.LENIENT) {
+                MICRO_OF_DAY.checkValidValue(cod);
+            }
             updateCheckConflict(MICRO_OF_DAY, SECOND_OF_DAY, cod / 1_000_000L);
             updateCheckConflict(MICRO_OF_DAY, MICRO_OF_SECOND, cod % 1_000_000L);
         }
         if (fieldValues.containsKey(MILLI_OF_DAY)) {
             long lod = fieldValues.remove(MILLI_OF_DAY);
+            if (resolverStyle != ResolverStyle.LENIENT) {
+                MILLI_OF_DAY.checkValidValue(lod);
+            }
             updateCheckConflict(MILLI_OF_DAY, SECOND_OF_DAY, lod / 1_000);
             updateCheckConflict(MILLI_OF_DAY, MILLI_OF_SECOND, lod % 1_000);
         }
         if (fieldValues.containsKey(SECOND_OF_DAY)) {
             long sod = fieldValues.remove(SECOND_OF_DAY);
+            if (resolverStyle != ResolverStyle.LENIENT) {
+                SECOND_OF_DAY.checkValidValue(sod);
+            }
             updateCheckConflict(SECOND_OF_DAY, HOUR_OF_DAY, sod / 3600);
             updateCheckConflict(SECOND_OF_DAY, MINUTE_OF_HOUR, (sod / 60) % 60);
             updateCheckConflict(SECOND_OF_DAY, SECOND_OF_MINUTE, sod % 60);
         }
         if (fieldValues.containsKey(MINUTE_OF_DAY)) {
             long mod = fieldValues.remove(MINUTE_OF_DAY);
+            if (resolverStyle != ResolverStyle.LENIENT) {
+                MINUTE_OF_DAY.checkValidValue(mod);
+            }
             updateCheckConflict(MINUTE_OF_DAY, HOUR_OF_DAY, mod / 60);
             updateCheckConflict(MINUTE_OF_DAY, MINUTE_OF_HOUR, mod % 60);
         }
@@ -345,29 +392,34 @@
         // combine partial second fields strictly, leaving lenient expansion to later
         if (fieldValues.containsKey(NANO_OF_SECOND)) {
             long nos = fieldValues.get(NANO_OF_SECOND);
+            if (resolverStyle != ResolverStyle.LENIENT) {
+                NANO_OF_SECOND.checkValidValue(nos);
+            }
             if (fieldValues.containsKey(MICRO_OF_SECOND)) {
                 long cos = fieldValues.remove(MICRO_OF_SECOND);
+                if (resolverStyle != ResolverStyle.LENIENT) {
+                    MICRO_OF_SECOND.checkValidValue(cos);
+                }
                 nos = cos * 1000 + (nos % 1000);
                 updateCheckConflict(MICRO_OF_SECOND, NANO_OF_SECOND, nos);
             }
             if (fieldValues.containsKey(MILLI_OF_SECOND)) {
                 long los = fieldValues.remove(MILLI_OF_SECOND);
+                if (resolverStyle != ResolverStyle.LENIENT) {
+                    MILLI_OF_SECOND.checkValidValue(los);
+                }
                 updateCheckConflict(MILLI_OF_SECOND, NANO_OF_SECOND, los * 1_000_000L + (nos % 1_000_000L));
             }
         }
 
-        // convert to time if possible
-        if (fieldValues.containsKey(NANO_OF_DAY)) {
-            long nod = fieldValues.remove(NANO_OF_DAY);
-            updateCheckConflict(LocalTime.ofNanoOfDay(nod));
-        }
+        // convert to time if all four fields available (optimization)
         if (fieldValues.containsKey(HOUR_OF_DAY) && fieldValues.containsKey(MINUTE_OF_HOUR) &&
                 fieldValues.containsKey(SECOND_OF_MINUTE) && fieldValues.containsKey(NANO_OF_SECOND)) {
-            int hodVal = HOUR_OF_DAY.checkValidIntValue(fieldValues.remove(HOUR_OF_DAY));
-            int mohVal = MINUTE_OF_HOUR.checkValidIntValue(fieldValues.remove(MINUTE_OF_HOUR));
-            int somVal = SECOND_OF_MINUTE.checkValidIntValue(fieldValues.remove(SECOND_OF_MINUTE));
-            int nosVal = NANO_OF_SECOND.checkValidIntValue(fieldValues.remove(NANO_OF_SECOND));
-            updateCheckConflict(LocalTime.of(hodVal, mohVal, somVal, nosVal));
+            long hod = fieldValues.remove(HOUR_OF_DAY);
+            long moh = fieldValues.remove(MINUTE_OF_HOUR);
+            long som = fieldValues.remove(SECOND_OF_MINUTE);
+            long nos = fieldValues.remove(NANO_OF_SECOND);
+            resolveTime(hod, moh, som, nos);
         }
     }
 
@@ -377,7 +429,7 @@
         // which would break updateCheckConflict(field)
 
         if (time == null) {
-            // can only get here if NANO_OF_SECOND not present
+            // NANO_OF_SECOND merged with MILLI/MICRO above
             if (fieldValues.containsKey(MILLI_OF_SECOND)) {
                 long los = fieldValues.remove(MILLI_OF_SECOND);
                 if (fieldValues.containsKey(MICRO_OF_SECOND)) {
@@ -395,43 +447,87 @@
                 long cos = fieldValues.remove(MICRO_OF_SECOND);
                 fieldValues.put(NANO_OF_SECOND, cos * 1_000L);
             }
-        }
 
-        // merge hour/minute/second/nano leniently
-        Long hod = fieldValues.get(HOUR_OF_DAY);
-        if (hod != null) {
-            int hodVal = HOUR_OF_DAY.checkValidIntValue(hod);
-            Long moh = fieldValues.get(MINUTE_OF_HOUR);
-            Long som = fieldValues.get(SECOND_OF_MINUTE);
-            Long nos = fieldValues.get(NANO_OF_SECOND);
+            // merge hour/minute/second/nano leniently
+            Long hod = fieldValues.get(HOUR_OF_DAY);
+            if (hod != null) {
+                Long moh = fieldValues.get(MINUTE_OF_HOUR);
+                Long som = fieldValues.get(SECOND_OF_MINUTE);
+                Long nos = fieldValues.get(NANO_OF_SECOND);
 
-            // check for invalid combinations that cannot be defaulted
-            if (time == null) {
+                // check for invalid combinations that cannot be defaulted
                 if ((moh == null && (som != null || nos != null)) ||
                         (moh != null && som == null && nos != null)) {
                     return;
                 }
-            }
 
-            // default as necessary and build time
-            int mohVal = (moh != null ? MINUTE_OF_HOUR.checkValidIntValue(moh) : (time != null ? time.getMinute() : 0));
-            int somVal = (som != null ? SECOND_OF_MINUTE.checkValidIntValue(som) : (time != null ? time.getSecond() : 0));
-            int nosVal = (nos != null ? NANO_OF_SECOND.checkValidIntValue(nos) : (time != null ? time.getNano() : 0));
-            updateCheckConflict(LocalTime.of(hodVal, mohVal, somVal, nosVal));
-            fieldValues.remove(HOUR_OF_DAY);
-            fieldValues.remove(MINUTE_OF_HOUR);
-            fieldValues.remove(SECOND_OF_MINUTE);
-            fieldValues.remove(NANO_OF_SECOND);
+                // default as necessary and build time
+                long mohVal = (moh != null ? moh : 0);
+                long somVal = (som != null ? som : 0);
+                long nosVal = (nos != null ? nos : 0);
+                resolveTime(hod, mohVal, somVal, nosVal);
+                fieldValues.remove(HOUR_OF_DAY);
+                fieldValues.remove(MINUTE_OF_HOUR);
+                fieldValues.remove(SECOND_OF_MINUTE);
+                fieldValues.remove(NANO_OF_SECOND);
+            }
+        }
+
+        // validate remaining
+        if (resolverStyle != ResolverStyle.LENIENT && fieldValues.size() > 0) {
+            for (Entry<TemporalField, Long> entry : fieldValues.entrySet()) {
+                TemporalField field = entry.getKey();
+                if (field instanceof ChronoField && field.isTimeBased()) {
+                    ((ChronoField) field).checkValidValue(entry.getValue());
+                }
+            }
         }
     }
 
-    private void updateCheckConflict(LocalTime lt) {
+    private void resolveTime(long hod, long moh, long som, long nos) {
+        if (resolverStyle == ResolverStyle.LENIENT) {
+            long totalNanos = Math.multiplyExact(hod, 3600_000_000_000L);
+            totalNanos = Math.addExact(totalNanos, Math.multiplyExact(moh, 60_000_000_000L));
+            totalNanos = Math.addExact(totalNanos, Math.multiplyExact(som, 1_000_000_000L));
+            totalNanos = Math.addExact(totalNanos, nos);
+            int excessDays = (int) Math.floorDiv(totalNanos, 86400_000_000_000L);  // safe int cast
+            long nod = Math.floorMod(totalNanos, 86400_000_000_000L);
+            updateCheckConflict(LocalTime.ofNanoOfDay(nod), Period.ofDays(excessDays));
+        } else {  // STRICT or SMART
+            int mohVal = MINUTE_OF_HOUR.checkValidIntValue(moh);
+            int nosVal = NANO_OF_SECOND.checkValidIntValue(nos);
+            // handle 24:00 end of day
+            if (resolverStyle == ResolverStyle.SMART && hod == 24 && mohVal == 0 && som == 0 && nosVal == 0) {
+                updateCheckConflict(LocalTime.MIDNIGHT, Period.ofDays(1));
+            } else {
+                int hodVal = HOUR_OF_DAY.checkValidIntValue(hod);
+                int somVal = SECOND_OF_MINUTE.checkValidIntValue(som);
+                updateCheckConflict(LocalTime.of(hodVal, mohVal, somVal, nosVal), Period.ZERO);
+            }
+        }
+    }
+
+    private void resolvePeriod() {
+        // add whole days if we have both date and time
+        if (date != null && time != null && excessDays.isZero() == false) {
+            date = date.plus(excessDays);
+            excessDays = Period.ZERO;
+        }
+    }
+
+    private void updateCheckConflict(LocalTime timeToSet, Period periodToSet) {
         if (time != null) {
-            if (lt != null && time.equals(lt) == false) {
-                throw new DateTimeException("Conflict found: Fields resolved to two different times: " + time + " " + lt);
+            if (time.equals(timeToSet) == false) {
+                throw new DateTimeException("Conflict found: Fields resolved to different times: " + time + " " + timeToSet);
+            }
+            if (excessDays.isZero() == false && periodToSet.isZero() == false && excessDays.equals(periodToSet) == false) {
+                throw new DateTimeException("Conflict found: Fields resolved to different excess periods: " + excessDays + " " + periodToSet);
+            } else {
+                excessDays = periodToSet;
             }
         } else {
-            time = lt;
+            time = timeToSet;
+            excessDays = periodToSet;
         }
     }
 
diff --git a/jdk/src/share/classes/java/time/format/ResolverStyle.java b/jdk/src/share/classes/java/time/format/ResolverStyle.java
index b53b827..313bd17 100644
--- a/jdk/src/share/classes/java/time/format/ResolverStyle.java
+++ b/jdk/src/share/classes/java/time/format/ResolverStyle.java
@@ -69,7 +69,7 @@
  * Phase 2 resolves the parsed field-value pairs into date and/or time objects.
  * This style is used to control how phase 2, resolving, happens.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This is an immutable and thread-safe enum.
  *
  * @since 1.8
@@ -96,10 +96,9 @@
      * behavior. Individual fields will interpret this differently.
      * <p>
      * For example, resolving year-month and day-of-month in the ISO calendar
-     * system using smart mode will ensure that the day-of-month is valid
-     * for the year-month, rejecting invalid values, with the exception that
-     * February 29th in a year other than a leap year will be converted to
-     * February 28th.
+     * system using smart mode will ensure that the day-of-month is from
+     * 1 to 31, converting any value beyond the last valid day-of-month to be
+     * the last valid day-of-month.
      */
     SMART,
     /**
@@ -110,6 +109,7 @@
      * <p>
      * For example, lenient mode allows the month in the ISO calendar system
      * to be outside the range 1 to 12.
+     * For example, month 15 is treated as being 3 months after month 12.
      */
     LENIENT;
 
diff --git a/jdk/src/share/classes/java/time/format/SignStyle.java b/jdk/src/share/classes/java/time/format/SignStyle.java
index 2f8c57a..56dfd03 100644
--- a/jdk/src/share/classes/java/time/format/SignStyle.java
+++ b/jdk/src/share/classes/java/time/format/SignStyle.java
@@ -68,7 +68,7 @@
  * to be controlled using this enum.
  * See {@link DateTimeFormatterBuilder} for usage.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This is an immutable and thread-safe enum.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/format/TextStyle.java b/jdk/src/share/classes/java/time/format/TextStyle.java
index dbc2c27..ed65d27 100644
--- a/jdk/src/share/classes/java/time/format/TextStyle.java
+++ b/jdk/src/share/classes/java/time/format/TextStyle.java
@@ -80,7 +80,7 @@
  * For example, the word used for a month when used alone in a date picker is different
  * to the word used for month in association with a day and year in a date.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This is immutable and thread-safe enum.
  */
 public enum TextStyle {
diff --git a/jdk/src/share/classes/java/time/format/package-info.java b/jdk/src/share/classes/java/time/format/package-info.java
index 94a0600..140bb6d 100644
--- a/jdk/src/share/classes/java/time/format/package-info.java
+++ b/jdk/src/share/classes/java/time/format/package-info.java
@@ -76,7 +76,7 @@
  * Localization occurs by calling
  * {@link java.time.format.DateTimeFormatter#withLocale(java.util.Locale) withLocale(Locale)}
  * on the formatter. Further customization is possible using
- * {@link java.time.format.DateTimeFormatSymbols DateTimeFormatSymbols}.
+ * {@link java.time.format.DecimalStyle DecimalStyle}.
  * </p>
  *
  * <h3>Package specification</h3>
diff --git a/jdk/src/share/classes/java/time/temporal/ChronoField.java b/jdk/src/share/classes/java/time/temporal/ChronoField.java
index 0fdeb22..ac4522b 100644
--- a/jdk/src/share/classes/java/time/temporal/ChronoField.java
+++ b/jdk/src/share/classes/java/time/temporal/ChronoField.java
@@ -93,7 +93,7 @@
  * just with slightly different rules.
  * The documentation of each field explains how it operates.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This is a final, immutable and thread-safe enum.
  *
  * @since 1.8
@@ -115,6 +115,10 @@
      * object stores, using integer division to remove excess precision.
      * For example, if the {@code TemporalAccessor} stores time to millisecond precision,
      * then the nano-of-second must be divided by 1,000,000 before replacing the milli-of-second.
+     * <p>
+     * When parsing this field it behaves equivalent to the following:
+     * The value is validated in strict and smart mode but not in lenient mode.
+     * The field is resolved in combination with {@code MILLI_OF_SECOND} and {@code MICRO_OF_SECOND}.
      */
     NANO_OF_SECOND("NanoOfSecond", NANOS, SECONDS, ValueRange.of(0, 999_999_999)),
     /**
@@ -126,6 +130,11 @@
      * This field is used to represent the nano-of-day handling any fraction of the second.
      * Implementations of {@code TemporalAccessor} should provide a value for this field if
      * they can return a value for {@link #SECOND_OF_DAY} filling unknown precision with zero.
+     * <p>
+     * When parsing this field it behaves equivalent to the following:
+     * The value is validated in strict and smart mode but not in lenient mode.
+     * The value is split to form {@code NANO_OF_SECOND}, {@code SECOND_OF_MINUTE},
+     * {@code MINUTE_OF_HOUR} and {@code HOUR_OF_DAY} fields.
      */
     NANO_OF_DAY("NanoOfDay", NANOS, DAYS, ValueRange.of(0, 86400L * 1000_000_000L - 1)),
     /**
@@ -141,6 +150,11 @@
      * <p>
      * When this field is used for setting a value, it should behave in the same way as
      * setting {@link #NANO_OF_SECOND} with the value multiplied by 1,000.
+     * <p>
+     * When parsing this field it behaves equivalent to the following:
+     * The value is validated in strict and smart mode but not in lenient mode.
+     * The field is resolved in combination with {@code MILLI_OF_SECOND} to produce
+     * {@code NANO_OF_SECOND}.
      */
     MICRO_OF_SECOND("MicroOfSecond", MICROS, SECONDS, ValueRange.of(0, 999_999)),
     /**
@@ -155,6 +169,11 @@
      * <p>
      * When this field is used for setting a value, it should behave in the same way as
      * setting {@link #NANO_OF_DAY} with the value multiplied by 1,000.
+     * <p>
+     * When parsing this field it behaves equivalent to the following:
+     * The value is validated in strict and smart mode but not in lenient mode.
+     * The value is split to form {@code MICRO_OF_SECOND}, {@code SECOND_OF_MINUTE},
+     * {@code MINUTE_OF_HOUR} and {@code HOUR_OF_DAY} fields.
      */
     MICRO_OF_DAY("MicroOfDay", MICROS, DAYS, ValueRange.of(0, 86400L * 1000_000L - 1)),
     /**
@@ -170,6 +189,11 @@
      * <p>
      * When this field is used for setting a value, it should behave in the same way as
      * setting {@link #NANO_OF_SECOND} with the value multiplied by 1,000,000.
+     * <p>
+     * When parsing this field it behaves equivalent to the following:
+     * The value is validated in strict and smart mode but not in lenient mode.
+     * The field is resolved in combination with {@code MICRO_OF_SECOND} to produce
+     * {@code NANO_OF_SECOND}.
      */
     MILLI_OF_SECOND("MilliOfSecond", MILLIS, SECONDS, ValueRange.of(0, 999)),
     /**
@@ -184,6 +208,11 @@
      * <p>
      * When this field is used for setting a value, it should behave in the same way as
      * setting {@link #NANO_OF_DAY} with the value multiplied by 1,000,000.
+     * <p>
+     * When parsing this field it behaves equivalent to the following:
+     * The value is validated in strict and smart mode but not in lenient mode.
+     * The value is split to form {@code MILLI_OF_SECOND}, {@code SECOND_OF_MINUTE},
+     * {@code MINUTE_OF_HOUR} and {@code HOUR_OF_DAY} fields.
      */
     MILLI_OF_DAY("MilliOfDay", MILLIS, DAYS, ValueRange.of(0, 86400L * 1000L - 1)),
     /**
@@ -191,6 +220,9 @@
      * <p>
      * This counts the second within the minute, from 0 to 59.
      * This field has the same meaning for all calendar systems.
+     * <p>
+     * When parsing this field it behaves equivalent to the following:
+     * The value is validated in strict and smart mode but not in lenient mode.
      */
     SECOND_OF_MINUTE("SecondOfMinute", SECONDS, MINUTES, ValueRange.of(0, 59), "second"),
     /**
@@ -198,6 +230,11 @@
      * <p>
      * This counts the second within the day, from 0 to (24 * 60 * 60) - 1.
      * This field has the same meaning for all calendar systems.
+     * <p>
+     * When parsing this field it behaves equivalent to the following:
+     * The value is validated in strict and smart mode but not in lenient mode.
+     * The value is split to form {@code SECOND_OF_MINUTE}, {@code MINUTE_OF_HOUR}
+     * and {@code HOUR_OF_DAY} fields.
      */
     SECOND_OF_DAY("SecondOfDay", SECONDS, DAYS, ValueRange.of(0, 86400L - 1)),
     /**
@@ -205,6 +242,9 @@
      * <p>
      * This counts the minute within the hour, from 0 to 59.
      * This field has the same meaning for all calendar systems.
+     * <p>
+     * When parsing this field it behaves equivalent to the following:
+     * The value is validated in strict and smart mode but not in lenient mode.
      */
     MINUTE_OF_HOUR("MinuteOfHour", MINUTES, HOURS, ValueRange.of(0, 59), "minute"),
     /**
@@ -212,6 +252,10 @@
      * <p>
      * This counts the minute within the day, from 0 to (24 * 60) - 1.
      * This field has the same meaning for all calendar systems.
+     * <p>
+     * When parsing this field it behaves equivalent to the following:
+     * The value is validated in strict and smart mode but not in lenient mode.
+     * The value is split to form {@code MINUTE_OF_HOUR} and {@code HOUR_OF_DAY} fields.
      */
     MINUTE_OF_DAY("MinuteOfDay", MINUTES, DAYS, ValueRange.of(0, (24 * 60) - 1)),
     /**
@@ -220,6 +264,12 @@
      * This counts the hour within the AM/PM, from 0 to 11.
      * This is the hour that would be observed on a standard 12-hour digital clock.
      * This field has the same meaning for all calendar systems.
+     * <p>
+     * When parsing this field it behaves equivalent to the following:
+     * The value is validated from 0 to 11 in strict and smart mode.
+     * In lenient mode the value is not validated. It is combined with
+     * {@code AMPM_OF_DAY} to form {@code HOUR_OF_DAY} by multiplying
+     * the {AMPM_OF_DAY} value by 12.
      */
     HOUR_OF_AMPM("HourOfAmPm", HOURS, HALF_DAYS, ValueRange.of(0, 11)),
     /**
@@ -228,6 +278,12 @@
      * This counts the hour within the AM/PM, from 1 to 12.
      * This is the hour that would be observed on a standard 12-hour analog wall clock.
      * This field has the same meaning for all calendar systems.
+     * <p>
+     * When parsing this field it behaves equivalent to the following:
+     * The value is validated from 1 to 12 in strict mode and from
+     * 0 to 12 in smart mode. In lenient mode the value is not validated.
+     * The field is converted to an {@code HOUR_OF_AMPM} with the same value,
+     * unless the value is 12, in which case it is converted to 0.
      */
     CLOCK_HOUR_OF_AMPM("ClockHourOfAmPm", HOURS, HALF_DAYS, ValueRange.of(1, 12)),
     /**
@@ -236,6 +292,13 @@
      * This counts the hour within the day, from 0 to 23.
      * This is the hour that would be observed on a standard 24-hour digital clock.
      * This field has the same meaning for all calendar systems.
+     * <p>
+     * When parsing this field it behaves equivalent to the following:
+     * The value is validated in strict and smart mode but not in lenient mode.
+     * The field is combined with {@code MINUTE_OF_HOUR}, {@code SECOND_OF_MINUTE} and
+     * {@code NANO_OF_SECOND} to produce a {@code LocalTime}.
+     * In lenient mode, any excess days are added to the parsed date, or
+     * made available via {@link java.time.format.DateTimeFormatter#parsedExcessDays()}.
      */
     HOUR_OF_DAY("HourOfDay", HOURS, DAYS, ValueRange.of(0, 23), "hour"),
     /**
@@ -244,6 +307,12 @@
      * This counts the hour within the AM/PM, from 1 to 24.
      * This is the hour that would be observed on a 24-hour analog wall clock.
      * This field has the same meaning for all calendar systems.
+     * <p>
+     * When parsing this field it behaves equivalent to the following:
+     * The value is validated from 1 to 24 in strict mode and from
+     * 0 to 24 in smart mode. In lenient mode the value is not validated.
+     * The field is converted to an {@code HOUR_OF_DAY} with the same value,
+     * unless the value is 24, in which case it is converted to 0.
      */
     CLOCK_HOUR_OF_DAY("ClockHourOfDay", HOURS, DAYS, ValueRange.of(1, 24)),
     /**
@@ -251,6 +320,12 @@
      * <p>
      * This counts the AM/PM within the day, from 0 (AM) to 1 (PM).
      * This field has the same meaning for all calendar systems.
+     * <p>
+     * When parsing this field it behaves equivalent to the following:
+     * The value is validated from 0 to 1 in strict and smart mode.
+     * In lenient mode the value is not validated. It is combined with
+     * {@code HOUR_OF_AMPM} to form {@code HOUR_OF_DAY} by multiplying
+     * the {AMPM_OF_DAY} value by 12.
      */
     AMPM_OF_DAY("AmPmOfDay", HALF_DAYS, DAYS, ValueRange.of(0, 1), "dayperiod"),
     /**
diff --git a/jdk/src/share/classes/java/time/temporal/ChronoUnit.java b/jdk/src/share/classes/java/time/temporal/ChronoUnit.java
index 03c5310..661960c 100644
--- a/jdk/src/share/classes/java/time/temporal/ChronoUnit.java
+++ b/jdk/src/share/classes/java/time/temporal/ChronoUnit.java
@@ -72,7 +72,7 @@
  * just with slightly different rules.
  * The documentation of each unit explains how it operates.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This is a final, immutable and thread-safe enum.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/temporal/IsoFields.java b/jdk/src/share/classes/java/time/temporal/IsoFields.java
index 851685a..e335c43 100644
--- a/jdk/src/share/classes/java/time/temporal/IsoFields.java
+++ b/jdk/src/share/classes/java/time/temporal/IsoFields.java
@@ -146,7 +146,7 @@
  * <tr><th>2009-01-05</th><td>Monday</td><td>Week 2 of week-based-year 2009</td></tr>
  * </table>
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * <p>
  * This class is immutable and thread-safe.
  *
diff --git a/jdk/src/share/classes/java/time/temporal/JulianFields.java b/jdk/src/share/classes/java/time/temporal/JulianFields.java
index 72956ce..95400ad 100644
--- a/jdk/src/share/classes/java/time/temporal/JulianFields.java
+++ b/jdk/src/share/classes/java/time/temporal/JulianFields.java
@@ -81,7 +81,7 @@
  * The fields are supported, and can be queried and set if {@code EPOCH_DAY} is available.
  * The fields work with all chronologies.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This is an immutable and thread-safe class.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/temporal/Temporal.java b/jdk/src/share/classes/java/time/temporal/Temporal.java
index 7cbc49f..1928186 100644
--- a/jdk/src/share/classes/java/time/temporal/Temporal.java
+++ b/jdk/src/share/classes/java/time/temporal/Temporal.java
@@ -119,7 +119,7 @@
  *  days to months.
  * </ul><p>
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This interface places no restrictions on the mutability of implementations,
  * however immutability is strongly recommended.
  * All implementations must be {@link Comparable}.
@@ -146,7 +146,7 @@
      *  date = date.with(next(WEDNESDAY));   // static import from Adjusters and DayOfWeek
      * </pre>
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * Implementations must not alter either this object.
      * Instead, an adjusted copy of the original must be returned.
      * This provides equivalent, safe behavior for immutable and mutable implementations.
@@ -177,7 +177,7 @@
      * In cases like this, the field is responsible for resolving the result. Typically it will choose
      * the previous valid date, which would be the last valid day of February in this example.
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * Implementations must check and handle all fields defined in {@link ChronoField}.
      * If the field is supported, then the adjustment must be performed.
      * If unsupported, then an {@code UnsupportedTemporalTypeException} must be thrown.
@@ -217,7 +217,7 @@
      * Note that calling {@code plus} followed by {@code minus} is not guaranteed to
      * return the same date-time.
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * Implementations must not alter either this object.
      * Instead, an adjusted copy of the original must be returned.
      * This provides equivalent, safe behavior for immutable and mutable implementations.
@@ -247,12 +247,8 @@
      * a date representing the 31st January, then adding one month would be unclear.
      * In cases like this, the field is responsible for resolving the result. Typically it will choose
      * the previous valid date, which would be the last valid day of February in this example.
-     * <p>
-     * If the implementation represents a date-time that has boundaries, such as {@code LocalTime},
-     * then the permitted units must include the boundary unit, but no multiples of the boundary unit.
-     * For example, {@code LocalTime} must accept {@code DAYS} but not {@code WEEKS} or {@code MONTHS}.
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * Implementations must check and handle all units defined in {@link ChronoUnit}.
      * If the unit is supported, then the addition must be performed.
      * If unsupported, then an {@code UnsupportedTemporalTypeException} must be thrown.
@@ -292,7 +288,7 @@
      * Note that calling {@code plus} followed by {@code minus} is not guaranteed to
      * return the same date-time.
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * Implementations must not alter either this object.
      * Instead, an adjusted copy of the original must be returned.
      * This provides equivalent, safe behavior for immutable and mutable implementations.
@@ -322,12 +318,8 @@
      * a date representing the 31st March, then subtracting one month would be unclear.
      * In cases like this, the field is responsible for resolving the result. Typically it will choose
      * the previous valid date, which would be the last valid day of February in this example.
-     * <p>
-     * If the implementation represents a date-time that has boundaries, such as {@code LocalTime},
-     * then the permitted units must include the boundary unit, but no multiples of the boundary unit.
-     * For example, {@code LocalTime} must accept {@code DAYS} but not {@code WEEKS} or {@code MONTHS}.
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * Implementations must behave in a manor equivalent to the default method behavior.
      * <p>
      * Implementations must not alter either this object or the specified temporal object.
@@ -353,10 +345,10 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Calculates the period between this temporal and another temporal in
-     * terms of the specified unit.
+     * Calculates the amount of time until another temporal in terms of the specified unit.
      * <p>
-     * This calculates the period between two temporals in terms of a single unit.
+     * This calculates the amount of time between two temporal objects
+     * of the same type in terms of a single {@code TemporalUnit}.
      * The start and end points are {@code this} and the specified temporal.
      * The result will be negative if the end is before the start.
      * For example, the period in hours between two temporal objects can be
@@ -385,7 +377,7 @@
      *  long daysBetween = DAYS.between(start, end);
      * </pre>
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * Implementations must begin by checking to ensure that the input temporal
      * object is of the same observable type as the implementation.
      * They must then perform the calculation for all instances of {@link ChronoUnit}.
@@ -410,11 +402,11 @@
      * Neither this object, nor the specified temporal, may be altered.
      *
      * @param endTemporal  the end temporal, of the same type as this object, not null
-     * @param unit  the unit to measure the period in, not null
-     * @return the period between this temporal object and the specified one in terms of
-     *  the unit; positive if the specified object is later than this one, negative if
-     *  it is earlier than this one
-     * @throws DateTimeException if the period cannot be calculated
+     * @param unit  the unit to measure the amount in, not null
+     * @return the amount of time between this temporal object and the specified one
+     *  in terms of the unit; positive if the specified object is later than this one,
+     *  negative if it is earlier than this one
+     * @throws DateTimeException if the amount cannot be calculated
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
diff --git a/jdk/src/share/classes/java/time/temporal/TemporalAccessor.java b/jdk/src/share/classes/java/time/temporal/TemporalAccessor.java
index 3f4a571..a212be8 100644
--- a/jdk/src/share/classes/java/time/temporal/TemporalAccessor.java
+++ b/jdk/src/share/classes/java/time/temporal/TemporalAccessor.java
@@ -94,7 +94,7 @@
  * of this interface may be in calendar systems other than ISO.
  * See {@link java.time.chrono.ChronoLocalDate} for a fuller discussion of the issues.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This interface places no restrictions on the mutability of implementations,
  * however immutability is strongly recommended.
  *
@@ -109,7 +109,7 @@
      * If false, then calling the {@link #range(TemporalField) range} and {@link #get(TemporalField) get}
      * methods will throw an exception.
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * Implementations must check and handle all fields defined in {@link ChronoField}.
      * If the field is supported, then true is returned, otherwise false
      * <p>
@@ -137,7 +137,7 @@
      * and it is important not to read too much into them. For example, there
      * could be values within the range that are invalid for the field.
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * Implementations must check and handle all fields defined in {@link ChronoField}.
      * If the field is supported, then the range of the field must be returned.
      * If unsupported, then an {@code UnsupportedTemporalTypeException} must be thrown.
@@ -183,7 +183,7 @@
      * If the date-time cannot return the value, because the field is unsupported or for
      * some other reason, an exception will be thrown.
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * Implementations must check and handle all fields defined in {@link ChronoField}.
      * If the field is supported and has an {@code int} range, then the value of
      * the field must be returned.
@@ -231,7 +231,7 @@
      * If the date-time cannot return the value, because the field is unsupported or for
      * some other reason, an exception will be thrown.
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * Implementations must check and handle all fields defined in {@link ChronoField}.
      * If the field is supported, then the value of the field must be returned.
      * If unsupported, then an {@code UnsupportedTemporalTypeException} must be thrown.
@@ -265,7 +265,7 @@
      * {@code LocalDate::from} and {@code ZoneId::from}.
      * Additional implementations are provided as static methods on {@link TemporalQuery}.
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * The default implementation must behave equivalent to this code:
      * <pre>
      *  if (query == TemporalQuery.zoneId() ||
diff --git a/jdk/src/share/classes/java/time/temporal/TemporalAdjuster.java b/jdk/src/share/classes/java/time/temporal/TemporalAdjuster.java
index 0cd44a3..13f8cea 100644
--- a/jdk/src/share/classes/java/time/temporal/TemporalAdjuster.java
+++ b/jdk/src/share/classes/java/time/temporal/TemporalAdjuster.java
@@ -97,7 +97,7 @@
  * <li>finding the next or previous day-of-week, such as "next Thursday"
  * </ul>
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This interface places no restrictions on the mutability of implementations,
  * however immutability is strongly recommended.
  * <p>
@@ -127,7 +127,7 @@
      * It is recommended to use the second approach, {@code with(TemporalAdjuster)},
      * as it is a lot clearer to read in code.
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * The implementation must take the input object and adjust it.
      * The implementation defines the logic of the adjustment and is responsible for
      * documenting that logic. It may use any method on {@code Temporal} to
@@ -162,10 +162,10 @@
      * This is provided for convenience to make user-written adjusters simpler.
      * <p>
      * In general, user-written adjusters should be static constants:
-     * <pre>
+     * <pre>{@code
      *  static TemporalAdjuster TWO_DAYS_LATER = TemporalAdjuster.ofDateAdjuster(
      *    date -> date.plusDays(2));
-     * </pre>
+     * }</pre>
      *
      * @param dateBasedAdjuster  the date-based adjuster, not null
      * @return the temporal adjuster wrapping on the date adjuster, not null
diff --git a/jdk/src/share/classes/java/time/temporal/TemporalAmount.java b/jdk/src/share/classes/java/time/temporal/TemporalAmount.java
index a264eba..802dc4d 100644
--- a/jdk/src/share/classes/java/time/temporal/TemporalAmount.java
+++ b/jdk/src/share/classes/java/time/temporal/TemporalAmount.java
@@ -90,7 +90,7 @@
  * used in application code. Instead, applications should create and pass
  * around instances of concrete types, such as {@code Period} and {@code Duration}.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This interface places no restrictions on the mutability of implementations,
  * however immutability is strongly recommended.
  *
@@ -104,7 +104,7 @@
      * value of the {@code TemporalAmount}.  A value must be returned
      * for each unit listed in {@code getUnits}.
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * Implementations may declare support for units not listed by {@link #getUnits()}.
      * Typically, the implementation would define additional units
      * as conversions for the convenience of developers.
@@ -124,7 +124,7 @@
      * The units are ordered from longest duration to the shortest duration
      * of the unit.
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * The list of units completely and uniquely represents the
      * state of the object without omissions, overlaps or duplication.
      * The units are in order from longest duration to shortest.
@@ -150,7 +150,7 @@
      * It is recommended to use the second approach, {@code plus(TemporalAmount)},
      * as it is a lot clearer to read in code.
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * The implementation must take the input object and add to it.
      * The implementation defines the logic of the addition and is responsible for
      * documenting that logic. It may use any method on {@code Temporal} to
@@ -192,7 +192,7 @@
      * It is recommended to use the second approach, {@code minus(TemporalAmount)},
      * as it is a lot clearer to read in code.
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * The implementation must take the input object and subtract from it.
      * The implementation defines the logic of the subtraction and is responsible for
      * documenting that logic. It may use any method on {@code Temporal} to
diff --git a/jdk/src/share/classes/java/time/temporal/TemporalField.java b/jdk/src/share/classes/java/time/temporal/TemporalField.java
index 81992b4..cce2dfb 100644
--- a/jdk/src/share/classes/java/time/temporal/TemporalField.java
+++ b/jdk/src/share/classes/java/time/temporal/TemporalField.java
@@ -82,7 +82,7 @@
  * If it is, then the date-time must handle it.
  * Otherwise, the method call is re-dispatched to the matching method in this interface.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This interface must be implemented with care to ensure other classes operate correctly.
  * All implementations that can be instantiated must be final, immutable and thread-safe.
  * Implementations should be {@code Serializable} where possible.
diff --git a/jdk/src/share/classes/java/time/temporal/TemporalQuery.java b/jdk/src/share/classes/java/time/temporal/TemporalQuery.java
index 5993778..188b13d 100644
--- a/jdk/src/share/classes/java/time/temporal/TemporalQuery.java
+++ b/jdk/src/share/classes/java/time/temporal/TemporalQuery.java
@@ -96,7 +96,7 @@
  * {@code LocalDate::from} and {@code ZoneId::from}.
  * Additional common implementations are provided on this interface as static methods.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This interface places no restrictions on the mutability of implementations,
  * however immutability is strongly recommended.
  *
@@ -124,7 +124,7 @@
      * It is recommended to use the second approach, {@code query(TemporalQuery)},
      * as it is a lot clearer to read in code.
      *
-     * <h3>Specification for implementors</h3>
+     * @implSpec
      * The implementation must take the input object and query it.
      * The implementation defines the logic of the query and is responsible for
      * documenting that logic.
diff --git a/jdk/src/share/classes/java/time/temporal/TemporalUnit.java b/jdk/src/share/classes/java/time/temporal/TemporalUnit.java
index 86e3ba8..01ab406 100644
--- a/jdk/src/share/classes/java/time/temporal/TemporalUnit.java
+++ b/jdk/src/share/classes/java/time/temporal/TemporalUnit.java
@@ -83,7 +83,7 @@
  * If it is, then the date-time must handle it.
  * Otherwise, the method call is re-dispatched to the matching method in this interface.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This interface must be implemented with care to ensure other classes operate correctly.
  * All implementations that can be instantiated must be final, immutable and thread-safe.
  * It is recommended to use an enum where possible.
@@ -197,19 +197,17 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Calculates the period in terms of this unit between two temporal objects
-     * of the same type.
+     * Calculates the amount of time between two temporal objects.
      * <p>
-     * This calculates the period between two temporals in terms of this unit.
-     * The start and end points are supplied as temporal objects and must be
-     * of the same type.
+     * This calculates the amount in terms of this unit. The start and end
+     * points are supplied as temporal objects and must be of the same type.
      * The result will be negative if the end is before the start.
-     * For example, the period in hours between two temporal objects can be
+     * For example, the amount in hours between two temporal objects can be
      * calculated using {@code HOURS.between(startTime, endTime)}.
      * <p>
      * The calculation returns a whole number, representing the number of
      * complete units between the two temporals.
-     * For example, the period in hours between the times 11:30 and 13:29
+     * For example, the amount in hours between the times 11:30 and 13:29
      * will only be one hour as it is one minute short of two hours.
      * <p>
      * There are two equivalent ways of using this method.
@@ -237,9 +235,9 @@
      *
      * @param temporal1  the base temporal object, not null
      * @param temporal2  the other temporal object, not null
-     * @return the period between temporal1 and temporal2 in terms of this unit;
+     * @return the amount of time between temporal1 and temporal2 in terms of this unit;
      *  positive if temporal2 is later than temporal1, negative if earlier
-     * @throws DateTimeException if the period cannot be calculated
+     * @throws DateTimeException if the amount cannot be calculated
      * @throws UnsupportedTemporalTypeException if the unit is not supported by the temporal
      * @throws ArithmeticException if numeric overflow occurs
      */
diff --git a/jdk/src/share/classes/java/time/temporal/UnsupportedTemporalTypeException.java b/jdk/src/share/classes/java/time/temporal/UnsupportedTemporalTypeException.java
index 4b47b0a..e4b2b12 100644
--- a/jdk/src/share/classes/java/time/temporal/UnsupportedTemporalTypeException.java
+++ b/jdk/src/share/classes/java/time/temporal/UnsupportedTemporalTypeException.java
@@ -67,7 +67,7 @@
  * UnsupportedTemporalTypeException indicates that a ChronoField or ChronoUnit is
  * not supported for a Temporal class.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is intended for use in a single thread.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/temporal/ValueRange.java b/jdk/src/share/classes/java/time/temporal/ValueRange.java
index d6e3a52..4ac8e74 100644
--- a/jdk/src/share/classes/java/time/temporal/ValueRange.java
+++ b/jdk/src/share/classes/java/time/temporal/ValueRange.java
@@ -79,7 +79,7 @@
  * <p>
  * Instances of this class are not tied to a specific field.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/temporal/WeekFields.java b/jdk/src/share/classes/java/time/temporal/WeekFields.java
index 29a1e1b..07ffa91 100644
--- a/jdk/src/share/classes/java/time/temporal/WeekFields.java
+++ b/jdk/src/share/classes/java/time/temporal/WeekFields.java
@@ -170,7 +170,8 @@
  * <tr><th>2009-01-05</th><td>Monday</td>
  *  <td>Week 2 of 2009</td><td>Week 1 of 2009</td></tr>
  * </table>
- * <h3>Specification for implementors</h3>
+ *
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
@@ -200,8 +201,6 @@
      * Note that the first week may start in the previous calendar year.
      * Note also that the first few days of a calendar year may be in the
      * week-based-year corresponding to the previous calendar year.
-     * <p>
-     * This field is an immutable and thread-safe singleton.
      */
     public static final WeekFields ISO = new WeekFields(DayOfWeek.MONDAY, 4);
 
@@ -211,8 +210,6 @@
      * <p>
      * Defined as starting on Sunday and with a minimum of 1 day in the month.
      * This week definition is in use in the US and other European countries.
-     * <p>
-     * This field is an immutable and thread-safe singleton.
      */
     public static final WeekFields SUNDAY_START = WeekFields.of(DayOfWeek.SUNDAY, 1);
 
@@ -230,7 +227,7 @@
      * In that case, the week is set to the last week of the year
      * with the same day-of-week.
      * <p>
-     * This field is an immutable and thread-safe singleton.
+     * This unit is an immutable and thread-safe singleton.
      */
     public static final TemporalUnit WEEK_BASED_YEARS = IsoFields.WEEK_BASED_YEARS;
 
@@ -247,22 +244,18 @@
      * The minimal number of days in the first week.
      */
     private final int minimalDays;
-
     /**
      * The field used to access the computed DayOfWeek.
      */
     private transient final TemporalField dayOfWeek = ComputedDayOfField.ofDayOfWeekField(this);
-
     /**
      * The field used to access the computed WeekOfMonth.
      */
     private transient final TemporalField weekOfMonth = ComputedDayOfField.ofWeekOfMonthField(this);
-
     /**
      * The field used to access the computed WeekOfYear.
      */
     private transient final TemporalField weekOfYear = ComputedDayOfField.ofWeekOfYearField(this);
-
     /**
      * The field that represents the week-of-week-based-year.
      * <p>
@@ -271,7 +264,6 @@
      * This unit is an immutable and thread-safe singleton.
      */
     private transient final TemporalField weekOfWeekBasedYear = ComputedDayOfField.ofWeekOfWeekBasedYearField(this);
-
     /**
      * The field that represents the week-based-year.
      * <p>
@@ -281,6 +273,7 @@
      */
     private transient final TemporalField weekBasedYear = ComputedDayOfField.ofWeekBasedYearField(this);
 
+    //-----------------------------------------------------------------------
     /**
      * Obtains an instance of {@code WeekFields} appropriate for a locale.
      * <p>
@@ -359,8 +352,7 @@
         try {
             return WeekFields.of(firstDayOfWeek, minimalDays);
         } catch (IllegalArgumentException iae) {
-            throw new InvalidObjectException("Invalid serialized WeekFields: "
-                    + iae.getMessage());
+            throw new InvalidObjectException("Invalid serialized WeekFields: " + iae.getMessage());
         }
     }
 
@@ -394,21 +386,24 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a field to access the day of week,
-     * computed based on this WeekFields.
+     * Returns a field to access the day of week based on this {@code WeekFields}.
      * <p>
-     * The days of week are numbered from 1 to 7.
-     * Day number 1 is the {@link #getFirstDayOfWeek() first day-of-week}.
+     * This is similar to {@link ChronoField#DAY_OF_WEEK} but uses values for
+     * the day-of-week based on this {@code WeekFields}.
+     * The days are numbered from 1 to 7 where the
+     * {@link #getFirstDayOfWeek() first day-of-week} is assigned the value 1.
+     * <p>
+     * For example, if the first day-of-week is Sunday, then that will have the
+     * value 1, with other days ranging from Monday as 2 to Saturday as 7.
      *
-     * @return the field for day-of-week using this week definition, not null
+     * @return a field providing access to the day-of-week with localized numbering, not null
      */
     public TemporalField dayOfWeek() {
         return dayOfWeek;
     }
 
     /**
-     * Returns a field to access the week of month,
-     * computed based on this WeekFields.
+     * Returns a field to access the week of month based on this {@code WeekFields}.
      * <p>
      * This represents the concept of the count of weeks within the month where weeks
      * start on a fixed day-of-week, such as Monday.
@@ -426,15 +421,15 @@
      * - if the 5th day of the month is a Monday, week two starts on the 5th and the 1st to 4th is in week one<br>
      * <p>
      * This field can be used with any calendar system.
-     * @return a TemporalField to access the WeekOfMonth, not null
+     *
+     * @return a field providing access to the week-of-month, not null
      */
     public TemporalField weekOfMonth() {
         return weekOfMonth;
     }
 
     /**
-     * Returns a field to access the week of year,
-     * computed based on this WeekFields.
+     * Returns a field to access the week of year based on this {@code WeekFields}.
      * <p>
      * This represents the concept of the count of weeks within the year where weeks
      * start on a fixed day-of-week, such as Monday.
@@ -452,15 +447,15 @@
      * - if the 5th day of the year is a Monday, week two starts on the 5th and the 1st to 4th is in week one<br>
      * <p>
      * This field can be used with any calendar system.
-     * @return a TemporalField to access the WeekOfYear, not null
+     *
+     * @return a field providing access to the week-of-year, not null
      */
     public TemporalField weekOfYear() {
         return weekOfYear;
     }
 
     /**
-     * Returns a field to access the week of a week-based-year,
-     * computed based on this WeekFields.
+     * Returns a field to access the week of a week-based-year based on this {@code WeekFields}.
      * <p>
      * This represents the concept of the count of weeks within the year where weeks
      * start on a fixed day-of-week, such as Monday and each week belongs to exactly one year.
@@ -482,15 +477,15 @@
      *   the 1st to 4th is in week one<br>
      * <p>
      * This field can be used with any calendar system.
-     * @return a TemporalField to access the week of week-based-year, not null
+     *
+     * @return a field providing access to the week-of-week-based-year, not null
      */
     public TemporalField weekOfWeekBasedYear() {
         return weekOfWeekBasedYear;
     }
 
     /**
-     * Returns a field to access the year of a week-based-year,
-     * computed based on this WeekFields.
+     * Returns a field to access the year of a week-based-year based on this {@code WeekFields}.
      * <p>
      * This represents the concept of the year where weeks start on a fixed day-of-week,
      * such as Monday and each week belongs to exactly one year.
@@ -504,14 +499,16 @@
      * is in the last week of the previous year.
      * <p>
      * This field can be used with any calendar system.
-     * @return a TemporalField to access the year of week-based-year, not null
+     *
+     * @return a field providing access to the week-based-year, not null
      */
     public TemporalField weekBasedYear() {
         return weekBasedYear;
     }
 
+    //-----------------------------------------------------------------------
     /**
-     * Checks if this WeekFields is equal to the specified object.
+     * Checks if this {@code WeekFields} is equal to the specified object.
      * <p>
      * The comparison is based on the entire state of the rules, which is
      * the first day-of-week and minimal days.
@@ -531,7 +528,7 @@
     }
 
     /**
-     * A hash code for these rules.
+     * A hash code for this {@code WeekFields}.
      *
      * @return a suitable hash code
      */
@@ -542,7 +539,7 @@
 
     //-----------------------------------------------------------------------
     /**
-     * A string representation of this definition.
+     * A string representation of this {@code WeekFields} instance.
      *
      * @return the string representation, not null
      */
@@ -957,7 +954,6 @@
         /**
          * Map the field range to a week range of a week year.
          * @param temporal  the temporal
-         * @param field  the field to get the range of
          * @return the ValueRange with the range adjusted to weeks.
          */
         private ValueRange rangeWeekOfWeekBasedYear(TemporalAccessor temporal) {
diff --git a/jdk/src/share/classes/java/time/zone/Ser.java b/jdk/src/share/classes/java/time/zone/Ser.java
index 7d5c0c6..e341264 100644
--- a/jdk/src/share/classes/java/time/zone/Ser.java
+++ b/jdk/src/share/classes/java/time/zone/Ser.java
@@ -74,7 +74,7 @@
 /**
  * The shared serialization delegate for this package.
  *
- * <h3>Implementation notes</h3>
+ * @implNote
  * This class is mutable and should be created once per serialization.
  *
  * @serial include
diff --git a/jdk/src/share/classes/java/time/zone/ZoneOffsetTransition.java b/jdk/src/share/classes/java/time/zone/ZoneOffsetTransition.java
index 1b5810b..f2eab7c 100644
--- a/jdk/src/share/classes/java/time/zone/ZoneOffsetTransition.java
+++ b/jdk/src/share/classes/java/time/zone/ZoneOffsetTransition.java
@@ -89,7 +89,7 @@
  * An example would be when the offset changes from {@code +04:00} to {@code +03:00}.
  * This might be described as 'the clocks will move back one hour tonight at 2am'.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/zone/ZoneOffsetTransitionRule.java b/jdk/src/share/classes/java/time/zone/ZoneOffsetTransitionRule.java
index bb1b79f..ad52f82 100644
--- a/jdk/src/share/classes/java/time/zone/ZoneOffsetTransitionRule.java
+++ b/jdk/src/share/classes/java/time/zone/ZoneOffsetTransitionRule.java
@@ -90,7 +90,7 @@
  * </ul><p>
  * These different rule types can be expressed and queried.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/zone/ZoneRules.java b/jdk/src/share/classes/java/time/zone/ZoneRules.java
index fa7498c..070ad6e 100644
--- a/jdk/src/share/classes/java/time/zone/ZoneRules.java
+++ b/jdk/src/share/classes/java/time/zone/ZoneRules.java
@@ -100,7 +100,7 @@
  * Applications should treat the data provided as representing the best information
  * available to the implementation of this rule.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is immutable and thread-safe.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/zone/ZoneRulesException.java b/jdk/src/share/classes/java/time/zone/ZoneRulesException.java
index e965af0..2c845ca 100644
--- a/jdk/src/share/classes/java/time/zone/ZoneRulesException.java
+++ b/jdk/src/share/classes/java/time/zone/ZoneRulesException.java
@@ -64,7 +64,7 @@
  * This exception is used to indicate a problems with the configured
  * time-zone rules.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This class is intended for use in a single thread.
  *
  * @since 1.8
diff --git a/jdk/src/share/classes/java/time/zone/ZoneRulesProvider.java b/jdk/src/share/classes/java/time/zone/ZoneRulesProvider.java
index 5c88e3e..9523664 100644
--- a/jdk/src/share/classes/java/time/zone/ZoneRulesProvider.java
+++ b/jdk/src/share/classes/java/time/zone/ZoneRulesProvider.java
@@ -111,7 +111,7 @@
  * Each provider will provide the latest rules for each zone ID, but they
  * may also provide the history of how the rules changed.
  *
- * <h3>Specification for implementors</h3>
+ * @implSpec
  * This interface is a service provider that can be called by multiple threads.
  * Implementations must be immutable and thread-safe.
  * <p>
diff --git a/jdk/src/share/classes/java/util/AbstractCollection.java b/jdk/src/share/classes/java/util/AbstractCollection.java
index 3c7a692..dcdd140 100644
--- a/jdk/src/share/classes/java/util/AbstractCollection.java
+++ b/jdk/src/share/classes/java/util/AbstractCollection.java
@@ -368,6 +368,7 @@
      * @see #contains(Object)
      */
     public boolean removeAll(Collection<?> c) {
+        Objects.requireNonNull(c);
         boolean modified = false;
         Iterator<?> it = iterator();
         while (it.hasNext()) {
@@ -401,6 +402,7 @@
      * @see #contains(Object)
      */
     public boolean retainAll(Collection<?> c) {
+        Objects.requireNonNull(c);
         boolean modified = false;
         Iterator<E> it = iterator();
         while (it.hasNext()) {
diff --git a/jdk/src/share/classes/java/util/AbstractSet.java b/jdk/src/share/classes/java/util/AbstractSet.java
index 91d9fb6..6dc2f52 100644
--- a/jdk/src/share/classes/java/util/AbstractSet.java
+++ b/jdk/src/share/classes/java/util/AbstractSet.java
@@ -166,6 +166,7 @@
      * @see #contains(Object)
      */
     public boolean removeAll(Collection<?> c) {
+        Objects.requireNonNull(c);
         boolean modified = false;
 
         if (size() > c.size()) {
diff --git a/jdk/src/share/classes/java/util/ArrayList.java b/jdk/src/share/classes/java/util/ArrayList.java
index 775f357..2211cc8 100644
--- a/jdk/src/share/classes/java/util/ArrayList.java
+++ b/jdk/src/share/classes/java/util/ArrayList.java
@@ -671,6 +671,7 @@
      * @see Collection#contains(Object)
      */
     public boolean removeAll(Collection<?> c) {
+        Objects.requireNonNull(c);
         return batchRemove(c, false);
     }
 
@@ -691,6 +692,7 @@
      * @see Collection#contains(Object)
      */
     public boolean retainAll(Collection<?> c) {
+        Objects.requireNonNull(c);
         return batchRemove(c, true);
     }
 
@@ -874,7 +876,8 @@
                 consumer.accept((E) elementData[i++]);
             }
             // update once at end of iteration to reduce heap write traffic
-            lastRet = cursor = i;
+            cursor = i;
+            lastRet = i - 1;
             checkForComodification();
         }
 
diff --git a/jdk/src/share/classes/java/util/Base64.java b/jdk/src/share/classes/java/util/Base64.java
index b9504e2..2dbaf92 100644
--- a/jdk/src/share/classes/java/util/Base64.java
+++ b/jdk/src/share/classes/java/util/Base64.java
@@ -625,7 +625,8 @@
      * character(s) padded), they are decoded as if followed by padding
      * character(s). If there is padding character present in the
      * final unit, the correct number of padding character(s) must be
-     * present, otherwise {@code IllegalArgumentException} is thrown
+     * present, otherwise {@code IllegalArgumentException} (
+     * {@code IOException} when reading from a Base64 stream) is thrown
      * during decoding.
      *
      * <p> Instances of {@link Decoder} class are safe for use by
@@ -1306,7 +1307,12 @@
                         return off - oldOff;
                 }
                 if (v == '=') {                  // padding byte(s)
-                    if (nextin != 6 && nextin != 0) {
+                    // =     shiftto==18 unnecessary padding
+                    // x=    shiftto==12 invalid unit
+                    // xx=   shiftto==6 && missing last '='
+                    // xx=y                or last is not '='
+                    if (nextin == 18 || nextin == 12 ||
+                        nextin == 6 && is.read() != '=') {
                         throw new IOException("Illegal base64 ending sequence:" + nextin);
                     }
                     b[off++] = (byte)(bits >> (16));
diff --git a/jdk/src/share/classes/java/util/BitSet.java b/jdk/src/share/classes/java/util/BitSet.java
index dc63a26..56faccc 100644
--- a/jdk/src/share/classes/java/util/BitSet.java
+++ b/jdk/src/share/classes/java/util/BitSet.java
@@ -29,6 +29,8 @@
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.LongBuffer;
+import java.util.stream.IntStream;
+import java.util.stream.StreamSupport;
 
 /**
  * This class implements a vector of bits that grows as needed. Each
@@ -1188,4 +1190,47 @@
         b.append('}');
         return b.toString();
     }
+
+    /**
+     * Returns a stream of indices for which this {@code BitSet}
+     * contains a bit in the set state. The indices are returned
+     * in order, from lowest to highest. The size of the stream
+     * is the number of bits in the set state, equal to the value
+     * returned by the {@link #cardinality()} method.
+     *
+     * <p>The bit set must remain constant during the execution of the
+     * terminal stream operation.  Otherwise, the result of the terminal
+     * stream operation is undefined.
+     *
+     * @return a stream of integers representing set indices
+     * @since 1.8
+     */
+    public IntStream stream() {
+        class BitSetIterator implements PrimitiveIterator.OfInt {
+            int next = nextSetBit(0);
+
+            @Override
+            public boolean hasNext() {
+                return next != -1;
+            }
+
+            @Override
+            public int nextInt() {
+                if (next != -1) {
+                    int ret = next;
+                    next = nextSetBit(next+1);
+                    return ret;
+                } else {
+                    throw new NoSuchElementException();
+                }
+            }
+        }
+
+        return StreamSupport.intStream(
+                () -> Spliterators.spliterator(
+                        new BitSetIterator(), cardinality(),
+                        Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED),
+                Spliterator.SIZED | Spliterator.SUBSIZED |
+                        Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED);
+    }
 }
diff --git a/jdk/src/share/classes/java/util/JapaneseImperialCalendar.java b/jdk/src/share/classes/java/util/JapaneseImperialCalendar.java
index ed95f96..e37374a 100644
--- a/jdk/src/share/classes/java/util/JapaneseImperialCalendar.java
+++ b/jdk/src/share/classes/java/util/JapaneseImperialCalendar.java
@@ -249,11 +249,14 @@
             CalendarDate transitionDate = eras[i].getSinceDate();
             date.setDate(transitionDate.getYear(), BaseCalendar.JANUARY, 1);
             long fdd = gcal.getFixedDate(date);
-            dayOfYear = Math.min((int)(fdd - fd), dayOfYear);
+            if (fd != fdd) {
+                dayOfYear = Math.min((int)(fd - fdd) + 1, dayOfYear);
+            }
             date.setDate(transitionDate.getYear(), BaseCalendar.DECEMBER, 31);
-            fdd = gcal.getFixedDate(date) + 1;
-            dayOfYear = Math.min((int)(fd - fdd), dayOfYear);
-
+            fdd = gcal.getFixedDate(date);
+            if (fd != fdd) {
+                dayOfYear = Math.min((int)(fdd - fd) + 1, dayOfYear);
+            }
             LocalGregorianCalendar.Date lgd = getCalendarDate(fd - 1);
             int y = lgd.getYear();
             // Unless the first year starts from January 1, the actual
diff --git a/jdk/src/share/classes/java/util/LinkedList.java b/jdk/src/share/classes/java/util/LinkedList.java
index 658d38f..54297d9 100644
--- a/jdk/src/share/classes/java/util/LinkedList.java
+++ b/jdk/src/share/classes/java/util/LinkedList.java
@@ -954,10 +954,10 @@
             Objects.requireNonNull(action);
             while (modCount == expectedModCount && nextIndex < size) {
                 action.accept(next.item);
+                lastReturned = next;
                 next = next.next;
                 nextIndex++;
             }
-            lastReturned = next;
             checkForComodification();
         }
 
diff --git a/jdk/src/share/classes/java/util/Objects.java b/jdk/src/share/classes/java/util/Objects.java
index 8052e05..e526079 100644
--- a/jdk/src/share/classes/java/util/Objects.java
+++ b/jdk/src/share/classes/java/util/Objects.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -25,6 +25,8 @@
 
 package java.util;
 
+import java.util.function.Supplier;
+
 /**
  * This class consists of {@code static} utility methods for operating
  * on objects.  These utilities include {@code null}-safe or {@code
@@ -226,4 +228,66 @@
             throw new NullPointerException(message);
         return obj;
     }
+
+    /**
+     * Returns {@code true} if the provided reference is {@code null} otherwise
+     * returns {@code false}.
+     *
+     * @apiNote This method exists to be used as a
+     * {@link java.util.function.Predicate}, {@code filter(Objects::isNull)}
+     *
+     * @param obj a reference to be checked against {@code null}
+     * @return {@code true} if the provided reference is {@code null} otherwise
+     * {@code false}
+     *
+     * @see java.util.function.Predicate
+     * @since 1.8
+     */
+    public static boolean isNull(Object obj) {
+        return obj == null;
+    }
+
+    /**
+     * Returns {@code true} if the provided reference is non-{@code null}
+     * otherwise returns {@code false}.
+     *
+     * @apiNote This method exists to be used as a
+     * {@link java.util.function.Predicate}, {@code filter(Objects::nonNull)}
+     *
+     * @param obj a reference to be checked against {@code null}
+     * @return {@code true} if the provided reference is non-{@code null}
+     * otherwise {@code false}
+     *
+     * @see java.util.function.Predicate
+     * @since 1.8
+     */
+    public static boolean nonNull(Object obj) {
+        return obj != null;
+    }
+
+    /**
+     * Checks that the specified object reference is not {@code null} and
+     * throws a customized {@link NullPointerException} if it is.
+     *
+     * <p>Unlike the method {@link #requireNonNull(Object, String)},
+     * this method allows creation of the message to be deferred until
+     * after the null check is made. While this may confer a
+     * performance advantage in the non-null case, when deciding to
+     * call this method care should be taken that the costs of
+     * creating the message supplier are less than the cost of just
+     * creating the string message directly.
+     *
+     * @param obj     the object reference to check for nullity
+     * @param messageSupplier supplier of the detail message to be
+     * used in the event that a {@code NullPointerException} is thrown
+     * @param <T> the type of the reference
+     * @return {@code obj} if not {@code null}
+     * @throws NullPointerException if {@code obj} is {@code null}
+     * @since 1.8
+     */
+    public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier) {
+        if (obj == null)
+            throw new NullPointerException(messageSupplier.get());
+        return obj;
+    }
 }
diff --git a/jdk/src/share/classes/java/util/Random.java b/jdk/src/share/classes/java/util/Random.java
index 6e87e3a..c169e05 100644
--- a/jdk/src/share/classes/java/util/Random.java
+++ b/jdk/src/share/classes/java/util/Random.java
@@ -26,6 +26,10 @@
 package java.util;
 import java.io.*;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+
 import sun.misc.Unsafe;
 
 /**
@@ -513,6 +517,59 @@
     }
 
     /**
+     * Returns a stream of pseudorandom, uniformly distributed
+     * {@code integer} values from this random number generator's
+     * sequence. Values are obtained as needed by calling
+     * {@link #nextInt()}.
+     *
+     * @return an infinite stream of {@code integer} values
+     * @since 1.8
+     */
+    public IntStream ints() {
+        return IntStream.generate(this::nextInt);
+    }
+
+    /**
+     * Returns a stream of pseudorandom, uniformly distributed
+     * {@code long} values from this random number generator's
+     * sequence. Values are obtained as needed by calling
+     * {@link #nextLong()}.
+     *
+     * @return an infinite stream of {@code long} values
+     * @since 1.8
+     */
+    public LongStream longs() {
+        return LongStream.generate(this::nextLong);
+    }
+
+    /**
+     * Returns a stream of pseudorandom, uniformly distributed
+     * {@code double} values between {@code 0.0} and {@code 1.0}
+     * from this random number generator's sequence. Values are
+     * obtained as needed by calling {@link #nextDouble()}.
+     *
+     * @return an infinite stream of {@code double} values
+     * @since 1.8
+     */
+    public DoubleStream doubles() {
+        return DoubleStream.generate(this::nextDouble);
+    }
+
+    /**
+     * Returns a stream of pseudorandom, Gaussian ("normally")
+     * distributed {@code double} values with mean {@code 0.0}
+     * and standard deviation {@code 1.0} from this random number
+     * generator's sequence. Values are obtained as needed by
+     * calling {@link #nextGaussian()}.
+     *
+     * @return an infinite stream of {@code double} values
+     * @since 1.8
+     */
+    public DoubleStream gaussians() {
+        return DoubleStream.generate(this::nextGaussian);
+    }
+
+    /**
      * Serializable fields for Random.
      *
      * @serialField    seed long
diff --git a/jdk/src/share/classes/java/util/Vector.java b/jdk/src/share/classes/java/util/Vector.java
index f5007ae..fc3a1f7 100644
--- a/jdk/src/share/classes/java/util/Vector.java
+++ b/jdk/src/share/classes/java/util/Vector.java
@@ -1172,7 +1172,8 @@
                     action.accept((E) elementData[i++]);
                 }
                 // update once at end of iteration to reduce heap write traffic
-                lastRet = cursor = i;
+                cursor = i;
+                lastRet = i - 1;
                 checkForComodification();
             }
         }
diff --git a/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java b/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java
index c19d512..0532d3d 100644
--- a/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java
+++ b/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java
@@ -39,6 +39,9 @@
 import java.util.Random;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
 
 /**
  * A random number generator isolated to the current thread.  Like the
@@ -241,6 +244,26 @@
         return offset + nextInt((int) n);
     }
 
+    @Override
+    public IntStream ints() {
+        return IntStream.generate(() -> current().nextInt());
+    }
+
+    @Override
+    public LongStream longs() {
+        return LongStream.generate(() -> current().nextLong());
+    }
+
+    @Override
+    public DoubleStream doubles() {
+        return DoubleStream.generate(() -> current().nextDouble());
+    }
+
+    @Override
+    public DoubleStream gaussians() {
+        return DoubleStream.generate(() -> current().nextGaussian());
+    }
+
     /**
      * Returns a pseudorandom, uniformly distributed value between the
      * given least value (inclusive) and bound (exclusive).
diff --git a/jdk/src/share/classes/java/util/jar/JarFile.java b/jdk/src/share/classes/java/util/jar/JarFile.java
index 84c0375..a70be7a 100644
--- a/jdk/src/share/classes/java/util/jar/JarFile.java
+++ b/jdk/src/share/classes/java/util/jar/JarFile.java
@@ -29,6 +29,8 @@
 import java.lang.ref.SoftReference;
 import java.net.URL;
 import java.util.*;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
 import java.util.zip.*;
 import java.security.CodeSigner;
 import java.security.cert.Certificate;
@@ -235,20 +237,42 @@
         return null;
     }
 
+    private class JarEntryIterator implements Enumeration<JarEntry>,
+            Iterator<JarEntry>
+    {
+        final Enumeration<? extends ZipEntry> e = JarFile.super.entries();
+
+        public boolean hasNext() {
+            return e.hasMoreElements();
+        }
+
+        public JarEntry next() {
+            ZipEntry ze = e.nextElement();
+            return new JarFileEntry(ze);
+        }
+
+        public boolean hasMoreElements() {
+            return hasNext();
+        }
+
+        public JarEntry nextElement() {
+            return next();
+        }
+    }
+
     /**
      * Returns an enumeration of the zip file entries.
      */
     public Enumeration<JarEntry> entries() {
-        final Enumeration<? extends ZipEntry> enum_ = super.entries();
-        return new Enumeration<JarEntry>() {
-            public boolean hasMoreElements() {
-                return enum_.hasMoreElements();
-            }
-            public JarFileEntry nextElement() {
-                ZipEntry ze = enum_.nextElement();
-                return new JarFileEntry(ze);
-            }
-        };
+        return new JarEntryIterator();
+    }
+
+    @Override
+    public Stream<JarEntry> stream() {
+        return StreamSupport.stream(Spliterators.spliterator(
+                new JarEntryIterator(), size(),
+                Spliterator.ORDERED | Spliterator.DISTINCT |
+                        Spliterator.IMMUTABLE | Spliterator.NONNULL));
     }
 
     private class JarFileEntry extends JarEntry {
diff --git a/jdk/src/share/classes/java/util/logging/LogManager.java b/jdk/src/share/classes/java/util/logging/LogManager.java
index 8545e47..387b335 100644
--- a/jdk/src/share/classes/java/util/logging/LogManager.java
+++ b/jdk/src/share/classes/java/util/logging/LogManager.java
@@ -433,11 +433,11 @@
     // add a new Logger or return the one that has been added previously
     // as a LogManager subclass may override the addLogger, getLogger,
     // readConfiguration, and other methods.
-    Logger demandLogger(String name, String resourceBundleName) {
+    Logger demandLogger(String name, String resourceBundleName, Class<?> caller) {
         Logger result = getLogger(name);
         if (result == null) {
             // only allocate the new logger once
-            Logger newLogger = new Logger(name, resourceBundleName);
+            Logger newLogger = new Logger(name, resourceBundleName, caller);
             do {
                 if (addLogger(newLogger)) {
                     // We successfully added the new Logger that we
@@ -519,7 +519,7 @@
         Logger demandLogger(String name, String resourceBundleName) {
             // a LogManager subclass may have its own implementation to add and
             // get a Logger.  So delegate to the LogManager to do the work.
-            return manager.demandLogger(name, resourceBundleName);
+            return manager.demandLogger(name, resourceBundleName, null);
         }
 
         synchronized Logger findLogger(String name) {
diff --git a/jdk/src/share/classes/java/util/logging/Logger.java b/jdk/src/share/classes/java/util/logging/Logger.java
index 20bba26..11b0c0c 100644
--- a/jdk/src/share/classes/java/util/logging/Logger.java
+++ b/jdk/src/share/classes/java/util/logging/Logger.java
@@ -191,8 +191,6 @@
  *
  * @since 1.4
  */
-
-
 public class Logger {
     private static final Handler emptyHandlers[] = new Handler[0];
     private static final int offValue = Level.OFF.intValue();
@@ -218,6 +216,7 @@
     private ArrayList<LogManager.LoggerWeakRef> kids;   // WeakReferences to loggers that have us as parent
     private volatile Level levelObject;
     private volatile int levelValue;  // current effective level value
+    private WeakReference<ClassLoader> callersClassLoaderRef;
 
     /**
      * GLOBAL_LOGGER_NAME is a name for the global logger.
@@ -278,18 +277,31 @@
      *             no corresponding resource can be found.
      */
     protected Logger(String name, String resourceBundleName) {
+        this(name, resourceBundleName, null);
+    }
+
+    Logger(String name, String resourceBundleName, Class<?> caller) {
         this.manager = LogManager.getLogManager();
-        if (resourceBundleName != null) {
-            // MissingResourceException or IllegalArgumentException can
-            // be thrown by setupResourceInfo(). Since this is the Logger
-            // constructor, the resourceBundleName field is null so
-            // IllegalArgumentException cannot happen here.
-            setupResourceInfo(resourceBundleName);
-        }
+        setupResourceInfo(resourceBundleName, caller);
         this.name = name;
         levelValue = Level.INFO.intValue();
     }
 
+    private void setCallersClassLoaderRef(Class<?> caller) {
+        ClassLoader callersClassLoader = ((caller != null)
+                                         ? caller.getClassLoader()
+                                         : null);
+        if (callersClassLoader != null) {
+            this.callersClassLoaderRef = new WeakReference(callersClassLoader);
+        }
+    }
+
+    private ClassLoader getCallersClassLoader() {
+        return (callersClassLoaderRef != null)
+                ? callersClassLoaderRef.get()
+                : null;
+    }
+
     // This constructor is used only to create the global Logger.
     // It is needed to break a cyclic dependence between the LogManager
     // and Logger static initializers causing deadlocks.
@@ -343,7 +355,9 @@
                 return manager.demandSystemLogger(name, resourceBundleName);
             }
         }
-        return manager.demandLogger(name, resourceBundleName);
+        return manager.demandLogger(name, resourceBundleName, caller);
+        // ends up calling new Logger(name, resourceBundleName, caller)
+        // iff the logger doesn't exist already
     }
 
     /**
@@ -436,11 +450,19 @@
     // adding a new Logger object is handled by LogManager.addLogger().
     @CallerSensitive
     public static Logger getLogger(String name, String resourceBundleName) {
-        Logger result = demandLogger(name, resourceBundleName, Reflection.getCallerClass());
+        Class<?> callerClass = Reflection.getCallerClass();
+        Logger result = demandLogger(name, resourceBundleName, callerClass);
 
         // MissingResourceException or IllegalArgumentException can be
         // thrown by setupResourceInfo().
-        result.setupResourceInfo(resourceBundleName);
+        // We have to set the callers ClassLoader here in case demandLogger
+        // above found a previously created Logger.  This can happen, for
+        // example, if Logger.getLogger(name) is called and subsequently
+        // Logger.getLogger(name, resourceBundleName) is called.  In this case
+        // we won't necessarily have the correct classloader saved away, so
+        // we need to set it here, too.
+
+        result.setupResourceInfo(resourceBundleName, callerClass);
         return result;
     }
 
@@ -507,11 +529,13 @@
 
     // Synchronization is not required here. All synchronization for
     // adding a new anonymous Logger object is handled by doSetParent().
+    @CallerSensitive
     public static Logger getAnonymousLogger(String resourceBundleName) {
         LogManager manager = LogManager.getLogManager();
         // cleanup some Loggers that have been GC'ed
         manager.drainLoggerRefQueueBounded();
-        Logger result = new Logger(null, resourceBundleName);
+        Logger result = new Logger(null, resourceBundleName,
+                                   Reflection.getCallerClass());
         result.anonymous = true;
         Logger root = manager.getLogger("");
         result.doSetParent(root);
@@ -527,7 +551,7 @@
      * @return localization bundle (may be null)
      */
     public ResourceBundle getResourceBundle() {
-        return findResourceBundle(getResourceBundleName());
+        return findResourceBundle(getResourceBundleName(), true);
     }
 
     /**
@@ -609,7 +633,7 @@
         String ebname = getEffectiveResourceBundleName();
         if (ebname != null && !ebname.equals(SYSTEM_LOGGER_RB_NAME)) {
             lr.setResourceBundleName(ebname);
-            lr.setResourceBundle(findResourceBundle(ebname));
+            lr.setResourceBundle(findResourceBundle(ebname, true));
         }
         log(lr);
     }
@@ -936,7 +960,7 @@
         lr.setLoggerName(name);
         if (rbname != null) {
             lr.setResourceBundleName(rbname);
-            lr.setResourceBundle(findResourceBundle(rbname));
+            lr.setResourceBundle(findResourceBundle(rbname, false));
         }
         log(lr);
     }
@@ -960,7 +984,6 @@
      *                         can be null
      * @param   msg     The string message (or a key in the message catalog)
      */
-
     public void logrb(Level level, String sourceClass, String sourceMethod,
                                 String bundleName, String msg) {
         if (level.intValue() < levelValue || levelValue == offValue) {
@@ -1609,9 +1632,18 @@
      * there is no suitable previous cached value.
      *
      * @param name the ResourceBundle to locate
+     * @param userCallersClassLoader if true search using the caller's ClassLoader
      * @return ResourceBundle specified by name or null if not found
      */
-    private synchronized ResourceBundle findResourceBundle(String name) {
+    private synchronized ResourceBundle findResourceBundle(String name,
+                                                           boolean useCallersClassLoader) {
+        // For all lookups, we first check the thread context class loader
+        // if it is set.  If not, we use the system classloader.  If we
+        // still haven't found it we use the callersClassLoaderRef if it
+        // is set and useCallersClassLoader is true.  We set
+        // callersClassLoaderRef initially upon creating the logger with a
+        // non-null resource bundle name.
+
         // Return a null bundle for a null name.
         if (name == null) {
             return null;
@@ -1644,17 +1676,40 @@
             catalogLocale = currentLocale;
             return catalog;
         } catch (MissingResourceException ex) {
+            // We can't find the ResourceBundle in the default
+            // ClassLoader.  Drop through.
+        }
+
+        if (useCallersClassLoader) {
+            // Try with the caller's ClassLoader
+            ClassLoader callersClassLoader = getCallersClassLoader();
+
+            if (callersClassLoader == null || callersClassLoader == cl) {
+                return null;
+            }
+
+            try {
+                catalog = ResourceBundle.getBundle(name, currentLocale,
+                                                   callersClassLoader);
+                catalogName = name;
+                catalogLocale = currentLocale;
+                return catalog;
+            } catch (MissingResourceException ex) {
+                return null; // no luck
+            }
+        } else {
             return null;
         }
     }
 
     // Private utility method to initialize our one entry
-    // resource bundle name cache.
+    // resource bundle name cache and the callers ClassLoader
     // Note: for consistency reasons, we are careful to check
     // that a suitable ResourceBundle exists before setting the
     // resourceBundleName field.
-    // Synchronized to prevent races in setting the field.
-    private synchronized void setupResourceInfo(String name) {
+    // Synchronized to prevent races in setting the fields.
+    private synchronized void setupResourceInfo(String name,
+                                                Class<?> callersClass) {
         if (name == null) {
             return;
         }
@@ -1672,9 +1727,14 @@
                 resourceBundleName + " != " + name);
         }
 
-        if (findResourceBundle(name) == null) {
+        setCallersClassLoaderRef(callersClass);
+        if (findResourceBundle(name, true) == null) {
             // We've failed to find an expected ResourceBundle.
-            throw new MissingResourceException("Can't find " + name + " bundle", name, "");
+            // unset the caller's ClassLoader since we were unable to find the
+            // the bundle using it
+            this.callersClassLoaderRef = null;
+            throw new MissingResourceException("Can't find " + name + " bundle",
+                                                name, "");
         }
         resourceBundleName = name;
     }
diff --git a/jdk/src/share/classes/java/util/regex/Matcher.java b/jdk/src/share/classes/java/util/regex/Matcher.java
index fb1cca4..b01ec84 100644
--- a/jdk/src/share/classes/java/util/regex/Matcher.java
+++ b/jdk/src/share/classes/java/util/regex/Matcher.java
@@ -25,6 +25,7 @@
 
 package java.util.regex;
 
+import java.util.Objects;
 
 /**
  * An engine that performs match operations on a {@link java.lang.CharSequence
@@ -370,12 +371,37 @@
     public int start(int group) {
         if (first < 0)
             throw new IllegalStateException("No match available");
-        if (group > groupCount())
+        if (group < 0 || group > groupCount())
             throw new IndexOutOfBoundsException("No group " + group);
         return groups[group * 2];
     }
 
     /**
+     * Returns the start index of the subsequence captured by the given
+     * <a href="Pattern.html#groupname">named-capturing group</a> during the
+     * previous match operation.
+     *
+     * @param  name
+     *         The name of a named-capturing group in this matcher's pattern
+     *
+     * @return  The index of the first character captured by the group,
+     *          or {@code -1} if the match was successful but the group
+     *          itself did not match anything
+     *
+     * @throws  IllegalStateException
+     *          If no match has yet been attempted,
+     *          or if the previous match operation failed
+     *
+     * @throws  IllegalArgumentException
+     *          If there is no capturing group in the pattern
+     *          with the given name
+     * @since 1.8
+     */
+    public int start(String name) {
+        return groups[getMatchedGroupIndex(name) * 2];
+    }
+
+    /**
      * Returns the offset after the last character matched.  </p>
      *
      * @return  The offset after the last character matched
@@ -417,12 +443,37 @@
     public int end(int group) {
         if (first < 0)
             throw new IllegalStateException("No match available");
-        if (group > groupCount())
+        if (group < 0 || group > groupCount())
             throw new IndexOutOfBoundsException("No group " + group);
         return groups[group * 2 + 1];
     }
 
     /**
+     * Returns the offset after the last character of the subsequence
+     * captured by the given <a href="Pattern.html#groupname">named-capturing
+     * group</a> during the previous match operation.
+     *
+     * @param  name
+     *         The name of a named-capturing group in this matcher's pattern
+     *
+     * @return  The offset after the last character captured by the group,
+     *          or {@code -1} if the match was successful
+     *          but the group itself did not match anything
+     *
+     * @throws  IllegalStateException
+     *          If no match has yet been attempted,
+     *          or if the previous match operation failed
+     *
+     * @throws  IllegalArgumentException
+     *          If there is no capturing group in the pattern
+     *          with the given name
+     * @since 1.8
+     */
+    public int end(String name) {
+        return groups[getMatchedGroupIndex(name) * 2 + 1];
+    }
+
+    /**
      * Returns the input subsequence matched by the previous match.
      *
      * <p> For a matcher <i>m</i> with input sequence <i>s</i>,
@@ -518,13 +569,7 @@
      * @since 1.7
      */
     public String group(String name) {
-        if (name == null)
-            throw new NullPointerException("Null group name");
-        if (first < 0)
-            throw new IllegalStateException("No match found");
-        if (!parentPattern.namedGroups().containsKey(name))
-            throw new IllegalArgumentException("No group with name <" + name + ">");
-        int group = parentPattern.namedGroups().get(name);
+        int group = getMatchedGroupIndex(name);
         if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
             return null;
         return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
@@ -1257,4 +1302,17 @@
         return text.charAt(i);
     }
 
+    /**
+     * Returns the group index of the matched capturing group.
+     *
+     * @return the index of the named-capturing group
+     */
+    int getMatchedGroupIndex(String name) {
+        Objects.requireNonNull(name, "Group name");
+        if (first < 0)
+            throw new IllegalStateException("No match found");
+        if (!parentPattern.namedGroups().containsKey(name))
+            throw new IllegalArgumentException("No group with name <" + name + ">");
+        return parentPattern.namedGroups().get(name);
+    }
 }
diff --git a/jdk/src/share/classes/java/util/regex/Pattern.java b/jdk/src/share/classes/java/util/regex/Pattern.java
index 529b07c..14cde68 100644
--- a/jdk/src/share/classes/java/util/regex/Pattern.java
+++ b/jdk/src/share/classes/java/util/regex/Pattern.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -25,15 +25,19 @@
 
 package java.util.regex;
 
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.text.CharacterIterator;
 import java.text.Normalizer;
 import java.util.Locale;
+import java.util.Iterator;
 import java.util.Map;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Arrays;
+import java.util.NoSuchElementException;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
 
 
 /**
@@ -612,6 +616,7 @@
  *   <li> White_Space
  *   <li> Digit
  *   <li> Hex_Digit
+ *   <li> Join_Control
  *   <li> Noncharacter_Code_Point
  *   <li> Assigned
  * </ul>
@@ -662,7 +667,7 @@
  * <tr><td><tt>\S</tt></td>
  *     <td>A non-whitespace character: <tt>[^\s]</tt></td></tr>
  * <tr><td><tt>\w</tt></td>
- *     <td>A word character: <tt>[\p{Alpha}\p{gc=Mn}\p{gc=Me}\p{gc=Mc}\p{Digit}\p{gc=Pc}]</tt></td></tr>
+ *     <td>A word character: <tt>[\p{Alpha}\p{gc=Mn}\p{gc=Me}\p{gc=Mc}\p{Digit}\p{gc=Pc}\p{IsJoin_Control}]</tt></td></tr>
  * <tr><td><tt>\W</tt></td>
  *     <td>A non-word character: <tt>[^\w]</tt></td></tr>
  * </table>
@@ -5741,4 +5746,83 @@
                     return Character.isMirrored(ch);}});
         }
     }
+
+    /**
+     * Creates a predicate which can be used to match a string.
+     *
+     * @return  The predicate which can be used for matching on a string
+     * @since   1.8
+     */
+    public Predicate<String> asPredicate() {
+        return s -> matcher(s).find();
+    }
+
+    /**
+     * Creates a stream from the given input sequence around matches of this
+     * pattern.
+     *
+     * <p> The stream returned by this method contains each substring of the
+     * input sequence that is terminated by another subsequence that matches
+     * this pattern or is terminated by the end of the input sequence.  The
+     * substrings in the stream are in the order in which they occur in the
+     * input.
+     *
+     * <p> If this pattern does not match any subsequence of the input then
+     * the resulting stream has just one element, namely the input sequence in
+     * string form.
+     *
+     * <p> If the input sequence is mutable, it must remain constant during the
+     * execution of the terminal stream operation.  Otherwise, the result of the
+     * terminal stream operation is undefined.
+     *
+     * @param   input
+     *          The character sequence to be split
+     *
+     * @return  The stream of strings computed by splitting the input
+     *          around matches of this pattern
+     * @see     #split(CharSequence)
+     * @since   1.8
+     */
+    public Stream<String> splitAsStream(final CharSequence input) {
+        class MatcherIterator implements Iterator<String> {
+            private final Matcher matcher;
+            // The start position of the next sub-sequence of input
+            // when current == input.length there are no more elements
+            private int current;
+            // null if the next element, if any, needs to obtained
+            private String nextElement;
+
+            MatcherIterator() {
+                this.matcher = matcher(input);
+            }
+
+            public String next() {
+                if (!hasNext())
+                    throw new NoSuchElementException();
+
+                String n = nextElement;
+                nextElement = null;
+                return n;
+            }
+
+            public boolean hasNext() {
+                if (nextElement != null)
+                    return true;
+
+                if (current == input.length())
+                    return false;
+
+                if (matcher.find()) {
+                    nextElement = input.subSequence(current, matcher.start()).toString();
+                    current = matcher.end();
+                } else {
+                    nextElement = input.subSequence(current, input.length()).toString();
+                    current = input.length();
+                }
+                return true;
+            }
+        }
+        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
+                new MatcherIterator(), Spliterator.ORDERED | Spliterator.NONNULL));
+    }
 }
diff --git a/jdk/src/share/classes/java/util/regex/UnicodeProp.java b/jdk/src/share/classes/java/util/regex/UnicodeProp.java
index d1a68c0..2c7c128 100644
--- a/jdk/src/share/classes/java/util/regex/UnicodeProp.java
+++ b/jdk/src/share/classes/java/util/regex/UnicodeProp.java
@@ -181,6 +181,7 @@
         //  \p{gc=Mark}
         //  \p{digit}
         //  \p{gc=Connector_Punctuation}
+        //  \p{Join_Control}    200C..200D
 
         public boolean is(int ch) {
             return ALPHABETIC.is(ch) ||
@@ -189,7 +190,15 @@
                       (1 << Character.COMBINING_SPACING_MARK) |
                       (1 << Character.DECIMAL_DIGIT_NUMBER) |
                       (1 << Character.CONNECTOR_PUNCTUATION)) >> Character.getType(ch)) & 1)
-                   != 0;
+                   != 0 ||
+                   JOIN_CONTROL.is(ch);
+        }
+    },
+
+    JOIN_CONTROL {
+        //  200C..200D    PropList.txt:Join_Control
+        public boolean is(int ch) {
+           return (ch == 0x200C || ch == 0x200D);
         }
     };
 
@@ -212,6 +221,7 @@
         aliases.put("WHITESPACE", "WHITE_SPACE");
         aliases.put("HEXDIGIT","HEX_DIGIT");
         aliases.put("NONCHARACTERCODEPOINT", "NONCHARACTER_CODE_POINT");
+        aliases.put("JOINCONTROL", "JOIN_CONTROL");
     }
 
     public static UnicodeProp forName(String propName) {
diff --git a/jdk/src/share/classes/java/util/stream/MatchOps.java b/jdk/src/share/classes/java/util/stream/MatchOps.java
index 3fdef94..0f9362a 100644
--- a/jdk/src/share/classes/java/util/stream/MatchOps.java
+++ b/jdk/src/share/classes/java/util/stream/MatchOps.java
@@ -94,12 +94,7 @@
             }
         }
 
-        // @@@ Workaround for JDK-8011591 -- when fixed, replace s with constructor ref
-        Supplier<BooleanTerminalSink<T>> s = new Supplier<BooleanTerminalSink<T>>() {
-            @Override
-            public BooleanTerminalSink<T> get() {return new MatchSink();}
-        };
-        return new MatchOp<>(StreamShape.REFERENCE, matchKind, s);
+        return new MatchOp<>(StreamShape.REFERENCE, matchKind, MatchSink::new);
     }
 
     /**
@@ -128,12 +123,7 @@
             }
         }
 
-        // @@@ Workaround for JDK-8011591 -- when fixed, replace s with constructor ref
-        Supplier<BooleanTerminalSink<Integer>> s = new Supplier<BooleanTerminalSink<Integer>>() {
-            @Override
-            public BooleanTerminalSink<Integer> get() {return new MatchSink();}
-        };
-        return new MatchOp<>(StreamShape.INT_VALUE, matchKind, s);
+        return new MatchOp<>(StreamShape.INT_VALUE, matchKind, MatchSink::new);
     }
 
     /**
@@ -163,12 +153,7 @@
             }
         }
 
-        // @@@ Workaround for JDK-8011591 -- when fixed, replace s with constructor ref
-        Supplier<BooleanTerminalSink<Long>> s = new Supplier<BooleanTerminalSink<Long>>() {
-            @Override
-            public BooleanTerminalSink<Long> get() {return new MatchSink();}
-        };
-        return new MatchOp<>(StreamShape.LONG_VALUE, matchKind, s);
+        return new MatchOp<>(StreamShape.LONG_VALUE, matchKind, MatchSink::new);
     }
 
     /**
@@ -198,12 +183,7 @@
             }
         }
 
-        // @@@ Workaround for JDK-8011591 -- when fixed, replace s with constructor ref
-        Supplier<BooleanTerminalSink<Double>> s = new Supplier<BooleanTerminalSink<Double>>() {
-            @Override
-            public BooleanTerminalSink<Double> get() {return new MatchSink();}
-        };
-        return new MatchOp<>(StreamShape.DOUBLE_VALUE, matchKind, s);
+        return new MatchOp<>(StreamShape.DOUBLE_VALUE, matchKind, MatchSink::new);
     }
 
     /**
diff --git a/jdk/src/share/classes/java/util/zip/GZIPInputStream.java b/jdk/src/share/classes/java/util/zip/GZIPInputStream.java
index 4db2e7f..74a5c60 100644
--- a/jdk/src/share/classes/java/util/zip/GZIPInputStream.java
+++ b/jdk/src/share/classes/java/util/zip/GZIPInputStream.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 
 import java.io.SequenceInputStream;
 import java.io.ByteArrayInputStream;
+import java.io.FilterInputStream;
 import java.io.InputStream;
 import java.io.IOException;
 import java.io.EOFException;
@@ -212,7 +213,10 @@
         int n = inf.getRemaining();
         if (n > 0) {
             in = new SequenceInputStream(
-                        new ByteArrayInputStream(buf, len - n, n), in);
+                        new ByteArrayInputStream(buf, len - n, n),
+                        new FilterInputStream(in) {
+                            public void close() throws IOException {}
+                        });
         }
         // Uses left-to-right evaluation order
         if ((readUInt(in) != crc.getValue()) ||
diff --git a/jdk/src/share/classes/java/util/zip/ZipFile.java b/jdk/src/share/classes/java/util/zip/ZipFile.java
index 9693809..f334f36 100644
--- a/jdk/src/share/classes/java/util/zip/ZipFile.java
+++ b/jdk/src/share/classes/java/util/zip/ZipFile.java
@@ -36,11 +36,15 @@
 import java.util.Deque;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
 import java.util.NoSuchElementException;
+import java.util.Spliterator;
+import java.util.Spliterators;
 import java.util.WeakHashMap;
-import java.security.AccessController;
-import sun.security.action.GetPropertyAction;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
 import static java.util.zip.ZipConstants64.*;
 
 /**
@@ -471,49 +475,80 @@
         return name;
     }
 
+    private class ZipEntryIterator implements Enumeration<ZipEntry>, Iterator<ZipEntry> {
+        private int i = 0;
+
+        public ZipEntryIterator() {
+            ensureOpen();
+        }
+
+        public boolean hasMoreElements() {
+            return hasNext();
+        }
+
+        public boolean hasNext() {
+            synchronized (ZipFile.this) {
+                ensureOpen();
+                return i < total;
+            }
+        }
+
+        public ZipEntry nextElement() {
+            return next();
+        }
+
+        public ZipEntry next() {
+            synchronized (ZipFile.this) {
+                ensureOpen();
+                if (i >= 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;
+            }
+        }
+    }
+
     /**
      * Returns an enumeration of the ZIP file entries.
      * @return an enumeration of the ZIP file entries
      * @throws IllegalStateException if the zip file has been closed
      */
     public Enumeration<? extends ZipEntry> entries() {
-        ensureOpen();
-        return new Enumeration<ZipEntry>() {
-                private int i = 0;
-                public boolean hasMoreElements() {
-                    synchronized (ZipFile.this) {
-                        ensureOpen();
-                        return i < total;
-                    }
-                }
-                public ZipEntry nextElement() throws NoSuchElementException {
-                    synchronized (ZipFile.this) {
-                        ensureOpen();
-                        if (i >= 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;
-                    }
-                }
-            };
+        return new ZipEntryIterator();
+    }
+
+    /**
+     * Return an ordered {@code Stream} over the ZIP file entries.
+     * Entries appear in the {@code Stream} in the order they appear in
+     * the central directory of the ZIP file.
+     *
+     * @return an ordered {@code Stream} of entries in this ZIP file
+     * @throws IllegalStateException if the zip file has been closed
+     * @since 1.8
+     */
+    public Stream<? extends ZipEntry> stream() {
+        return StreamSupport.stream(Spliterators.spliterator(
+                new ZipEntryIterator(), size(),
+                Spliterator.ORDERED | Spliterator.DISTINCT |
+                        Spliterator.IMMUTABLE | Spliterator.NONNULL));
     }
 
     private ZipEntry getZipEntry(String name, long jzentry) {
diff --git a/jdk/src/share/classes/javax/management/remote/rmi/RMIServerImpl.java b/jdk/src/share/classes/javax/management/remote/rmi/RMIServerImpl.java
index 0b6ad75..2226f6c 100644
--- a/jdk/src/share/classes/javax/management/remote/rmi/RMIServerImpl.java
+++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIServerImpl.java
@@ -474,6 +474,15 @@
         String clientHost = "";
         try {
             clientHost = RemoteServer.getClientHost();
+            /*
+             * According to the rules specified in the javax.management.remote
+             * package description, a numeric IPv6 address (detected by the
+             * presence of otherwise forbidden ":" character) forming a part
+             * of the connection id must be enclosed in square brackets.
+             */
+            if (clientHost.contains(":")) {
+                clientHost = "[" + clientHost + "]";
+            }
         } catch (ServerNotActiveException e) {
             logger.trace("makeConnectionId", "getClientHost", e);
         }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/AnnotationVisitor.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/AnnotationVisitor.java
index 9690afe..0841a6c 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/AnnotationVisitor.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/AnnotationVisitor.java
@@ -70,7 +70,7 @@
 
     /**
      * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4}.
+     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
      */
     protected final int api;
 
@@ -83,8 +83,9 @@
     /**
      * Constructs a new {@link AnnotationVisitor}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
      */
     public AnnotationVisitor(final int api) {
         this(api, null);
@@ -93,15 +94,17 @@
     /**
      * Constructs a new {@link AnnotationVisitor}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
-     * @param av the annotation visitor to which this visitor must delegate
-     *        method calls. May be null.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param av
+     *            the annotation visitor to which this visitor must delegate
+     *            method calls. May be null.
      */
     public AnnotationVisitor(final int api, final AnnotationVisitor av) {
-        /*if (api != Opcodes.ASM4) {
+        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
             throw new IllegalArgumentException();
-        }*/
+        }
         this.api = api;
         this.av = av;
     }
@@ -109,14 +112,17 @@
     /**
      * Visits a primitive value of the annotation.
      *
-     * @param name the value name.
-     * @param value the actual value, whose type must be {@link Byte},
-     *        {@link Boolean}, {@link Character}, {@link Short}, {@link Integer}
-     *        , {@link Long}, {@link Float}, {@link Double}, {@link String} or
-     *        {@link Type} or OBJECT or ARRAY sort. This value can also be an
-     *        array of byte, boolean, short, char, int, long, float or double
-     *        values (this is equivalent to using {@link #visitArray visitArray}
-     *        and visiting each array element in turn, but is more convenient).
+     * @param name
+     *            the value name.
+     * @param value
+     *            the actual value, whose type must be {@link Byte},
+     *            {@link Boolean}, {@link Character}, {@link Short},
+     *            {@link Integer} , {@link Long}, {@link Float}, {@link Double},
+     *            {@link String} or {@link Type} or OBJECT or ARRAY sort. This
+     *            value can also be an array of byte, boolean, short, char, int,
+     *            long, float or double values (this is equivalent to using
+     *            {@link #visitArray visitArray} and visiting each array element
+     *            in turn, but is more convenient).
      */
     public void visit(String name, Object value) {
         if (av != null) {
@@ -127,9 +133,12 @@
     /**
      * Visits an enumeration value of the annotation.
      *
-     * @param name the value name.
-     * @param desc the class descriptor of the enumeration class.
-     * @param value the actual enumeration value.
+     * @param name
+     *            the value name.
+     * @param desc
+     *            the class descriptor of the enumeration class.
+     * @param value
+     *            the actual enumeration value.
      */
     public void visitEnum(String name, String desc, String value) {
         if (av != null) {
@@ -140,12 +149,14 @@
     /**
      * Visits a nested annotation value of the annotation.
      *
-     * @param name the value name.
-     * @param desc the class descriptor of the nested annotation class.
+     * @param name
+     *            the value name.
+     * @param desc
+     *            the class descriptor of the nested annotation class.
      * @return a visitor to visit the actual nested annotation value, or
-     *         <tt>null</tt> if this visitor is not interested in visiting
-     *         this nested annotation. <i>The nested annotation value must be
-     *         fully visited before calling other methods on this annotation
+     *         <tt>null</tt> if this visitor is not interested in visiting this
+     *         nested annotation. <i>The nested annotation value must be fully
+     *         visited before calling other methods on this annotation
      *         visitor</i>.
      */
     public AnnotationVisitor visitAnnotation(String name, String desc) {
@@ -161,10 +172,11 @@
      * can be passed as value to {@link #visit visit}. This is what
      * {@link ClassReader} does.
      *
-     * @param name the value name.
+     * @param name
+     *            the value name.
      * @return a visitor to visit the actual array value elements, or
-     *         <tt>null</tt> if this visitor is not interested in visiting
-     *         these values. The 'name' parameters passed to the methods of this
+     *         <tt>null</tt> if this visitor is not interested in visiting these
+     *         values. The 'name' parameters passed to the methods of this
      *         visitor are ignored. <i>All the array values must be visited
      *         before calling other methods on this annotation visitor</i>.
      */
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/AnnotationWriter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/AnnotationWriter.java
index ca72839..5419615 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/AnnotationWriter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/AnnotationWriter.java
@@ -119,21 +119,21 @@
     /**
      * Constructs a new {@link AnnotationWriter}.
      *
-     * @param cw the class writer to which this annotation must be added.
-     * @param named <tt>true<tt> if values are named, <tt>false</tt> otherwise.
-     * @param bv where the annotation values must be stored.
-     * @param parent where the number of annotation values must be stored.
-     * @param offset where in <tt>parent</tt> the number of annotation values must
-     *      be stored.
+     * @param cw
+     *            the class writer to which this annotation must be added.
+     * @param named
+     *            <tt>true<tt> if values are named, <tt>false</tt> otherwise.
+     * @param bv
+     *            where the annotation values must be stored.
+     * @param parent
+     *            where the number of annotation values must be stored.
+     * @param offset
+     *            where in <tt>parent</tt> the number of annotation values must
+     *            be stored.
      */
-    AnnotationWriter(
-        final ClassWriter cw,
-        final boolean named,
-        final ByteVector bv,
-        final ByteVector parent,
-        final int offset)
-    {
-        super(Opcodes.ASM4);
+    AnnotationWriter(final ClassWriter cw, final boolean named,
+            final ByteVector bv, final ByteVector parent, final int offset) {
+        super(Opcodes.ASM5);
         this.cw = cw;
         this.named = named;
         this.bv = bv;
@@ -219,11 +219,8 @@
     }
 
     @Override
-    public void visitEnum(
-        final String name,
-        final String desc,
-        final String value)
-    {
+    public void visitEnum(final String name, final String desc,
+            final String value) {
         ++size;
         if (named) {
             bv.putShort(cw.newUTF8(name));
@@ -232,10 +229,8 @@
     }
 
     @Override
-    public AnnotationVisitor visitAnnotation(
-        final String name,
-        final String desc)
-    {
+    public AnnotationVisitor visitAnnotation(final String name,
+            final String desc) {
         ++size;
         if (named) {
             bv.putShort(cw.newUTF8(name));
@@ -288,7 +283,8 @@
      * Puts the annotations of this annotation writer list into the given byte
      * vector.
      *
-     * @param out where the annotations must be put.
+     * @param out
+     *            where the annotations must be put.
      */
     void put(final ByteVector out) {
         int n = 0;
@@ -315,15 +311,15 @@
     /**
      * Puts the given annotation lists into the given byte vector.
      *
-     * @param panns an array of annotation writer lists.
-     * @param off index of the first annotation to be written.
-     * @param out where the annotations must be put.
+     * @param panns
+     *            an array of annotation writer lists.
+     * @param off
+     *            index of the first annotation to be written.
+     * @param out
+     *            where the annotations must be put.
      */
-    static void put(
-        final AnnotationWriter[] panns,
-        final int off,
-        final ByteVector out)
-    {
+    static void put(final AnnotationWriter[] panns, final int off,
+            final ByteVector out) {
         int size = 1 + 2 * (panns.length - off);
         for (int i = off; i < panns.length; ++i) {
             size += panns[i] == null ? 0 : panns[i].getSize();
@@ -348,4 +344,57 @@
             }
         }
     }
+
+    /**
+     * Puts the given type reference and type path into the given bytevector.
+     * LOCAL_VARIABLE and RESOURCE_VARIABLE target types are not supported.
+     *
+     * @param typeRef
+     *            a reference to the annotated type. See {@link TypeReference}.
+     * @param typePath
+     *            the path to the annotated type argument, wildcard bound, array
+     *            element type, or static inner type within 'typeRef'. May be
+     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
+     * @param out
+     *            where the type reference and type path must be put.
+     */
+    static void putTarget(int typeRef, TypePath typePath, ByteVector out) {
+        switch (typeRef >>> 24) {
+        case 0x00: // CLASS_TYPE_PARAMETER
+        case 0x01: // METHOD_TYPE_PARAMETER
+        case 0x16: // METHOD_FORMAL_PARAMETER
+            out.putShort(typeRef >>> 16);
+            break;
+        case 0x13: // FIELD
+        case 0x14: // METHOD_RETURN
+        case 0x15: // METHOD_RECEIVER
+            out.putByte(typeRef >>> 24);
+            break;
+        case 0x47: // CAST
+        case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+        case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
+        case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+        case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
+            out.putInt(typeRef);
+            break;
+        // case 0x10: // CLASS_EXTENDS
+        // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
+        // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
+        // case 0x17: // THROWS
+        // case 0x42: // EXCEPTION_PARAMETER
+        // case 0x43: // INSTANCEOF
+        // case 0x44: // NEW
+        // case 0x45: // CONSTRUCTOR_REFERENCE
+        // case 0x46: // METHOD_REFERENCE
+        default:
+            out.put12(typeRef >>> 24, (typeRef & 0xFFFF00) >> 8);
+            break;
+        }
+        if (typePath == null) {
+            out.putByte(0);
+        } else {
+            int length = typePath.b[typePath.offset] * 2 + 1;
+            out.putByteArray(typePath.b, typePath.offset, length);
+        }
+    }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Attribute.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Attribute.java
index 03817bc..20eb272 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Attribute.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Attribute.java
@@ -84,7 +84,8 @@
     /**
      * Constructs a new empty attribute.
      *
-     * @param type the type of the attribute.
+     * @param type
+     *            the type of the attribute.
      */
     protected Attribute(final String type) {
         this.type = type;
@@ -120,39 +121,39 @@
     }
 
     /**
-     * Reads a {@link #type type} attribute. This method must return a <i>new</i>
-     * {@link Attribute} object, of type {@link #type type}, corresponding to
-     * the <tt>len</tt> bytes starting at the given offset, in the given class
-     * reader.
+     * Reads a {@link #type type} attribute. This method must return a
+     * <i>new</i> {@link Attribute} object, of type {@link #type type},
+     * corresponding to the <tt>len</tt> bytes starting at the given offset, in
+     * the given class reader.
      *
-     * @param cr the class that contains the attribute to be read.
-     * @param off index of the first byte of the attribute's content in {@link
-     *        ClassReader#b cr.b}. The 6 attribute header bytes, containing the
-     *        type and the length of the attribute, are not taken into account
-     *        here.
-     * @param len the length of the attribute's content.
-     * @param buf buffer to be used to call
-     *        {@link ClassReader#readUTF8 readUTF8},
-     *        {@link ClassReader#readClass(int,char[]) readClass} or
-     *        {@link ClassReader#readConst readConst}.
-     * @param codeOff index of the first byte of code's attribute content in
-     *        {@link ClassReader#b cr.b}, or -1 if the attribute to be read is
-     *        not a code attribute. The 6 attribute header bytes, containing the
-     *        type and the length of the attribute, are not taken into account
-     *        here.
-     * @param labels the labels of the method's code, or <tt>null</tt> if the
-     *        attribute to be read is not a code attribute.
+     * @param cr
+     *            the class that contains the attribute to be read.
+     * @param off
+     *            index of the first byte of the attribute's content in
+     *            {@link ClassReader#b cr.b}. The 6 attribute header bytes,
+     *            containing the type and the length of the attribute, are not
+     *            taken into account here.
+     * @param len
+     *            the length of the attribute's content.
+     * @param buf
+     *            buffer to be used to call {@link ClassReader#readUTF8
+     *            readUTF8}, {@link ClassReader#readClass(int,char[]) readClass}
+     *            or {@link ClassReader#readConst readConst}.
+     * @param codeOff
+     *            index of the first byte of code's attribute content in
+     *            {@link ClassReader#b cr.b}, or -1 if the attribute to be read
+     *            is not a code attribute. The 6 attribute header bytes,
+     *            containing the type and the length of the attribute, are not
+     *            taken into account here.
+     * @param labels
+     *            the labels of the method's code, or <tt>null</tt> if the
+     *            attribute to be read is not a code attribute.
      * @return a <i>new</i> {@link Attribute} object corresponding to the given
      *         bytes.
      */
-    protected Attribute read(
-        final ClassReader cr,
-        final int off,
-        final int len,
-        final char[] buf,
-        final int codeOff,
-        final Label[] labels)
-    {
+    protected Attribute read(final ClassReader cr, final int off,
+            final int len, final char[] buf, final int codeOff,
+            final Label[] labels) {
         Attribute attr = new Attribute(type);
         attr.value = new byte[len];
         System.arraycopy(cr.b, off, attr.value, 0, len);
@@ -162,30 +163,30 @@
     /**
      * Returns the byte array form of this attribute.
      *
-     * @param cw the class to which this attribute must be added. This parameter
-     *        can be used to add to the constant pool of this class the items
-     *        that corresponds to this attribute.
-     * @param code the bytecode of the method corresponding to this code
-     *        attribute, or <tt>null</tt> if this attribute is not a code
-     *        attributes.
-     * @param len the length of the bytecode of the method corresponding to this
-     *        code attribute, or <tt>null</tt> if this attribute is not a code
-     *        attribute.
-     * @param maxStack the maximum stack size of the method corresponding to
-     *        this code attribute, or -1 if this attribute is not a code
-     *        attribute.
-     * @param maxLocals the maximum number of local variables of the method
-     *        corresponding to this code attribute, or -1 if this attribute is
-     *        not a code attribute.
+     * @param cw
+     *            the class to which this attribute must be added. This
+     *            parameter can be used to add to the constant pool of this
+     *            class the items that corresponds to this attribute.
+     * @param code
+     *            the bytecode of the method corresponding to this code
+     *            attribute, or <tt>null</tt> if this attribute is not a code
+     *            attributes.
+     * @param len
+     *            the length of the bytecode of the method corresponding to this
+     *            code attribute, or <tt>null</tt> if this attribute is not a
+     *            code attribute.
+     * @param maxStack
+     *            the maximum stack size of the method corresponding to this
+     *            code attribute, or -1 if this attribute is not a code
+     *            attribute.
+     * @param maxLocals
+     *            the maximum number of local variables of the method
+     *            corresponding to this code attribute, or -1 if this attribute
+     *            is not a code attribute.
      * @return the byte array form of this attribute.
      */
-    protected ByteVector write(
-        final ClassWriter cw,
-        final byte[] code,
-        final int len,
-        final int maxStack,
-        final int maxLocals)
-    {
+    protected ByteVector write(final ClassWriter cw, final byte[] code,
+            final int len, final int maxStack, final int maxLocals) {
         ByteVector v = new ByteVector();
         v.data = value;
         v.length = value.length;
@@ -210,30 +211,30 @@
     /**
      * Returns the size of all the attributes in this attribute list.
      *
-     * @param cw the class writer to be used to convert the attributes into byte
-     *        arrays, with the {@link #write write} method.
-     * @param code the bytecode of the method corresponding to these code
-     *        attributes, or <tt>null</tt> if these attributes are not code
-     *        attributes.
-     * @param len the length of the bytecode of the method corresponding to
-     *        these code attributes, or <tt>null</tt> if these attributes are
-     *        not code attributes.
-     * @param maxStack the maximum stack size of the method corresponding to
-     *        these code attributes, or -1 if these attributes are not code
-     *        attributes.
-     * @param maxLocals the maximum number of local variables of the method
-     *        corresponding to these code attributes, or -1 if these attributes
-     *        are not code attributes.
+     * @param cw
+     *            the class writer to be used to convert the attributes into
+     *            byte arrays, with the {@link #write write} method.
+     * @param code
+     *            the bytecode of the method corresponding to these code
+     *            attributes, or <tt>null</tt> if these attributes are not code
+     *            attributes.
+     * @param len
+     *            the length of the bytecode of the method corresponding to
+     *            these code attributes, or <tt>null</tt> if these attributes
+     *            are not code attributes.
+     * @param maxStack
+     *            the maximum stack size of the method corresponding to these
+     *            code attributes, or -1 if these attributes are not code
+     *            attributes.
+     * @param maxLocals
+     *            the maximum number of local variables of the method
+     *            corresponding to these code attributes, or -1 if these
+     *            attributes are not code attributes.
      * @return the size of all the attributes in this attribute list. This size
      *         includes the size of the attribute headers.
      */
-    final int getSize(
-        final ClassWriter cw,
-        final byte[] code,
-        final int len,
-        final int maxStack,
-        final int maxLocals)
-    {
+    final int getSize(final ClassWriter cw, final byte[] code, final int len,
+            final int maxStack, final int maxLocals) {
         Attribute attr = this;
         int size = 0;
         while (attr != null) {
@@ -248,30 +249,30 @@
      * Writes all the attributes of this attribute list in the given byte
      * vector.
      *
-     * @param cw the class writer to be used to convert the attributes into byte
-     *        arrays, with the {@link #write write} method.
-     * @param code the bytecode of the method corresponding to these code
-     *        attributes, or <tt>null</tt> if these attributes are not code
-     *        attributes.
-     * @param len the length of the bytecode of the method corresponding to
-     *        these code attributes, or <tt>null</tt> if these attributes are
-     *        not code attributes.
-     * @param maxStack the maximum stack size of the method corresponding to
-     *        these code attributes, or -1 if these attributes are not code
-     *        attributes.
-     * @param maxLocals the maximum number of local variables of the method
-     *        corresponding to these code attributes, or -1 if these attributes
-     *        are not code attributes.
-     * @param out where the attributes must be written.
+     * @param cw
+     *            the class writer to be used to convert the attributes into
+     *            byte arrays, with the {@link #write write} method.
+     * @param code
+     *            the bytecode of the method corresponding to these code
+     *            attributes, or <tt>null</tt> if these attributes are not code
+     *            attributes.
+     * @param len
+     *            the length of the bytecode of the method corresponding to
+     *            these code attributes, or <tt>null</tt> if these attributes
+     *            are not code attributes.
+     * @param maxStack
+     *            the maximum stack size of the method corresponding to these
+     *            code attributes, or -1 if these attributes are not code
+     *            attributes.
+     * @param maxLocals
+     *            the maximum number of local variables of the method
+     *            corresponding to these code attributes, or -1 if these
+     *            attributes are not code attributes.
+     * @param out
+     *            where the attributes must be written.
      */
-    final void put(
-        final ClassWriter cw,
-        final byte[] code,
-        final int len,
-        final int maxStack,
-        final int maxLocals,
-        final ByteVector out)
-    {
+    final void put(final ClassWriter cw, final byte[] code, final int len,
+            final int maxStack, final int maxLocals, final ByteVector out) {
         Attribute attr = this;
         while (attr != null) {
             ByteVector b = attr.write(cw, code, len, maxStack, maxLocals);
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ByteVector.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ByteVector.java
index 6a00f9d..0d3472b 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ByteVector.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ByteVector.java
@@ -88,7 +88,8 @@
      * Constructs a new {@link ByteVector ByteVector} with the given initial
      * size.
      *
-     * @param initialSize the initial size of the byte vector to be constructed.
+     * @param initialSize
+     *            the initial size of the byte vector to be constructed.
      */
     public ByteVector(final int initialSize) {
         data = new byte[initialSize];
@@ -98,7 +99,8 @@
      * Puts a byte into this byte vector. The byte vector is automatically
      * enlarged if necessary.
      *
-     * @param b a byte.
+     * @param b
+     *            a byte.
      * @return this byte vector.
      */
     public ByteVector putByte(final int b) {
@@ -115,8 +117,10 @@
      * Puts two bytes into this byte vector. The byte vector is automatically
      * enlarged if necessary.
      *
-     * @param b1 a byte.
-     * @param b2 another byte.
+     * @param b1
+     *            a byte.
+     * @param b2
+     *            another byte.
      * @return this byte vector.
      */
     ByteVector put11(final int b1, final int b2) {
@@ -135,7 +139,8 @@
      * Puts a short into this byte vector. The byte vector is automatically
      * enlarged if necessary.
      *
-     * @param s a short.
+     * @param s
+     *            a short.
      * @return this byte vector.
      */
     public ByteVector putShort(final int s) {
@@ -154,8 +159,10 @@
      * Puts a byte and a short into this byte vector. The byte vector is
      * automatically enlarged if necessary.
      *
-     * @param b a byte.
-     * @param s a short.
+     * @param b
+     *            a byte.
+     * @param s
+     *            a short.
      * @return this byte vector.
      */
     ByteVector put12(final int b, final int s) {
@@ -175,7 +182,8 @@
      * Puts an int into this byte vector. The byte vector is automatically
      * enlarged if necessary.
      *
-     * @param i an int.
+     * @param i
+     *            an int.
      * @return this byte vector.
      */
     public ByteVector putInt(final int i) {
@@ -196,7 +204,8 @@
      * Puts a long into this byte vector. The byte vector is automatically
      * enlarged if necessary.
      *
-     * @param l a long.
+     * @param l
+     *            a long.
      * @return this byte vector.
      */
     public ByteVector putLong(final long l) {
@@ -223,7 +232,8 @@
      * Puts an UTF8 string into this byte vector. The byte vector is
      * automatically enlarged if necessary.
      *
-     * @param s a String.
+     * @param s
+     *            a String.
      * @return this byte vector.
      */
     public ByteVector putUTF8(final String s) {
@@ -288,14 +298,16 @@
      * Puts an array of bytes into this byte vector. The byte vector is
      * automatically enlarged if necessary.
      *
-     * @param b an array of bytes. May be <tt>null</tt> to put <tt>len</tt>
-     *        null bytes into this byte vector.
-     * @param off index of the fist byte of b that must be copied.
-     * @param len number of bytes of b that must be copied.
+     * @param b
+     *            an array of bytes. May be <tt>null</tt> to put <tt>len</tt>
+     *            null bytes into this byte vector.
+     * @param off
+     *            index of the fist byte of b that must be copied.
+     * @param len
+     *            number of bytes of b that must be copied.
      * @return this byte vector.
      */
-    public ByteVector putByteArray(final byte[] b, final int off, final int len)
-    {
+    public ByteVector putByteArray(final byte[] b, final int off, final int len) {
         if (length + len > data.length) {
             enlarge(len);
         }
@@ -309,8 +321,9 @@
     /**
      * Enlarge this byte vector so that it can receive n more bytes.
      *
-     * @param size number of additional bytes that this byte vector should be
-     *        able to receive.
+     * @param size
+     *            number of additional bytes that this byte vector should be
+     *            able to receive.
      */
     private void enlarge(final int size) {
         int length1 = 2 * data.length;
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java
index 99d8a10..8cbc2d2 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java
@@ -141,9 +141,8 @@
     public final byte[] b;
 
     /**
-     * The start index of each constant pool item in {@link #b b}, plus one.
-     * The one byte offset skips the constant pool item tag that indicates its
-     * type.
+     * The start index of each constant pool item in {@link #b b}, plus one. The
+     * one byte offset skips the constant pool item tag that indicates its type.
      */
     private final int[] items;
 
@@ -176,7 +175,8 @@
     /**
      * Constructs a new {@link ClassReader} object.
      *
-     * @param b the bytecode of the class to be read.
+     * @param b
+     *            the bytecode of the class to be read.
      */
     public ClassReader(final byte[] b) {
         this(b, 0, b.length);
@@ -185,14 +185,17 @@
     /**
      * Constructs a new {@link ClassReader} object.
      *
-     * @param b the bytecode of the class to be read.
-     * @param off the start offset of the class data.
-     * @param len the length of the class data.
+     * @param b
+     *            the bytecode of the class to be read.
+     * @param off
+     *            the start offset of the class data.
+     * @param len
+     *            the length of the class data.
      */
     public ClassReader(final byte[] b, final int off, final int len) {
         this.b = b;
         // checks the class version
-        if (readShort(6) > Opcodes.V1_7) {
+        if (readShort(off + 6) > Opcodes.V1_8) {
             throw new IllegalArgumentException();
         }
         // parses the constant pool
@@ -205,35 +208,35 @@
             items[i] = index + 1;
             int size;
             switch (b[index]) {
-                case ClassWriter.FIELD:
-                case ClassWriter.METH:
-                case ClassWriter.IMETH:
-                case ClassWriter.INT:
-                case ClassWriter.FLOAT:
-                case ClassWriter.NAME_TYPE:
-                case ClassWriter.INDY:
-                    size = 5;
-                    break;
-                case ClassWriter.LONG:
-                case ClassWriter.DOUBLE:
-                    size = 9;
-                    ++i;
-                    break;
-                case ClassWriter.UTF8:
-                    size = 3 + readUnsignedShort(index + 1);
-                    if (size > max) {
-                        max = size;
-                    }
-                    break;
-                case ClassWriter.HANDLE:
-                    size = 4;
-                    break;
-                // case ClassWriter.CLASS:
-                // case ClassWriter.STR:
-                // case ClassWriter.MTYPE
-                default:
-                    size = 3;
-                    break;
+            case ClassWriter.FIELD:
+            case ClassWriter.METH:
+            case ClassWriter.IMETH:
+            case ClassWriter.INT:
+            case ClassWriter.FLOAT:
+            case ClassWriter.NAME_TYPE:
+            case ClassWriter.INDY:
+                size = 5;
+                break;
+            case ClassWriter.LONG:
+            case ClassWriter.DOUBLE:
+                size = 9;
+                ++i;
+                break;
+            case ClassWriter.UTF8:
+                size = 3 + readUnsignedShort(index + 1);
+                if (size > max) {
+                    max = size;
+                }
+                break;
+            case ClassWriter.HANDLE:
+                size = 4;
+                break;
+            // case ClassWriter.CLASS:
+            // case ClassWriter.STR:
+            // case ClassWriter.MTYPE
+            default:
+                size = 3;
+                break;
             }
             index += size;
         }
@@ -278,8 +281,7 @@
      * @see ClassVisitor#visit(int, int, String, String, String, String[])
      */
     public String getSuperName() {
-        int n = items[readUnsignedShort(header + 4)];
-        return n == 0 ? null : readUTF8(n, new char[maxStringLength]);
+        return readClass(header + 4, new char[maxStringLength]);
     }
 
     /**
@@ -309,7 +311,8 @@
      * Copies the constant pool data into the given {@link ClassWriter}. Should
      * be called before the {@link #accept(ClassVisitor,int)} method.
      *
-     * @param classWriter the {@link ClassWriter} to copy constant pool into.
+     * @param classWriter
+     *            the {@link ClassWriter} to copy constant pool into.
      */
     void copyPool(final ClassWriter classWriter) {
         char[] buf = new char[maxStringLength];
@@ -321,82 +324,63 @@
             Item item = new Item(i);
             int nameType;
             switch (tag) {
-                case ClassWriter.FIELD:
-                case ClassWriter.METH:
-                case ClassWriter.IMETH:
-                    nameType = items[readUnsignedShort(index + 2)];
-                    item.set(tag,
-                            readClass(index, buf),
-                            readUTF8(nameType, buf),
-                            readUTF8(nameType + 2, buf));
-                    break;
-
-                case ClassWriter.INT:
-                    item.set(readInt(index));
-                    break;
-
-                case ClassWriter.FLOAT:
-                    item.set(Float.intBitsToFloat(readInt(index)));
-                    break;
-
-                case ClassWriter.NAME_TYPE:
-                    item.set(tag,
-                            readUTF8(index, buf),
-                            readUTF8(index + 2, buf),
-                            null);
-                    break;
-
-                case ClassWriter.LONG:
-                    item.set(readLong(index));
-                    ++i;
-                    break;
-
-                case ClassWriter.DOUBLE:
-                    item.set(Double.longBitsToDouble(readLong(index)));
-                    ++i;
-                    break;
-
-                case ClassWriter.UTF8: {
-                    String s = strings[i];
-                    if (s == null) {
-                        index = items[i];
-                        s = strings[i] = readUTF(index + 2,
-                                readUnsignedShort(index),
-                                buf);
-                    }
-                    item.set(tag, s, null, null);
+            case ClassWriter.FIELD:
+            case ClassWriter.METH:
+            case ClassWriter.IMETH:
+                nameType = items[readUnsignedShort(index + 2)];
+                item.set(tag, readClass(index, buf), readUTF8(nameType, buf),
+                        readUTF8(nameType + 2, buf));
+                break;
+            case ClassWriter.INT:
+                item.set(readInt(index));
+                break;
+            case ClassWriter.FLOAT:
+                item.set(Float.intBitsToFloat(readInt(index)));
+                break;
+            case ClassWriter.NAME_TYPE:
+                item.set(tag, readUTF8(index, buf), readUTF8(index + 2, buf),
+                        null);
+                break;
+            case ClassWriter.LONG:
+                item.set(readLong(index));
+                ++i;
+                break;
+            case ClassWriter.DOUBLE:
+                item.set(Double.longBitsToDouble(readLong(index)));
+                ++i;
+                break;
+            case ClassWriter.UTF8: {
+                String s = strings[i];
+                if (s == null) {
+                    index = items[i];
+                    s = strings[i] = readUTF(index + 2,
+                            readUnsignedShort(index), buf);
                 }
-                    break;
-
-                case ClassWriter.HANDLE: {
-                    int fieldOrMethodRef = items[readUnsignedShort(index + 1)];
-                    nameType = items[readUnsignedShort(fieldOrMethodRef + 2)];
-                    item.set(ClassWriter.HANDLE_BASE + readByte(index),
-                            readClass(fieldOrMethodRef, buf),
-                            readUTF8(nameType, buf),
-                            readUTF8(nameType + 2, buf));
-
+                item.set(tag, s, null, null);
+                break;
+            }
+            case ClassWriter.HANDLE: {
+                int fieldOrMethodRef = items[readUnsignedShort(index + 1)];
+                nameType = items[readUnsignedShort(fieldOrMethodRef + 2)];
+                item.set(ClassWriter.HANDLE_BASE + readByte(index),
+                        readClass(fieldOrMethodRef, buf),
+                        readUTF8(nameType, buf), readUTF8(nameType + 2, buf));
+                break;
+            }
+            case ClassWriter.INDY:
+                if (classWriter.bootstrapMethods == null) {
+                    copyBootstrapMethods(classWriter, items2, buf);
                 }
-                    break;
-
-
-                case ClassWriter.INDY:
-                    if (classWriter.bootstrapMethods == null) {
-                        copyBootstrapMethods(classWriter, items2, buf);
-                    }
-                    nameType = items[readUnsignedShort(index + 2)];
-                    item.set(readUTF8(nameType, buf),
-                            readUTF8(nameType + 2, buf),
-                            readUnsignedShort(index));
-                    break;
-
-
-                // case ClassWriter.STR:
-                // case ClassWriter.CLASS:
-                // case ClassWriter.MTYPE
-                default:
-                    item.set(tag, readUTF8(index, buf), null, null);
-                    break;
+                nameType = items[readUnsignedShort(index + 2)];
+                item.set(readUTF8(nameType, buf), readUTF8(nameType + 2, buf),
+                        readUnsignedShort(index));
+                break;
+            // case ClassWriter.STR:
+            // case ClassWriter.CLASS:
+            // case ClassWriter.MTYPE
+            default:
+                item.set(tag, readUTF8(index, buf), null, null);
+                break;
             }
 
             int index2 = item.hashCode % items2.length;
@@ -411,77 +395,59 @@
         classWriter.index = ll;
     }
 
-    private void copyBootstrapMethods(ClassWriter classWriter, Item[] items2, char[] buf) {
-        int i, j, k, u, v;
-
-        // skip class header
-        v = header;
-        v += 8 + (readUnsignedShort(v + 6) << 1);
-
-        // skips fields and methods
-        i = readUnsignedShort(v);
-        v += 2;
-        for (; i > 0; --i) {
-            j = readUnsignedShort(v + 6);
-            v += 8;
-            for (; j > 0; --j) {
-                v += 6 + readInt(v + 2);
-            }
-        }
-        i = readUnsignedShort(v);
-        v += 2;
-        for (; i > 0; --i) {
-            j = readUnsignedShort(v + 6);
-            v += 8;
-            for (; j > 0; --j) {
-                v += 6 + readInt(v + 2);
-            }
-        }
-
-        // read class attributes
-        i = readUnsignedShort(v);
-        v += 2;
-        for (; i > 0; --i) {
-            String attrName = readUTF8(v, buf);
-            int size = readInt(v + 2);
+    /**
+     * Copies the bootstrap method data into the given {@link ClassWriter}.
+     * Should be called before the {@link #accept(ClassVisitor,int)} method.
+     *
+     * @param classWriter
+     *            the {@link ClassWriter} to copy bootstrap methods into.
+     */
+    private void copyBootstrapMethods(final ClassWriter classWriter,
+            final Item[] items, final char[] c) {
+        // finds the "BootstrapMethods" attribute
+        int u = getAttributes();
+        boolean found = false;
+        for (int i = readUnsignedShort(u); i > 0; --i) {
+            String attrName = readUTF8(u + 2, c);
             if ("BootstrapMethods".equals(attrName)) {
-                int boostrapMethodCount = readUnsignedShort(v + 6);
-                int x = v + 8;
-                for (j = 0; j < boostrapMethodCount; j++) {
-                    int hashCode = readConst(readUnsignedShort(x), buf).hashCode();
-                    k = readUnsignedShort(x + 2);
-                    u = x + 4;
-                    for(; k > 0; --k) {
-                        hashCode ^= readConst(readUnsignedShort(u), buf).hashCode();
-                        u += 2;
-                    }
-                    Item item = new Item(j);
-                    item.set(x - v - 8, hashCode & 0x7FFFFFFF);
-
-                    int index2 = item.hashCode % items2.length;
-                    item.next = items2[index2];
-                    items2[index2] = item;
-
-                    x = u;
-                }
-
-                classWriter.bootstrapMethodsCount = boostrapMethodCount;
-                ByteVector bootstrapMethods = new ByteVector(size + 62);
-                bootstrapMethods.putByteArray(b, v + 8, size - 2);
-                classWriter.bootstrapMethods = bootstrapMethods;
-                return;
+                found = true;
+                break;
             }
-            v += 6 + size;
+            u += 6 + readInt(u + 4);
         }
-
-        // we are in trouble !!!
+        if (!found) {
+            return;
+        }
+        // copies the bootstrap methods in the class writer
+        int boostrapMethodCount = readUnsignedShort(u + 8);
+        for (int j = 0, v = u + 10; j < boostrapMethodCount; j++) {
+            int position = v - u - 10;
+            int hashCode = readConst(readUnsignedShort(v), c).hashCode();
+            for (int k = readUnsignedShort(v + 2); k > 0; --k) {
+                hashCode ^= readConst(readUnsignedShort(v + 4), c).hashCode();
+                v += 2;
+            }
+            v += 4;
+            Item item = new Item(j);
+            item.set(position, hashCode & 0x7FFFFFFF);
+            int index = item.hashCode % items.length;
+            item.next = items[index];
+            items[index] = item;
+        }
+        int attrSize = readInt(u + 4);
+        ByteVector bootstrapMethods = new ByteVector(attrSize + 62);
+        bootstrapMethods.putByteArray(b, u + 10, attrSize - 2);
+        classWriter.bootstrapMethodsCount = boostrapMethodCount;
+        classWriter.bootstrapMethods = bootstrapMethods;
     }
 
     /**
      * Constructs a new {@link ClassReader} object.
      *
-     * @param is an input stream from which to read the class.
-     * @throws IOException if a problem occurs during reading.
+     * @param is
+     *            an input stream from which to read the class.
+     * @throws IOException
+     *             if a problem occurs during reading.
      */
     public ClassReader(final InputStream is) throws IOException {
         this(readClass(is, false));
@@ -490,25 +456,30 @@
     /**
      * Constructs a new {@link ClassReader} object.
      *
-     * @param name the binary qualified name of the class to be read.
-     * @throws IOException if an exception occurs during reading.
+     * @param name
+     *            the binary qualified name of the class to be read.
+     * @throws IOException
+     *             if an exception occurs during reading.
      */
     public ClassReader(final String name) throws IOException {
-        this(readClass(ClassLoader.getSystemResourceAsStream(name.replace('.', '/')
-                + ".class"), true));
+        this(readClass(
+                ClassLoader.getSystemResourceAsStream(name.replace('.', '/')
+                        + ".class"), true));
     }
 
     /**
      * Reads the bytecode of a class.
      *
-     * @param is an input stream from which to read the class.
-     * @param close true to close the input stream after reading.
+     * @param is
+     *            an input stream from which to read the class.
+     * @param close
+     *            true to close the input stream after reading.
      * @return the bytecode read from the given input stream.
-     * @throws IOException if a problem occurs during reading.
+     * @throws IOException
+     *             if a problem occurs during reading.
      */
     private static byte[] readClass(final InputStream is, boolean close)
-            throws IOException
-    {
+            throws IOException {
         if (is == null) {
             throw new IOException("Class not found");
         }
@@ -549,14 +520,16 @@
     // ------------------------------------------------------------------------
 
     /**
-     * Makes the given visitor visit the Java class of this {@link ClassReader}.
-     * This class is the one specified in the constructor (see
+     * Makes the given visitor visit the Java class of this {@link ClassReader}
+     * . This class is the one specified in the constructor (see
      * {@link #ClassReader(byte[]) ClassReader}).
      *
-     * @param classVisitor the visitor that must visit this class.
-     * @param flags option flags that can be used to modify the default behavior
-     *        of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES},
-     *        {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
+     * @param classVisitor
+     *            the visitor that must visit this class.
+     * @param flags
+     *            option flags that can be used to modify the default behavior
+     *            of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES}
+     *            , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
      */
     public void accept(final ClassVisitor classVisitor, final int flags) {
         accept(classVisitor, new Attribute[0], flags);
@@ -567,1092 +540,186 @@
      * This class is the one specified in the constructor (see
      * {@link #ClassReader(byte[]) ClassReader}).
      *
-     * @param classVisitor the visitor that must visit this class.
-     * @param attrs prototypes of the attributes that must be parsed during the
-     *        visit of the class. Any attribute whose type is not equal to the
-     *        type of one the prototypes will not be parsed: its byte array
-     *        value will be passed unchanged to the ClassWriter. <i>This may
-     *        corrupt it if this value contains references to the constant pool,
-     *        or has syntactic or semantic links with a class element that has
-     *        been transformed by a class adapter between the reader and the
-     *        writer</i>.
-     * @param flags option flags that can be used to modify the default behavior
-     *        of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES},
-     *        {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
+     * @param classVisitor
+     *            the visitor that must visit this class.
+     * @param attrs
+     *            prototypes of the attributes that must be parsed during the
+     *            visit of the class. Any attribute whose type is not equal to
+     *            the type of one the prototypes will not be parsed: its byte
+     *            array value will be passed unchanged to the ClassWriter.
+     *            <i>This may corrupt it if this value contains references to
+     *            the constant pool, or has syntactic or semantic links with a
+     *            class element that has been transformed by a class adapter
+     *            between the reader and the writer</i>.
+     * @param flags
+     *            option flags that can be used to modify the default behavior
+     *            of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES}
+     *            , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
      */
-    public void accept(
-        final ClassVisitor classVisitor,
-        final Attribute[] attrs,
-        final int flags)
-    {
-        byte[] b = this.b; // the bytecode array
+    public void accept(final ClassVisitor classVisitor,
+            final Attribute[] attrs, final int flags) {
+        int u = header; // current offset in the class file
         char[] c = new char[maxStringLength]; // buffer used to read strings
-        int i, j, k; // loop variables
-        int u, v, w; // indexes in b
-        Attribute attr;
 
-        int access;
-        String name;
-        String desc;
-        String attrName;
-        String signature;
-        int anns = 0;
-        int ianns = 0;
-        Attribute cattrs = null;
+        Context context = new Context();
+        context.attrs = attrs;
+        context.flags = flags;
+        context.buffer = c;
 
-        // visits the header
-        u = header;
-        access = readUnsignedShort(u);
-        name = readClass(u + 2, c);
-        v = items[readUnsignedShort(u + 4)];
-        String superClassName = v == 0 ? null : readUTF8(v, c);
-        String[] implementedItfs = new String[readUnsignedShort(u + 6)];
-        w = 0;
+        // reads the class declaration
+        int access = readUnsignedShort(u);
+        String name = readClass(u + 2, c);
+        String superClass = readClass(u + 4, c);
+        String[] interfaces = new String[readUnsignedShort(u + 6)];
         u += 8;
-        for (i = 0; i < implementedItfs.length; ++i) {
-            implementedItfs[i] = readClass(u, c);
+        for (int i = 0; i < interfaces.length; ++i) {
+            interfaces[i] = readClass(u, c);
             u += 2;
         }
 
-        boolean skipCode = (flags & SKIP_CODE) != 0;
-        boolean skipDebug = (flags & SKIP_DEBUG) != 0;
-        boolean unzip = (flags & EXPAND_FRAMES) != 0;
-
-        // skips fields and methods
-        v = u;
-        i = readUnsignedShort(v);
-        v += 2;
-        for (; i > 0; --i) {
-            j = readUnsignedShort(v + 6);
-            v += 8;
-            for (; j > 0; --j) {
-                v += 6 + readInt(v + 2);
-            }
-        }
-        i = readUnsignedShort(v);
-        v += 2;
-        for (; i > 0; --i) {
-            j = readUnsignedShort(v + 6);
-            v += 8;
-            for (; j > 0; --j) {
-                v += 6 + readInt(v + 2);
-            }
-        }
-        // reads the class's attributes
-        signature = null;
+        // reads the class attributes
+        String signature = null;
         String sourceFile = null;
         String sourceDebug = null;
         String enclosingOwner = null;
         String enclosingName = null;
         String enclosingDesc = null;
-        int[] bootstrapMethods = null;  // start indexed of the bsms
+        int anns = 0;
+        int ianns = 0;
+        int tanns = 0;
+        int itanns = 0;
+        int innerClasses = 0;
+        Attribute attributes = null;
 
-        i = readUnsignedShort(v);
-        v += 2;
-        for (; i > 0; --i) {
-            attrName = readUTF8(v, c);
+        u = getAttributes();
+        for (int i = readUnsignedShort(u); i > 0; --i) {
+            String attrName = readUTF8(u + 2, c);
             // tests are sorted in decreasing frequency order
             // (based on frequencies observed on typical classes)
             if ("SourceFile".equals(attrName)) {
-                sourceFile = readUTF8(v + 6, c);
+                sourceFile = readUTF8(u + 8, c);
             } else if ("InnerClasses".equals(attrName)) {
-                w = v + 6;
+                innerClasses = u + 8;
             } else if ("EnclosingMethod".equals(attrName)) {
-                enclosingOwner = readClass(v + 6, c);
-                int item = readUnsignedShort(v + 8);
+                enclosingOwner = readClass(u + 8, c);
+                int item = readUnsignedShort(u + 10);
                 if (item != 0) {
                     enclosingName = readUTF8(items[item], c);
                     enclosingDesc = readUTF8(items[item] + 2, c);
                 }
             } else if (SIGNATURES && "Signature".equals(attrName)) {
-                signature = readUTF8(v + 6, c);
-            } else if (ANNOTATIONS && "RuntimeVisibleAnnotations".equals(attrName)) {
-                anns = v + 6;
+                signature = readUTF8(u + 8, c);
+            } else if (ANNOTATIONS
+                    && "RuntimeVisibleAnnotations".equals(attrName)) {
+                anns = u + 8;
+            } else if (ANNOTATIONS
+                    && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+                tanns = u + 8;
             } else if ("Deprecated".equals(attrName)) {
                 access |= Opcodes.ACC_DEPRECATED;
             } else if ("Synthetic".equals(attrName)) {
-                access |= Opcodes.ACC_SYNTHETIC | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
+                access |= Opcodes.ACC_SYNTHETIC
+                        | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
             } else if ("SourceDebugExtension".equals(attrName)) {
-                int len = readInt(v + 2);
-                sourceDebug = readUTF(v + 6, len, new char[len]);
-            } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) {
-                ianns = v + 6;
+                int len = readInt(u + 4);
+                sourceDebug = readUTF(u + 8, len, new char[len]);
+            } else if (ANNOTATIONS
+                    && "RuntimeInvisibleAnnotations".equals(attrName)) {
+                ianns = u + 8;
+            } else if (ANNOTATIONS
+                    && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+                itanns = u + 8;
             } else if ("BootstrapMethods".equals(attrName)) {
-                int boostrapMethodCount = readUnsignedShort(v + 6);
-                bootstrapMethods = new int[boostrapMethodCount];
-                int x = v + 8;
-                for (j = 0; j < boostrapMethodCount; j++) {
-                    bootstrapMethods[j] = x;
-                    x += 2 + readUnsignedShort(x + 2) << 1;
+                int[] bootstrapMethods = new int[readUnsignedShort(u + 8)];
+                for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) {
+                    bootstrapMethods[j] = v;
+                    v += 2 + readUnsignedShort(v + 2) << 1;
                 }
+                context.bootstrapMethods = bootstrapMethods;
             } else {
-                attr = readAttribute(attrs,
-                        attrName,
-                        v + 6,
-                        readInt(v + 2),
-                        c,
-                        -1,
-                        null);
+                Attribute attr = readAttribute(attrs, attrName, u + 8,
+                        readInt(u + 4), c, -1, null);
                 if (attr != null) {
-                    attr.next = cattrs;
-                    cattrs = attr;
+                    attr.next = attributes;
+                    attributes = attr;
                 }
             }
-            v += 6 + readInt(v + 2);
+            u += 6 + readInt(u + 4);
         }
-        // calls the visit method
-        classVisitor.visit(readInt(4),
-                access,
-                name,
-                signature,
-                superClassName,
-                implementedItfs);
 
-        // calls the visitSource method
-        if (!skipDebug && (sourceFile != null || sourceDebug != null)) {
+        // visits the class declaration
+        classVisitor.visit(readInt(items[1] - 7), access, name, signature,
+                superClass, interfaces);
+
+        // visits the source and debug info
+        if ((flags & SKIP_DEBUG) == 0
+                && (sourceFile != null || sourceDebug != null)) {
             classVisitor.visitSource(sourceFile, sourceDebug);
         }
 
-        // calls the visitOuterClass method
+        // visits the outer class
         if (enclosingOwner != null) {
-            classVisitor.visitOuterClass(enclosingOwner,
-                    enclosingName,
+            classVisitor.visitOuterClass(enclosingOwner, enclosingName,
                     enclosingDesc);
         }
 
-        // visits the class annotations
-        if (ANNOTATIONS) {
-            for (i = 1; i >= 0; --i) {
-                v = i == 0 ? ianns : anns;
-                if (v != 0) {
-                    j = readUnsignedShort(v);
-                    v += 2;
-                    for (; j > 0; --j) {
-                        v = readAnnotationValues(v + 2,
-                                c,
-                                true,
-                                classVisitor.visitAnnotation(readUTF8(v, c), i != 0));
-                    }
-                }
+        // visits the class annotations and type annotations
+        if (ANNOTATIONS && anns != 0) {
+            for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
+                v = readAnnotationValues(v + 2, c, true,
+                        classVisitor.visitAnnotation(readUTF8(v, c), true));
+            }
+        }
+        if (ANNOTATIONS && ianns != 0) {
+            for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
+                v = readAnnotationValues(v + 2, c, true,
+                        classVisitor.visitAnnotation(readUTF8(v, c), false));
+            }
+        }
+        if (ANNOTATIONS && tanns != 0) {
+            for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
+                v = readAnnotationTarget(context, v);
+                v = readAnnotationValues(v + 2, c, true,
+                        classVisitor.visitTypeAnnotation(context.typeRef,
+                                context.typePath, readUTF8(v, c), true));
+            }
+        }
+        if (ANNOTATIONS && itanns != 0) {
+            for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
+                v = readAnnotationTarget(context, v);
+                v = readAnnotationValues(v + 2, c, true,
+                        classVisitor.visitTypeAnnotation(context.typeRef,
+                                context.typePath, readUTF8(v, c), false));
             }
         }
 
-        // visits the class attributes
-        while (cattrs != null) {
-            attr = cattrs.next;
-            cattrs.next = null;
-            classVisitor.visitAttribute(cattrs);
-            cattrs = attr;
+        // visits the attributes
+        while (attributes != null) {
+            Attribute attr = attributes.next;
+            attributes.next = null;
+            classVisitor.visitAttribute(attributes);
+            attributes = attr;
         }
 
-        // calls the visitInnerClass method
-        if (w != 0) {
-            i = readUnsignedShort(w);
-            w += 2;
-            for (; i > 0; --i) {
-                classVisitor.visitInnerClass(readUnsignedShort(w) == 0
-                        ? null
-                        : readClass(w, c), readUnsignedShort(w + 2) == 0
-                        ? null
-                        : readClass(w + 2, c), readUnsignedShort(w + 4) == 0
-                        ? null
-                        : readUTF8(w + 4, c), readUnsignedShort(w + 6));
-                w += 8;
-            }
-        }
-
-        // visits the fields
-        i = readUnsignedShort(u);
-        u += 2;
-        for (; i > 0; --i) {
-            access = readUnsignedShort(u);
-            name = readUTF8(u + 2, c);
-            desc = readUTF8(u + 4, c);
-            // visits the field's attributes and looks for a ConstantValue
-            // attribute
-            int fieldValueItem = 0;
-            signature = null;
-            anns = 0;
-            ianns = 0;
-            cattrs = null;
-
-            j = readUnsignedShort(u + 6);
-            u += 8;
-            for (; j > 0; --j) {
-                attrName = readUTF8(u, c);
-                // tests are sorted in decreasing frequency order
-                // (based on frequencies observed on typical classes)
-                if ("ConstantValue".equals(attrName)) {
-                    fieldValueItem = readUnsignedShort(u + 6);
-                } else if (SIGNATURES && "Signature".equals(attrName)) {
-                    signature = readUTF8(u + 6, c);
-                } else if ("Deprecated".equals(attrName)) {
-                    access |= Opcodes.ACC_DEPRECATED;
-                } else if ("Synthetic".equals(attrName)) {
-                    access |= Opcodes.ACC_SYNTHETIC  | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
-                } else if (ANNOTATIONS && "RuntimeVisibleAnnotations".equals(attrName)) {
-                    anns = u + 6;
-                } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) {
-                    ianns = u + 6;
-                } else {
-                    attr = readAttribute(attrs,
-                            attrName,
-                            u + 6,
-                            readInt(u + 2),
-                            c,
-                            -1,
-                            null);
-                    if (attr != null) {
-                        attr.next = cattrs;
-                        cattrs = attr;
-                    }
-                }
-                u += 6 + readInt(u + 2);
-            }
-            // visits the field
-            FieldVisitor fv = classVisitor.visitField(access,
-                    name,
-                    desc,
-                    signature,
-                    fieldValueItem == 0 ? null : readConst(fieldValueItem, c));
-            // visits the field annotations and attributes
-            if (fv != null) {
-                if (ANNOTATIONS) {
-                    for (j = 1; j >= 0; --j) {
-                        v = j == 0 ? ianns : anns;
-                        if (v != 0) {
-                            k = readUnsignedShort(v);
-                            v += 2;
-                            for (; k > 0; --k) {
-                                v = readAnnotationValues(v + 2,
-                                        c,
-                                        true,
-                                        fv.visitAnnotation(readUTF8(v, c), j != 0));
-                            }
-                        }
-                    }
-                }
-                while (cattrs != null) {
-                    attr = cattrs.next;
-                    cattrs.next = null;
-                    fv.visitAttribute(cattrs);
-                    cattrs = attr;
-                }
-                fv.visitEnd();
-            }
-        }
-
-        // visits the methods
-        i = readUnsignedShort(u);
-        u += 2;
-        for (; i > 0; --i) {
-            int u0 = u + 6;
-            access = readUnsignedShort(u);
-            name = readUTF8(u + 2, c);
-            desc = readUTF8(u + 4, c);
-            signature = null;
-            anns = 0;
-            ianns = 0;
-            int dann = 0;
-            int mpanns = 0;
-            int impanns = 0;
-            cattrs = null;
-            v = 0;
-            w = 0;
-
-            // looks for Code and Exceptions attributes
-            j = readUnsignedShort(u + 6);
-            u += 8;
-            for (; j > 0; --j) {
-                attrName = readUTF8(u, c);
-                int attrSize = readInt(u + 2);
-                u += 6;
-                // tests are sorted in decreasing frequency order
-                // (based on frequencies observed on typical classes)
-                if ("Code".equals(attrName)) {
-                    if (!skipCode) {
-                        v = u;
-                    }
-                } else if ("Exceptions".equals(attrName)) {
-                    w = u;
-                } else if (SIGNATURES && "Signature".equals(attrName)) {
-                    signature = readUTF8(u, c);
-                } else if ("Deprecated".equals(attrName)) {
-                    access |= Opcodes.ACC_DEPRECATED;
-                } else if (ANNOTATIONS && "RuntimeVisibleAnnotations".equals(attrName)) {
-                    anns = u;
-                } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
-                    dann = u;
-                } else if ("Synthetic".equals(attrName)) {
-                    access |= Opcodes.ACC_SYNTHETIC | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
-                } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) {
-                    ianns = u;
-                } else if (ANNOTATIONS && "RuntimeVisibleParameterAnnotations".equals(attrName))
-                {
-                    mpanns = u;
-                } else if (ANNOTATIONS && "RuntimeInvisibleParameterAnnotations".equals(attrName))
-                {
-                    impanns = u;
-                } else {
-                    attr = readAttribute(attrs,
-                            attrName,
-                            u,
-                            attrSize,
-                            c,
-                            -1,
-                            null);
-                    if (attr != null) {
-                        attr.next = cattrs;
-                        cattrs = attr;
-                    }
-                }
-                u += attrSize;
-            }
-            // reads declared exceptions
-            String[] exceptions;
-            if (w == 0) {
-                exceptions = null;
-            } else {
-                exceptions = new String[readUnsignedShort(w)];
-                w += 2;
-                for (j = 0; j < exceptions.length; ++j) {
-                    exceptions[j] = readClass(w, c);
-                    w += 2;
-                }
-            }
-
-            // visits the method's code, if any
-            MethodVisitor mv = classVisitor.visitMethod(access,
-                    name,
-                    desc,
-                    signature,
-                    exceptions);
-
-            if (mv != null) {
-                /*
-                 * if the returned MethodVisitor is in fact a MethodWriter, it
-                 * means there is no method adapter between the reader and the
-                 * writer. If, in addition, the writer's constant pool was
-                 * copied from this reader (mw.cw.cr == this), and the signature
-                 * and exceptions of the method have not been changed, then it
-                 * is possible to skip all visit events and just copy the
-                 * original code of the method to the writer (the access, name
-                 * and descriptor can have been changed, this is not important
-                 * since they are not copied as is from the reader).
-                 */
-                if (WRITER && mv instanceof MethodWriter) {
-                    MethodWriter mw = (MethodWriter) mv;
-                    if (mw.cw.cr == this) {
-                        if (signature == mw.signature) {
-                            boolean sameExceptions = false;
-                            if (exceptions == null) {
-                                sameExceptions = mw.exceptionCount == 0;
-                            } else {
-                                if (exceptions.length == mw.exceptionCount) {
-                                    sameExceptions = true;
-                                    for (j = exceptions.length - 1; j >= 0; --j)
-                                    {
-                                        w -= 2;
-                                        if (mw.exceptions[j] != readUnsignedShort(w))
-                                        {
-                                            sameExceptions = false;
-                                            break;
-                                        }
-                                    }
-                                }
-                            }
-                            if (sameExceptions) {
-                                /*
-                                 * we do not copy directly the code into
-                                 * MethodWriter to save a byte array copy
-                                 * operation. The real copy will be done in
-                                 * ClassWriter.toByteArray().
-                                 */
-                                mw.classReaderOffset = u0;
-                                mw.classReaderLength = u - u0;
-                                continue;
-                            }
-                        }
-                    }
-                }
-
-                if (ANNOTATIONS && dann != 0) {
-                    AnnotationVisitor dv = mv.visitAnnotationDefault();
-                    readAnnotationValue(dann, c, null, dv);
-                    if (dv != null) {
-                        dv.visitEnd();
-                    }
-                }
-                if (ANNOTATIONS) {
-                    for (j = 1; j >= 0; --j) {
-                        w = j == 0 ? ianns : anns;
-                        if (w != 0) {
-                            k = readUnsignedShort(w);
-                            w += 2;
-                            for (; k > 0; --k) {
-                                w = readAnnotationValues(w + 2,
-                                        c,
-                                        true,
-                                        mv.visitAnnotation(readUTF8(w, c), j != 0));
-                            }
-                        }
-                    }
-                }
-                if (ANNOTATIONS && mpanns != 0) {
-                    readParameterAnnotations(mpanns, desc, c, true, mv);
-                }
-                if (ANNOTATIONS && impanns != 0) {
-                    readParameterAnnotations(impanns, desc, c, false, mv);
-                }
-                while (cattrs != null) {
-                    attr = cattrs.next;
-                    cattrs.next = null;
-                    mv.visitAttribute(cattrs);
-                    cattrs = attr;
-                }
-            }
-
-            if (mv != null && v != 0) {
-                int maxStack = readUnsignedShort(v);
-                int maxLocals = readUnsignedShort(v + 2);
-                int codeLength = readInt(v + 4);
+        // visits the inner classes
+        if (innerClasses != 0) {
+            int v = innerClasses + 2;
+            for (int i = readUnsignedShort(innerClasses); i > 0; --i) {
+                classVisitor.visitInnerClass(readClass(v, c),
+                        readClass(v + 2, c), readUTF8(v + 4, c),
+                        readUnsignedShort(v + 6));
                 v += 8;
-
-                int codeStart = v;
-                int codeEnd = v + codeLength;
-
-                mv.visitCode();
-
-                // 1st phase: finds the labels
-                int label;
-                Label[] labels = new Label[codeLength + 2];
-                readLabel(codeLength + 1, labels);
-                while (v < codeEnd) {
-                    w = v - codeStart;
-                    int opcode = b[v] & 0xFF;
-                    switch (ClassWriter.TYPE[opcode]) {
-                        case ClassWriter.NOARG_INSN:
-                        case ClassWriter.IMPLVAR_INSN:
-                            v += 1;
-                            break;
-                        case ClassWriter.LABEL_INSN:
-                            readLabel(w + readShort(v + 1), labels);
-                            v += 3;
-                            break;
-                        case ClassWriter.LABELW_INSN:
-                            readLabel(w + readInt(v + 1), labels);
-                            v += 5;
-                            break;
-                        case ClassWriter.WIDE_INSN:
-                            opcode = b[v + 1] & 0xFF;
-                            if (opcode == Opcodes.IINC) {
-                                v += 6;
-                            } else {
-                                v += 4;
-                            }
-                            break;
-                        case ClassWriter.TABL_INSN:
-                            // skips 0 to 3 padding bytes*
-                            v = v + 4 - (w & 3);
-                            // reads instruction
-                            readLabel(w + readInt(v), labels);
-                            j = readInt(v + 8) - readInt(v + 4) + 1;
-                            v += 12;
-                            for (; j > 0; --j) {
-                                readLabel(w + readInt(v), labels);
-                                v += 4;
-                            }
-                            break;
-                        case ClassWriter.LOOK_INSN:
-                            // skips 0 to 3 padding bytes*
-                            v = v + 4 - (w & 3);
-                            // reads instruction
-                            readLabel(w + readInt(v), labels);
-                            j = readInt(v + 4);
-                            v += 8;
-                            for (; j > 0; --j) {
-                                readLabel(w + readInt(v + 4), labels);
-                                v += 8;
-                            }
-                            break;
-                        case ClassWriter.VAR_INSN:
-                        case ClassWriter.SBYTE_INSN:
-                        case ClassWriter.LDC_INSN:
-                            v += 2;
-                            break;
-                        case ClassWriter.SHORT_INSN:
-                        case ClassWriter.LDCW_INSN:
-                        case ClassWriter.FIELDORMETH_INSN:
-                        case ClassWriter.TYPE_INSN:
-                        case ClassWriter.IINC_INSN:
-                            v += 3;
-                            break;
-                        case ClassWriter.ITFMETH_INSN:
-                        case ClassWriter.INDYMETH_INSN:
-                            v += 5;
-                            break;
-                        // case MANA_INSN:
-                        default:
-                            v += 4;
-                            break;
-                    }
-                }
-                // parses the try catch entries
-                j = readUnsignedShort(v);
-                v += 2;
-                for (; j > 0; --j) {
-                    Label start = readLabel(readUnsignedShort(v), labels);
-                    Label end = readLabel(readUnsignedShort(v + 2), labels);
-                    Label handler = readLabel(readUnsignedShort(v + 4), labels);
-                    int type = readUnsignedShort(v + 6);
-                    if (type == 0) {
-                        mv.visitTryCatchBlock(start, end, handler, null);
-                    } else {
-                        mv.visitTryCatchBlock(start,
-                                end,
-                                handler,
-                                readUTF8(items[type], c));
-                    }
-                    v += 8;
-                }
-                // parses the local variable, line number tables, and code
-                // attributes
-                int varTable = 0;
-                int varTypeTable = 0;
-                int stackMap = 0;
-                int stackMapSize = 0;
-                int frameCount = 0;
-                int frameMode = 0;
-                int frameOffset = 0;
-                int frameLocalCount = 0;
-                int frameLocalDiff = 0;
-                int frameStackCount = 0;
-                Object[] frameLocal = null;
-                Object[] frameStack = null;
-                boolean zip = true;
-                cattrs = null;
-                j = readUnsignedShort(v);
-                v += 2;
-                for (; j > 0; --j) {
-                    attrName = readUTF8(v, c);
-                    if ("LocalVariableTable".equals(attrName)) {
-                        if (!skipDebug) {
-                            varTable = v + 6;
-                            k = readUnsignedShort(v + 6);
-                            w = v + 8;
-                            for (; k > 0; --k) {
-                                label = readUnsignedShort(w);
-                                if (labels[label] == null) {
-                                    readLabel(label, labels).status |= Label.DEBUG;
-                                }
-                                label += readUnsignedShort(w + 2);
-                                if (labels[label] == null) {
-                                    readLabel(label, labels).status |= Label.DEBUG;
-                                }
-                                w += 10;
-                            }
-                        }
-                    } else if ("LocalVariableTypeTable".equals(attrName)) {
-                        varTypeTable = v + 6;
-                    } else if ("LineNumberTable".equals(attrName)) {
-                        if (!skipDebug) {
-                            k = readUnsignedShort(v + 6);
-                            w = v + 8;
-                            for (; k > 0; --k) {
-                                label = readUnsignedShort(w);
-                                if (labels[label] == null) {
-                                    readLabel(label, labels).status |= Label.DEBUG;
-                                }
-                                labels[label].line = readUnsignedShort(w + 2);
-                                w += 4;
-                            }
-                        }
-                    } else if (FRAMES && "StackMapTable".equals(attrName)) {
-                        if ((flags & SKIP_FRAMES) == 0) {
-                            stackMap = v + 8;
-                            stackMapSize = readInt(v + 2);
-                            frameCount = readUnsignedShort(v + 6);
-                        }
-                        /*
-                         * here we do not extract the labels corresponding to
-                         * the attribute content. This would require a full
-                         * parsing of the attribute, which would need to be
-                         * repeated in the second phase (see below). Instead the
-                         * content of the attribute is read one frame at a time
-                         * (i.e. after a frame has been visited, the next frame
-                         * is read), and the labels it contains are also
-                         * extracted one frame at a time. Thanks to the ordering
-                         * of frames, having only a "one frame lookahead" is not
-                         * a problem, i.e. it is not possible to see an offset
-                         * smaller than the offset of the current insn and for
-                         * which no Label exist.
-                         */
-                        /*
-                         * This is not true for UNINITIALIZED type offsets. We
-                         * solve this by parsing the stack map table without a
-                         * full decoding (see below).
-                         */
-                    } else if (FRAMES && "StackMap".equals(attrName)) {
-                        if ((flags & SKIP_FRAMES) == 0) {
-                            stackMap = v + 8;
-                            stackMapSize = readInt(v + 2);
-                            frameCount = readUnsignedShort(v + 6);
-                            zip = false;
-                        }
-                        /*
-                         * IMPORTANT! here we assume that the frames are
-                         * ordered, as in the StackMapTable attribute, although
-                         * this is not guaranteed by the attribute format.
-                         */
-                    } else {
-                        for (k = 0; k < attrs.length; ++k) {
-                            if (attrs[k].type.equals(attrName)) {
-                                attr = attrs[k].read(this,
-                                        v + 6,
-                                        readInt(v + 2),
-                                        c,
-                                        codeStart - 8,
-                                        labels);
-                                if (attr != null) {
-                                    attr.next = cattrs;
-                                    cattrs = attr;
-                                }
-                            }
-                        }
-                    }
-                    v += 6 + readInt(v + 2);
-                }
-
-                // 2nd phase: visits each instruction
-                if (FRAMES && stackMap != 0) {
-                    // creates the very first (implicit) frame from the method
-                    // descriptor
-                    frameLocal = new Object[maxLocals];
-                    frameStack = new Object[maxStack];
-                    if (unzip) {
-                        int local = 0;
-                        if ((access & Opcodes.ACC_STATIC) == 0) {
-                            if ("<init>".equals(name)) {
-                                frameLocal[local++] = Opcodes.UNINITIALIZED_THIS;
-                            } else {
-                                frameLocal[local++] = readClass(header + 2, c);
-                            }
-                        }
-                        j = 1;
-                        loop: while (true) {
-                            k = j;
-                            switch (desc.charAt(j++)) {
-                                case 'Z':
-                                case 'C':
-                                case 'B':
-                                case 'S':
-                                case 'I':
-                                    frameLocal[local++] = Opcodes.INTEGER;
-                                    break;
-                                case 'F':
-                                    frameLocal[local++] = Opcodes.FLOAT;
-                                    break;
-                                case 'J':
-                                    frameLocal[local++] = Opcodes.LONG;
-                                    break;
-                                case 'D':
-                                    frameLocal[local++] = Opcodes.DOUBLE;
-                                    break;
-                                case '[':
-                                    while (desc.charAt(j) == '[') {
-                                        ++j;
-                                    }
-                                    if (desc.charAt(j) == 'L') {
-                                        ++j;
-                                        while (desc.charAt(j) != ';') {
-                                            ++j;
-                                        }
-                                    }
-                                    frameLocal[local++] = desc.substring(k, ++j);
-                                    break;
-                                case 'L':
-                                    while (desc.charAt(j) != ';') {
-                                        ++j;
-                                    }
-                                    frameLocal[local++] = desc.substring(k + 1,
-                                            j++);
-                                    break;
-                                default:
-                                    break loop;
-                            }
-                        }
-                        frameLocalCount = local;
-                    }
-                    /*
-                     * for the first explicit frame the offset is not
-                     * offset_delta + 1 but only offset_delta; setting the
-                     * implicit frame offset to -1 allow the use of the
-                     * "offset_delta + 1" rule in all cases
-                     */
-                    frameOffset = -1;
-                    /*
-                     * Finds labels for UNINITIALIZED frame types. Instead of
-                     * decoding each element of the stack map table, we look
-                     * for 3 consecutive bytes that "look like" an UNINITIALIZED
-                     * type (tag 8, offset within code bounds, NEW instruction
-                     * at this offset). We may find false positives (i.e. not
-                     * real UNINITIALIZED types), but this should be rare, and
-                     * the only consequence will be the creation of an unneeded
-                     * label. This is better than creating a label for each NEW
-                     * instruction, and faster than fully decoding the whole
-                     * stack map table.
-                     */
-                    for (j = stackMap; j < stackMap + stackMapSize - 2; ++j) {
-                        if (b[j] == 8) { // UNINITIALIZED FRAME TYPE
-                            k = readUnsignedShort(j + 1);
-                            if (k >= 0 && k < codeLength) { // potential offset
-                                if ((b[codeStart + k] & 0xFF) == Opcodes.NEW) { // NEW at this offset
-                                    readLabel(k, labels);
-                                }
-                            }
-                        }
-                    }
-                }
-                v = codeStart;
-                Label l;
-                while (v < codeEnd) {
-                    w = v - codeStart;
-
-                    l = labels[w];
-                    if (l != null) {
-                        mv.visitLabel(l);
-                        if (!skipDebug && l.line > 0) {
-                            mv.visitLineNumber(l.line, l);
-                        }
-                    }
-
-                    while (FRAMES && frameLocal != null
-                            && (frameOffset == w || frameOffset == -1))
-                    {
-                        // if there is a frame for this offset,
-                        // makes the visitor visit it,
-                        // and reads the next frame if there is one.
-                        if (!zip || unzip) {
-                            mv.visitFrame(Opcodes.F_NEW,
-                                    frameLocalCount,
-                                    frameLocal,
-                                    frameStackCount,
-                                    frameStack);
-                        } else if (frameOffset != -1) {
-                            mv.visitFrame(frameMode,
-                                    frameLocalDiff,
-                                    frameLocal,
-                                    frameStackCount,
-                                    frameStack);
-                        }
-
-                        if (frameCount > 0) {
-                            int tag, delta, n;
-                            if (zip) {
-                                tag = b[stackMap++] & 0xFF;
-                            } else {
-                                tag = MethodWriter.FULL_FRAME;
-                                frameOffset = -1;
-                            }
-                            frameLocalDiff = 0;
-                            if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME)
-                            {
-                                delta = tag;
-                                frameMode = Opcodes.F_SAME;
-                                frameStackCount = 0;
-                            } else if (tag < MethodWriter.RESERVED) {
-                                delta = tag
-                                        - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME;
-                                stackMap = readFrameType(frameStack,
-                                        0,
-                                        stackMap,
-                                        c,
-                                        labels);
-                                frameMode = Opcodes.F_SAME1;
-                                frameStackCount = 1;
-                            } else {
-                                delta = readUnsignedShort(stackMap);
-                                stackMap += 2;
-                                if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
-                                {
-                                    stackMap = readFrameType(frameStack,
-                                            0,
-                                            stackMap,
-                                            c,
-                                            labels);
-                                    frameMode = Opcodes.F_SAME1;
-                                    frameStackCount = 1;
-                                } else if (tag >= MethodWriter.CHOP_FRAME
-                                        && tag < MethodWriter.SAME_FRAME_EXTENDED)
-                                {
-                                    frameMode = Opcodes.F_CHOP;
-                                    frameLocalDiff = MethodWriter.SAME_FRAME_EXTENDED
-                                            - tag;
-                                    frameLocalCount -= frameLocalDiff;
-                                    frameStackCount = 0;
-                                } else if (tag == MethodWriter.SAME_FRAME_EXTENDED)
-                                {
-                                    frameMode = Opcodes.F_SAME;
-                                    frameStackCount = 0;
-                                } else if (tag < MethodWriter.FULL_FRAME) {
-                                    j = unzip ? frameLocalCount : 0;
-                                    for (k = tag
-                                            - MethodWriter.SAME_FRAME_EXTENDED; k > 0; k--)
-                                    {
-                                        stackMap = readFrameType(frameLocal,
-                                                j++,
-                                                stackMap,
-                                                c,
-                                                labels);
-                                    }
-                                    frameMode = Opcodes.F_APPEND;
-                                    frameLocalDiff = tag
-                                            - MethodWriter.SAME_FRAME_EXTENDED;
-                                    frameLocalCount += frameLocalDiff;
-                                    frameStackCount = 0;
-                                } else { // if (tag == FULL_FRAME) {
-                                    frameMode = Opcodes.F_FULL;
-                                    n = frameLocalDiff = frameLocalCount = readUnsignedShort(stackMap);
-                                    stackMap += 2;
-                                    for (j = 0; n > 0; n--) {
-                                        stackMap = readFrameType(frameLocal,
-                                                j++,
-                                                stackMap,
-                                                c,
-                                                labels);
-                                    }
-                                    n = frameStackCount = readUnsignedShort(stackMap);
-                                    stackMap += 2;
-                                    for (j = 0; n > 0; n--) {
-                                        stackMap = readFrameType(frameStack,
-                                                j++,
-                                                stackMap,
-                                                c,
-                                                labels);
-                                    }
-                                }
-                            }
-                            frameOffset += delta + 1;
-                            readLabel(frameOffset, labels);
-
-                            --frameCount;
-                        } else {
-                            frameLocal = null;
-                        }
-                    }
-
-                    int opcode = b[v] & 0xFF;
-                    switch (ClassWriter.TYPE[opcode]) {
-                        case ClassWriter.NOARG_INSN:
-                            mv.visitInsn(opcode);
-                            v += 1;
-                            break;
-                        case ClassWriter.IMPLVAR_INSN:
-                            if (opcode > Opcodes.ISTORE) {
-                                opcode -= 59; // ISTORE_0
-                                mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2),
-                                        opcode & 0x3);
-                            } else {
-                                opcode -= 26; // ILOAD_0
-                                mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2),
-                                        opcode & 0x3);
-                            }
-                            v += 1;
-                            break;
-                        case ClassWriter.LABEL_INSN:
-                            mv.visitJumpInsn(opcode, labels[w
-                                    + readShort(v + 1)]);
-                            v += 3;
-                            break;
-                        case ClassWriter.LABELW_INSN:
-                            mv.visitJumpInsn(opcode - 33, labels[w
-                                    + readInt(v + 1)]);
-                            v += 5;
-                            break;
-                        case ClassWriter.WIDE_INSN:
-                            opcode = b[v + 1] & 0xFF;
-                            if (opcode == Opcodes.IINC) {
-                                mv.visitIincInsn(readUnsignedShort(v + 2),
-                                        readShort(v + 4));
-                                v += 6;
-                            } else {
-                                mv.visitVarInsn(opcode,
-                                        readUnsignedShort(v + 2));
-                                v += 4;
-                            }
-                            break;
-                        case ClassWriter.TABL_INSN:
-                            // skips 0 to 3 padding bytes
-                            v = v + 4 - (w & 3);
-                            // reads instruction
-                            label = w + readInt(v);
-                            int min = readInt(v + 4);
-                            int max = readInt(v + 8);
-                            v += 12;
-                            Label[] table = new Label[max - min + 1];
-                            for (j = 0; j < table.length; ++j) {
-                                table[j] = labels[w + readInt(v)];
-                                v += 4;
-                            }
-                            mv.visitTableSwitchInsn(min,
-                                    max,
-                                    labels[label],
-                                    table);
-                            break;
-                        case ClassWriter.LOOK_INSN:
-                            // skips 0 to 3 padding bytes
-                            v = v + 4 - (w & 3);
-                            // reads instruction
-                            label = w + readInt(v);
-                            j = readInt(v + 4);
-                            v += 8;
-                            int[] keys = new int[j];
-                            Label[] values = new Label[j];
-                            for (j = 0; j < keys.length; ++j) {
-                                keys[j] = readInt(v);
-                                values[j] = labels[w + readInt(v + 4)];
-                                v += 8;
-                            }
-                            mv.visitLookupSwitchInsn(labels[label],
-                                    keys,
-                                    values);
-                            break;
-                        case ClassWriter.VAR_INSN:
-                            mv.visitVarInsn(opcode, b[v + 1] & 0xFF);
-                            v += 2;
-                            break;
-                        case ClassWriter.SBYTE_INSN:
-                            mv.visitIntInsn(opcode, b[v + 1]);
-                            v += 2;
-                            break;
-                        case ClassWriter.SHORT_INSN:
-                            mv.visitIntInsn(opcode, readShort(v + 1));
-                            v += 3;
-                            break;
-                        case ClassWriter.LDC_INSN:
-                            mv.visitLdcInsn(readConst(b[v + 1] & 0xFF, c));
-                            v += 2;
-                            break;
-                        case ClassWriter.LDCW_INSN:
-                            mv.visitLdcInsn(readConst(readUnsignedShort(v + 1),
-                                    c));
-                            v += 3;
-                            break;
-                        case ClassWriter.FIELDORMETH_INSN:
-                        case ClassWriter.ITFMETH_INSN: {
-                            int cpIndex = items[readUnsignedShort(v + 1)];
-                            String iowner = readClass(cpIndex, c);
-                            cpIndex = items[readUnsignedShort(cpIndex + 2)];
-                            String iname = readUTF8(cpIndex, c);
-                            String idesc = readUTF8(cpIndex + 2, c);
-                            if (opcode < Opcodes.INVOKEVIRTUAL) {
-                                mv.visitFieldInsn(opcode, iowner, iname, idesc);
-                            } else {
-                                mv.visitMethodInsn(opcode, iowner, iname, idesc);
-                            }
-                            if (opcode == Opcodes.INVOKEINTERFACE) {
-                                v += 5;
-                            } else {
-                                v += 3;
-                            }
-                            break;
-                        }
-                        case ClassWriter.INDYMETH_INSN: {
-                            int cpIndex = items[readUnsignedShort(v + 1)];
-                            int bsmIndex = bootstrapMethods[readUnsignedShort(cpIndex)];
-                            cpIndex = items[readUnsignedShort(cpIndex + 2)];
-                            String iname = readUTF8(cpIndex, c);
-                            String idesc = readUTF8(cpIndex + 2, c);
-
-                            int mhIndex = readUnsignedShort(bsmIndex);
-                            Handle bsm = (Handle) readConst(mhIndex, c);
-                            int bsmArgCount = readUnsignedShort(bsmIndex + 2);
-                            Object[] bsmArgs = new Object[bsmArgCount];
-                            bsmIndex += 4;
-                            for(int a = 0; a < bsmArgCount; a++) {
-                                int argIndex = readUnsignedShort(bsmIndex);
-                                bsmArgs[a] = readConst(argIndex, c);
-                                bsmIndex += 2;
-                            }
-                            mv.visitInvokeDynamicInsn(iname, idesc, bsm, bsmArgs);
-
-                            v += 5;
-                            break;
-                        }
-                        case ClassWriter.TYPE_INSN:
-                            mv.visitTypeInsn(opcode, readClass(v + 1, c));
-                            v += 3;
-                            break;
-                        case ClassWriter.IINC_INSN:
-                            mv.visitIincInsn(b[v + 1] & 0xFF, b[v + 2]);
-                            v += 3;
-                            break;
-                        // case MANA_INSN:
-                        default:
-                            mv.visitMultiANewArrayInsn(readClass(v + 1, c),
-                                    b[v + 3] & 0xFF);
-                            v += 4;
-                            break;
-                    }
-                }
-                l = labels[codeEnd - codeStart];
-                if (l != null) {
-                    mv.visitLabel(l);
-                }
-                // visits the local variable tables
-                if (!skipDebug && varTable != 0) {
-                    int[] typeTable = null;
-                    if (varTypeTable != 0) {
-                        k = readUnsignedShort(varTypeTable) * 3;
-                        w = varTypeTable + 2;
-                        typeTable = new int[k];
-                        while (k > 0) {
-                            typeTable[--k] = w + 6; // signature
-                            typeTable[--k] = readUnsignedShort(w + 8); // index
-                            typeTable[--k] = readUnsignedShort(w); // start
-                            w += 10;
-                        }
-                    }
-                    k = readUnsignedShort(varTable);
-                    w = varTable + 2;
-                    for (; k > 0; --k) {
-                        int start = readUnsignedShort(w);
-                        int length = readUnsignedShort(w + 2);
-                        int index = readUnsignedShort(w + 8);
-                        String vsignature = null;
-                        if (typeTable != null) {
-                            for (int a = 0; a < typeTable.length; a += 3) {
-                                if (typeTable[a] == start
-                                        && typeTable[a + 1] == index)
-                                {
-                                    vsignature = readUTF8(typeTable[a + 2], c);
-                                    break;
-                                }
-                            }
-                        }
-                        mv.visitLocalVariable(readUTF8(w + 4, c),
-                                readUTF8(w + 6, c),
-                                vsignature,
-                                labels[start],
-                                labels[start + length],
-                                index);
-                        w += 10;
-                    }
-                }
-                // visits the other attributes
-                while (cattrs != null) {
-                    attr = cattrs.next;
-                    cattrs.next = null;
-                    mv.visitAttribute(cattrs);
-                    cattrs = attr;
-                }
-                // visits the max stack and max locals values
-                mv.visitMaxs(maxStack, maxLocals);
             }
+        }
 
-            if (mv != null) {
-                mv.visitEnd();
-            }
+        // visits the fields and methods
+        u = header + 10 + 2 * interfaces.length;
+        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+            u = readField(classVisitor, context, u);
+        }
+        u += 2;
+        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+            u = readMethod(classVisitor, context, u);
         }
 
         // visits the end of the class
@@ -1660,24 +727,1031 @@
     }
 
     /**
+     * Reads a field and makes the given visitor visit it.
+     *
+     * @param classVisitor
+     *            the visitor that must visit the field.
+     * @param context
+     *            information about the class being parsed.
+     * @param u
+     *            the start offset of the field in the class file.
+     * @return the offset of the first byte following the field in the class.
+     */
+    private int readField(final ClassVisitor classVisitor,
+            final Context context, int u) {
+        // reads the field declaration
+        char[] c = context.buffer;
+        int access = readUnsignedShort(u);
+        String name = readUTF8(u + 2, c);
+        String desc = readUTF8(u + 4, c);
+        u += 6;
+
+        // reads the field attributes
+        String signature = null;
+        int anns = 0;
+        int ianns = 0;
+        int tanns = 0;
+        int itanns = 0;
+        Object value = null;
+        Attribute attributes = null;
+
+        for (int i = readUnsignedShort(u); i > 0; --i) {
+            String attrName = readUTF8(u + 2, c);
+            // tests are sorted in decreasing frequency order
+            // (based on frequencies observed on typical classes)
+            if ("ConstantValue".equals(attrName)) {
+                int item = readUnsignedShort(u + 8);
+                value = item == 0 ? null : readConst(item, c);
+            } else if (SIGNATURES && "Signature".equals(attrName)) {
+                signature = readUTF8(u + 8, c);
+            } else if ("Deprecated".equals(attrName)) {
+                access |= Opcodes.ACC_DEPRECATED;
+            } else if ("Synthetic".equals(attrName)) {
+                access |= Opcodes.ACC_SYNTHETIC
+                        | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
+            } else if (ANNOTATIONS
+                    && "RuntimeVisibleAnnotations".equals(attrName)) {
+                anns = u + 8;
+            } else if (ANNOTATIONS
+                    && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+                tanns = u + 8;
+            } else if (ANNOTATIONS
+                    && "RuntimeInvisibleAnnotations".equals(attrName)) {
+                ianns = u + 8;
+            } else if (ANNOTATIONS
+                    && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+                itanns = u + 8;
+            } else {
+                Attribute attr = readAttribute(context.attrs, attrName, u + 8,
+                        readInt(u + 4), c, -1, null);
+                if (attr != null) {
+                    attr.next = attributes;
+                    attributes = attr;
+                }
+            }
+            u += 6 + readInt(u + 4);
+        }
+        u += 2;
+
+        // visits the field declaration
+        FieldVisitor fv = classVisitor.visitField(access, name, desc,
+                signature, value);
+        if (fv == null) {
+            return u;
+        }
+
+        // visits the field annotations and type annotations
+        if (ANNOTATIONS && anns != 0) {
+            for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
+                v = readAnnotationValues(v + 2, c, true,
+                        fv.visitAnnotation(readUTF8(v, c), true));
+            }
+        }
+        if (ANNOTATIONS && ianns != 0) {
+            for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
+                v = readAnnotationValues(v + 2, c, true,
+                        fv.visitAnnotation(readUTF8(v, c), false));
+            }
+        }
+        if (ANNOTATIONS && tanns != 0) {
+            for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
+                v = readAnnotationTarget(context, v);
+                v = readAnnotationValues(v + 2, c, true,
+                        fv.visitTypeAnnotation(context.typeRef,
+                                context.typePath, readUTF8(v, c), true));
+            }
+        }
+        if (ANNOTATIONS && itanns != 0) {
+            for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
+                v = readAnnotationTarget(context, v);
+                v = readAnnotationValues(v + 2, c, true,
+                        fv.visitTypeAnnotation(context.typeRef,
+                                context.typePath, readUTF8(v, c), false));
+            }
+        }
+
+        // visits the field attributes
+        while (attributes != null) {
+            Attribute attr = attributes.next;
+            attributes.next = null;
+            fv.visitAttribute(attributes);
+            attributes = attr;
+        }
+
+        // visits the end of the field
+        fv.visitEnd();
+
+        return u;
+    }
+
+    /**
+     * Reads a method and makes the given visitor visit it.
+     *
+     * @param classVisitor
+     *            the visitor that must visit the method.
+     * @param context
+     *            information about the class being parsed.
+     * @param u
+     *            the start offset of the method in the class file.
+     * @return the offset of the first byte following the method in the class.
+     */
+    private int readMethod(final ClassVisitor classVisitor,
+            final Context context, int u) {
+        // reads the method declaration
+        char[] c = context.buffer;
+        context.access = readUnsignedShort(u);
+        context.name = readUTF8(u + 2, c);
+        context.desc = readUTF8(u + 4, c);
+        u += 6;
+
+        // reads the method attributes
+        int code = 0;
+        int exception = 0;
+        String[] exceptions = null;
+        String signature = null;
+        int methodParameters = 0;
+        int anns = 0;
+        int ianns = 0;
+        int tanns = 0;
+        int itanns = 0;
+        int dann = 0;
+        int mpanns = 0;
+        int impanns = 0;
+        int firstAttribute = u;
+        Attribute attributes = null;
+
+        for (int i = readUnsignedShort(u); i > 0; --i) {
+            String attrName = readUTF8(u + 2, c);
+            // tests are sorted in decreasing frequency order
+            // (based on frequencies observed on typical classes)
+            if ("Code".equals(attrName)) {
+                if ((context.flags & SKIP_CODE) == 0) {
+                    code = u + 8;
+                }
+            } else if ("Exceptions".equals(attrName)) {
+                exceptions = new String[readUnsignedShort(u + 8)];
+                exception = u + 10;
+                for (int j = 0; j < exceptions.length; ++j) {
+                    exceptions[j] = readClass(exception, c);
+                    exception += 2;
+                }
+            } else if (SIGNATURES && "Signature".equals(attrName)) {
+                signature = readUTF8(u + 8, c);
+            } else if ("Deprecated".equals(attrName)) {
+                context.access |= Opcodes.ACC_DEPRECATED;
+            } else if (ANNOTATIONS
+                    && "RuntimeVisibleAnnotations".equals(attrName)) {
+                anns = u + 8;
+            } else if (ANNOTATIONS
+                    && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+                tanns = u + 8;
+            } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
+                dann = u + 8;
+            } else if ("Synthetic".equals(attrName)) {
+                context.access |= Opcodes.ACC_SYNTHETIC
+                        | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
+            } else if (ANNOTATIONS
+                    && "RuntimeInvisibleAnnotations".equals(attrName)) {
+                ianns = u + 8;
+            } else if (ANNOTATIONS
+                    && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+                itanns = u + 8;
+            } else if (ANNOTATIONS
+                    && "RuntimeVisibleParameterAnnotations".equals(attrName)) {
+                mpanns = u + 8;
+            } else if (ANNOTATIONS
+                    && "RuntimeInvisibleParameterAnnotations".equals(attrName)) {
+                impanns = u + 8;
+            } else if ("MethodParameters".equals(attrName)) {
+                methodParameters = u + 8;
+            } else {
+                Attribute attr = readAttribute(context.attrs, attrName, u + 8,
+                        readInt(u + 4), c, -1, null);
+                if (attr != null) {
+                    attr.next = attributes;
+                    attributes = attr;
+                }
+            }
+            u += 6 + readInt(u + 4);
+        }
+        u += 2;
+
+        // visits the method declaration
+        MethodVisitor mv = classVisitor.visitMethod(context.access,
+                context.name, context.desc, signature, exceptions);
+        if (mv == null) {
+            return u;
+        }
+
+        /*
+         * if the returned MethodVisitor is in fact a MethodWriter, it means
+         * there is no method adapter between the reader and the writer. If, in
+         * addition, the writer's constant pool was copied from this reader
+         * (mw.cw.cr == this), and the signature and exceptions of the method
+         * have not been changed, then it is possible to skip all visit events
+         * and just copy the original code of the method to the writer (the
+         * access, name and descriptor can have been changed, this is not
+         * important since they are not copied as is from the reader).
+         */
+        if (WRITER && mv instanceof MethodWriter) {
+            MethodWriter mw = (MethodWriter) mv;
+            if (mw.cw.cr == this && signature == mw.signature) {
+                boolean sameExceptions = false;
+                if (exceptions == null) {
+                    sameExceptions = mw.exceptionCount == 0;
+                } else if (exceptions.length == mw.exceptionCount) {
+                    sameExceptions = true;
+                    for (int j = exceptions.length - 1; j >= 0; --j) {
+                        exception -= 2;
+                        if (mw.exceptions[j] != readUnsignedShort(exception)) {
+                            sameExceptions = false;
+                            break;
+                        }
+                    }
+                }
+                if (sameExceptions) {
+                    /*
+                     * we do not copy directly the code into MethodWriter to
+                     * save a byte array copy operation. The real copy will be
+                     * done in ClassWriter.toByteArray().
+                     */
+                    mw.classReaderOffset = firstAttribute;
+                    mw.classReaderLength = u - firstAttribute;
+                    return u;
+                }
+            }
+        }
+
+        // visit the method parameters
+        if (methodParameters != 0) {
+            for (int i = b[methodParameters] & 0xFF, v = methodParameters + 1; i > 0; --i, v = v + 4) {
+                mv.visitParameter(readUTF8(v, c), readUnsignedShort(v + 2));
+            }
+        }
+
+        // visits the method annotations
+        if (ANNOTATIONS && dann != 0) {
+            AnnotationVisitor dv = mv.visitAnnotationDefault();
+            readAnnotationValue(dann, c, null, dv);
+            if (dv != null) {
+                dv.visitEnd();
+            }
+        }
+        if (ANNOTATIONS && anns != 0) {
+            for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
+                v = readAnnotationValues(v + 2, c, true,
+                        mv.visitAnnotation(readUTF8(v, c), true));
+            }
+        }
+        if (ANNOTATIONS && ianns != 0) {
+            for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
+                v = readAnnotationValues(v + 2, c, true,
+                        mv.visitAnnotation(readUTF8(v, c), false));
+            }
+        }
+        if (ANNOTATIONS && tanns != 0) {
+            for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
+                v = readAnnotationTarget(context, v);
+                v = readAnnotationValues(v + 2, c, true,
+                        mv.visitTypeAnnotation(context.typeRef,
+                                context.typePath, readUTF8(v, c), true));
+            }
+        }
+        if (ANNOTATIONS && itanns != 0) {
+            for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
+                v = readAnnotationTarget(context, v);
+                v = readAnnotationValues(v + 2, c, true,
+                        mv.visitTypeAnnotation(context.typeRef,
+                                context.typePath, readUTF8(v, c), false));
+            }
+        }
+        if (ANNOTATIONS && mpanns != 0) {
+            readParameterAnnotations(mv, context, mpanns, true);
+        }
+        if (ANNOTATIONS && impanns != 0) {
+            readParameterAnnotations(mv, context, impanns, false);
+        }
+
+        // visits the method attributes
+        while (attributes != null) {
+            Attribute attr = attributes.next;
+            attributes.next = null;
+            mv.visitAttribute(attributes);
+            attributes = attr;
+        }
+
+        // visits the method code
+        if (code != 0) {
+            mv.visitCode();
+            readCode(mv, context, code);
+        }
+
+        // visits the end of the method
+        mv.visitEnd();
+
+        return u;
+    }
+
+    /**
+     * Reads the bytecode of a method and makes the given visitor visit it.
+     *
+     * @param mv
+     *            the visitor that must visit the method's code.
+     * @param context
+     *            information about the class being parsed.
+     * @param u
+     *            the start offset of the code attribute in the class file.
+     */
+    private void readCode(final MethodVisitor mv, final Context context, int u) {
+        // reads the header
+        byte[] b = this.b;
+        char[] c = context.buffer;
+        int maxStack = readUnsignedShort(u);
+        int maxLocals = readUnsignedShort(u + 2);
+        int codeLength = readInt(u + 4);
+        u += 8;
+
+        // reads the bytecode to find the labels
+        int codeStart = u;
+        int codeEnd = u + codeLength;
+        Label[] labels = context.labels = new Label[codeLength + 2];
+        readLabel(codeLength + 1, labels);
+        while (u < codeEnd) {
+            int offset = u - codeStart;
+            int opcode = b[u] & 0xFF;
+            switch (ClassWriter.TYPE[opcode]) {
+            case ClassWriter.NOARG_INSN:
+            case ClassWriter.IMPLVAR_INSN:
+                u += 1;
+                break;
+            case ClassWriter.LABEL_INSN:
+                readLabel(offset + readShort(u + 1), labels);
+                u += 3;
+                break;
+            case ClassWriter.LABELW_INSN:
+                readLabel(offset + readInt(u + 1), labels);
+                u += 5;
+                break;
+            case ClassWriter.WIDE_INSN:
+                opcode = b[u + 1] & 0xFF;
+                if (opcode == Opcodes.IINC) {
+                    u += 6;
+                } else {
+                    u += 4;
+                }
+                break;
+            case ClassWriter.TABL_INSN:
+                // skips 0 to 3 padding bytes
+                u = u + 4 - (offset & 3);
+                // reads instruction
+                readLabel(offset + readInt(u), labels);
+                for (int i = readInt(u + 8) - readInt(u + 4) + 1; i > 0; --i) {
+                    readLabel(offset + readInt(u + 12), labels);
+                    u += 4;
+                }
+                u += 12;
+                break;
+            case ClassWriter.LOOK_INSN:
+                // skips 0 to 3 padding bytes
+                u = u + 4 - (offset & 3);
+                // reads instruction
+                readLabel(offset + readInt(u), labels);
+                for (int i = readInt(u + 4); i > 0; --i) {
+                    readLabel(offset + readInt(u + 12), labels);
+                    u += 8;
+                }
+                u += 8;
+                break;
+            case ClassWriter.VAR_INSN:
+            case ClassWriter.SBYTE_INSN:
+            case ClassWriter.LDC_INSN:
+                u += 2;
+                break;
+            case ClassWriter.SHORT_INSN:
+            case ClassWriter.LDCW_INSN:
+            case ClassWriter.FIELDORMETH_INSN:
+            case ClassWriter.TYPE_INSN:
+            case ClassWriter.IINC_INSN:
+                u += 3;
+                break;
+            case ClassWriter.ITFMETH_INSN:
+            case ClassWriter.INDYMETH_INSN:
+                u += 5;
+                break;
+            // case MANA_INSN:
+            default:
+                u += 4;
+                break;
+            }
+        }
+
+        // reads the try catch entries to find the labels, and also visits them
+        for (int i = readUnsignedShort(u); i > 0; --i) {
+            Label start = readLabel(readUnsignedShort(u + 2), labels);
+            Label end = readLabel(readUnsignedShort(u + 4), labels);
+            Label handler = readLabel(readUnsignedShort(u + 6), labels);
+            String type = readUTF8(items[readUnsignedShort(u + 8)], c);
+            mv.visitTryCatchBlock(start, end, handler, type);
+            u += 8;
+        }
+        u += 2;
+
+        // reads the code attributes
+        int[] tanns = null; // start index of each visible type annotation
+        int[] itanns = null; // start index of each invisible type annotation
+        int tann = 0; // current index in tanns array
+        int itann = 0; // current index in itanns array
+        int ntoff = -1; // next visible type annotation code offset
+        int nitoff = -1; // next invisible type annotation code offset
+        int varTable = 0;
+        int varTypeTable = 0;
+        boolean zip = true;
+        boolean unzip = (context.flags & EXPAND_FRAMES) != 0;
+        int stackMap = 0;
+        int stackMapSize = 0;
+        int frameCount = 0;
+        Context frame = null;
+        Attribute attributes = null;
+
+        for (int i = readUnsignedShort(u); i > 0; --i) {
+            String attrName = readUTF8(u + 2, c);
+            if ("LocalVariableTable".equals(attrName)) {
+                if ((context.flags & SKIP_DEBUG) == 0) {
+                    varTable = u + 8;
+                    for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
+                        int label = readUnsignedShort(v + 10);
+                        if (labels[label] == null) {
+                            readLabel(label, labels).status |= Label.DEBUG;
+                        }
+                        label += readUnsignedShort(v + 12);
+                        if (labels[label] == null) {
+                            readLabel(label, labels).status |= Label.DEBUG;
+                        }
+                        v += 10;
+                    }
+                }
+            } else if ("LocalVariableTypeTable".equals(attrName)) {
+                varTypeTable = u + 8;
+            } else if ("LineNumberTable".equals(attrName)) {
+                if ((context.flags & SKIP_DEBUG) == 0) {
+                    for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
+                        int label = readUnsignedShort(v + 10);
+                        if (labels[label] == null) {
+                            readLabel(label, labels).status |= Label.DEBUG;
+                        }
+                        labels[label].line = readUnsignedShort(v + 12);
+                        v += 4;
+                    }
+                }
+            } else if (ANNOTATIONS
+                    && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+                tanns = readTypeAnnotations(mv, context, u + 8, true);
+                ntoff = tanns.length == 0 || readByte(tanns[0]) < 0x43 ? -1
+                        : readUnsignedShort(tanns[0] + 1);
+            } else if (ANNOTATIONS
+                    && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+                itanns = readTypeAnnotations(mv, context, u + 8, false);
+                nitoff = itanns.length == 0 || readByte(itanns[0]) < 0x43 ? -1
+                        : readUnsignedShort(itanns[0] + 1);
+            } else if (FRAMES && "StackMapTable".equals(attrName)) {
+                if ((context.flags & SKIP_FRAMES) == 0) {
+                    stackMap = u + 10;
+                    stackMapSize = readInt(u + 4);
+                    frameCount = readUnsignedShort(u + 8);
+                }
+                /*
+                 * here we do not extract the labels corresponding to the
+                 * attribute content. This would require a full parsing of the
+                 * attribute, which would need to be repeated in the second
+                 * phase (see below). Instead the content of the attribute is
+                 * read one frame at a time (i.e. after a frame has been
+                 * visited, the next frame is read), and the labels it contains
+                 * are also extracted one frame at a time. Thanks to the
+                 * ordering of frames, having only a "one frame lookahead" is
+                 * not a problem, i.e. it is not possible to see an offset
+                 * smaller than the offset of the current insn and for which no
+                 * Label exist.
+                 */
+                /*
+                 * This is not true for UNINITIALIZED type offsets. We solve
+                 * this by parsing the stack map table without a full decoding
+                 * (see below).
+                 */
+            } else if (FRAMES && "StackMap".equals(attrName)) {
+                if ((context.flags & SKIP_FRAMES) == 0) {
+                    zip = false;
+                    stackMap = u + 10;
+                    stackMapSize = readInt(u + 4);
+                    frameCount = readUnsignedShort(u + 8);
+                }
+                /*
+                 * IMPORTANT! here we assume that the frames are ordered, as in
+                 * the StackMapTable attribute, although this is not guaranteed
+                 * by the attribute format.
+                 */
+            } else {
+                for (int j = 0; j < context.attrs.length; ++j) {
+                    if (context.attrs[j].type.equals(attrName)) {
+                        Attribute attr = context.attrs[j].read(this, u + 8,
+                                readInt(u + 4), c, codeStart - 8, labels);
+                        if (attr != null) {
+                            attr.next = attributes;
+                            attributes = attr;
+                        }
+                    }
+                }
+            }
+            u += 6 + readInt(u + 4);
+        }
+        u += 2;
+
+        // generates the first (implicit) stack map frame
+        if (FRAMES && (stackMap != 0 || unzip)) {
+            /*
+             * for the first explicit frame the offset is not offset_delta + 1
+             * but only offset_delta; setting the implicit frame offset to -1
+             * allow the use of the "offset_delta + 1" rule in all cases
+             */
+            frame = context;
+            frame.offset = -1;
+            frame.mode = 0;
+            frame.localCount = 0;
+            frame.localDiff = 0;
+            frame.stackCount = 0;
+            frame.local = new Object[maxLocals];
+            frame.stack = new Object[maxStack];
+            if (unzip) {
+                getImplicitFrame(context);
+            }
+        }
+        if (FRAMES && stackMap != 0) {
+            /*
+             * Finds labels for UNINITIALIZED frame types. Instead of decoding
+             * each element of the stack map table, we look for 3 consecutive
+             * bytes that "look like" an UNINITIALIZED type (tag 8, offset
+             * within code bounds, NEW instruction at this offset). We may find
+             * false positives (i.e. not real UNINITIALIZED types), but this
+             * should be rare, and the only consequence will be the creation of
+             * an unneeded label. This is better than creating a label for each
+             * NEW instruction, and faster than fully decoding the whole stack
+             * map table.
+             */
+            for (int i = stackMap; i < stackMap + stackMapSize - 2; ++i) {
+                if (b[i] == 8) { // UNINITIALIZED FRAME TYPE
+                    int v = readUnsignedShort(i + 1);
+                    if (v >= 0 && v < codeLength) {
+                        if ((b[codeStart + v] & 0xFF) == Opcodes.NEW) {
+                            readLabel(v, labels);
+                        }
+                    }
+                }
+            }
+        }
+
+        // visits the instructions
+        u = codeStart;
+        while (u < codeEnd) {
+            int offset = u - codeStart;
+
+            // visits the label and line number for this offset, if any
+            Label l = labels[offset];
+            if (l != null) {
+                mv.visitLabel(l);
+                if ((context.flags & SKIP_DEBUG) == 0 && l.line > 0) {
+                    mv.visitLineNumber(l.line, l);
+                }
+            }
+
+            // visits the frame(s) for this offset, if any
+            while (FRAMES && frame != null
+                    && (frame.offset == offset || frame.offset == -1)) {
+                // if there is a frame for this offset, makes the visitor visit
+                // it, and reads the next frame if there is one.
+                if (!zip || unzip) {
+                    mv.visitFrame(Opcodes.F_NEW, frame.localCount, frame.local,
+                            frame.stackCount, frame.stack);
+                } else if (frame.offset != -1) {
+                    mv.visitFrame(frame.mode, frame.localDiff, frame.local,
+                            frame.stackCount, frame.stack);
+                }
+                if (frameCount > 0) {
+                    stackMap = readFrame(stackMap, zip, unzip, frame);
+                    --frameCount;
+                } else {
+                    frame = null;
+                }
+            }
+
+            // visits the instruction at this offset
+            int opcode = b[u] & 0xFF;
+            switch (ClassWriter.TYPE[opcode]) {
+            case ClassWriter.NOARG_INSN:
+                mv.visitInsn(opcode);
+                u += 1;
+                break;
+            case ClassWriter.IMPLVAR_INSN:
+                if (opcode > Opcodes.ISTORE) {
+                    opcode -= 59; // ISTORE_0
+                    mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2),
+                            opcode & 0x3);
+                } else {
+                    opcode -= 26; // ILOAD_0
+                    mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2), opcode & 0x3);
+                }
+                u += 1;
+                break;
+            case ClassWriter.LABEL_INSN:
+                mv.visitJumpInsn(opcode, labels[offset + readShort(u + 1)]);
+                u += 3;
+                break;
+            case ClassWriter.LABELW_INSN:
+                mv.visitJumpInsn(opcode - 33, labels[offset + readInt(u + 1)]);
+                u += 5;
+                break;
+            case ClassWriter.WIDE_INSN:
+                opcode = b[u + 1] & 0xFF;
+                if (opcode == Opcodes.IINC) {
+                    mv.visitIincInsn(readUnsignedShort(u + 2), readShort(u + 4));
+                    u += 6;
+                } else {
+                    mv.visitVarInsn(opcode, readUnsignedShort(u + 2));
+                    u += 4;
+                }
+                break;
+            case ClassWriter.TABL_INSN: {
+                // skips 0 to 3 padding bytes
+                u = u + 4 - (offset & 3);
+                // reads instruction
+                int label = offset + readInt(u);
+                int min = readInt(u + 4);
+                int max = readInt(u + 8);
+                Label[] table = new Label[max - min + 1];
+                u += 12;
+                for (int i = 0; i < table.length; ++i) {
+                    table[i] = labels[offset + readInt(u)];
+                    u += 4;
+                }
+                mv.visitTableSwitchInsn(min, max, labels[label], table);
+                break;
+            }
+            case ClassWriter.LOOK_INSN: {
+                // skips 0 to 3 padding bytes
+                u = u + 4 - (offset & 3);
+                // reads instruction
+                int label = offset + readInt(u);
+                int len = readInt(u + 4);
+                int[] keys = new int[len];
+                Label[] values = new Label[len];
+                u += 8;
+                for (int i = 0; i < len; ++i) {
+                    keys[i] = readInt(u);
+                    values[i] = labels[offset + readInt(u + 4)];
+                    u += 8;
+                }
+                mv.visitLookupSwitchInsn(labels[label], keys, values);
+                break;
+            }
+            case ClassWriter.VAR_INSN:
+                mv.visitVarInsn(opcode, b[u + 1] & 0xFF);
+                u += 2;
+                break;
+            case ClassWriter.SBYTE_INSN:
+                mv.visitIntInsn(opcode, b[u + 1]);
+                u += 2;
+                break;
+            case ClassWriter.SHORT_INSN:
+                mv.visitIntInsn(opcode, readShort(u + 1));
+                u += 3;
+                break;
+            case ClassWriter.LDC_INSN:
+                mv.visitLdcInsn(readConst(b[u + 1] & 0xFF, c));
+                u += 2;
+                break;
+            case ClassWriter.LDCW_INSN:
+                mv.visitLdcInsn(readConst(readUnsignedShort(u + 1), c));
+                u += 3;
+                break;
+            case ClassWriter.FIELDORMETH_INSN:
+            case ClassWriter.ITFMETH_INSN: {
+                int cpIndex = items[readUnsignedShort(u + 1)];
+                String iowner = readClass(cpIndex, c);
+                cpIndex = items[readUnsignedShort(cpIndex + 2)];
+                String iname = readUTF8(cpIndex, c);
+                String idesc = readUTF8(cpIndex + 2, c);
+                if (opcode < Opcodes.INVOKEVIRTUAL) {
+                    mv.visitFieldInsn(opcode, iowner, iname, idesc);
+                } else {
+                    mv.visitMethodInsn(opcode, iowner, iname, idesc);
+                }
+                if (opcode == Opcodes.INVOKEINTERFACE) {
+                    u += 5;
+                } else {
+                    u += 3;
+                }
+                break;
+            }
+            case ClassWriter.INDYMETH_INSN: {
+                int cpIndex = items[readUnsignedShort(u + 1)];
+                int bsmIndex = context.bootstrapMethods[readUnsignedShort(cpIndex)];
+                Handle bsm = (Handle) readConst(readUnsignedShort(bsmIndex), c);
+                int bsmArgCount = readUnsignedShort(bsmIndex + 2);
+                Object[] bsmArgs = new Object[bsmArgCount];
+                bsmIndex += 4;
+                for (int i = 0; i < bsmArgCount; i++) {
+                    bsmArgs[i] = readConst(readUnsignedShort(bsmIndex), c);
+                    bsmIndex += 2;
+                }
+                cpIndex = items[readUnsignedShort(cpIndex + 2)];
+                String iname = readUTF8(cpIndex, c);
+                String idesc = readUTF8(cpIndex + 2, c);
+                mv.visitInvokeDynamicInsn(iname, idesc, bsm, bsmArgs);
+                u += 5;
+                break;
+            }
+            case ClassWriter.TYPE_INSN:
+                mv.visitTypeInsn(opcode, readClass(u + 1, c));
+                u += 3;
+                break;
+            case ClassWriter.IINC_INSN:
+                mv.visitIincInsn(b[u + 1] & 0xFF, b[u + 2]);
+                u += 3;
+                break;
+            // case MANA_INSN:
+            default:
+                mv.visitMultiANewArrayInsn(readClass(u + 1, c), b[u + 3] & 0xFF);
+                u += 4;
+                break;
+            }
+
+            // visit the instruction annotations, if any
+            while (tanns != null && tann < tanns.length && ntoff <= offset) {
+                if (ntoff == offset) {
+                    int v = readAnnotationTarget(context, tanns[tann]);
+                    readAnnotationValues(v + 2, c, true,
+                            mv.visitInsnAnnotation(context.typeRef,
+                                    context.typePath, readUTF8(v, c), true));
+                }
+                ntoff = ++tann >= tanns.length || readByte(tanns[tann]) < 0x43 ? -1
+                        : readUnsignedShort(tanns[tann] + 1);
+            }
+            while (itanns != null && itann < itanns.length && nitoff <= offset) {
+                if (nitoff == offset) {
+                    int v = readAnnotationTarget(context, itanns[itann]);
+                    readAnnotationValues(v + 2, c, true,
+                            mv.visitInsnAnnotation(context.typeRef,
+                                    context.typePath, readUTF8(v, c), false));
+                }
+                nitoff = ++itann >= itanns.length
+                        || readByte(itanns[itann]) < 0x43 ? -1
+                        : readUnsignedShort(itanns[itann] + 1);
+            }
+        }
+        if (labels[codeLength] != null) {
+            mv.visitLabel(labels[codeLength]);
+        }
+
+        // visits the local variable tables
+        if ((context.flags & SKIP_DEBUG) == 0 && varTable != 0) {
+            int[] typeTable = null;
+            if (varTypeTable != 0) {
+                u = varTypeTable + 2;
+                typeTable = new int[readUnsignedShort(varTypeTable) * 3];
+                for (int i = typeTable.length; i > 0;) {
+                    typeTable[--i] = u + 6; // signature
+                    typeTable[--i] = readUnsignedShort(u + 8); // index
+                    typeTable[--i] = readUnsignedShort(u); // start
+                    u += 10;
+                }
+            }
+            u = varTable + 2;
+            for (int i = readUnsignedShort(varTable); i > 0; --i) {
+                int start = readUnsignedShort(u);
+                int length = readUnsignedShort(u + 2);
+                int index = readUnsignedShort(u + 8);
+                String vsignature = null;
+                if (typeTable != null) {
+                    for (int j = 0; j < typeTable.length; j += 3) {
+                        if (typeTable[j] == start && typeTable[j + 1] == index) {
+                            vsignature = readUTF8(typeTable[j + 2], c);
+                            break;
+                        }
+                    }
+                }
+                mv.visitLocalVariable(readUTF8(u + 4, c), readUTF8(u + 6, c),
+                        vsignature, labels[start], labels[start + length],
+                        index);
+                u += 10;
+            }
+        }
+
+        // visits the local variables type annotations
+        if (tanns != null) {
+            for (int i = 0; i < tanns.length; ++i) {
+                if ((readByte(tanns[i]) >> 1) == (0x40 >> 1)) {
+                    int v = readAnnotationTarget(context, tanns[i]);
+                    v = readAnnotationValues(v + 2, c, true,
+                            mv.visitLocalVariableAnnotation(context.typeRef,
+                                    context.typePath, context.start,
+                                    context.end, context.index, readUTF8(v, c),
+                                    true));
+                }
+            }
+        }
+        if (itanns != null) {
+            for (int i = 0; i < itanns.length; ++i) {
+                if ((readByte(itanns[i]) >> 1) == (0x40 >> 1)) {
+                    int v = readAnnotationTarget(context, itanns[i]);
+                    v = readAnnotationValues(v + 2, c, true,
+                            mv.visitLocalVariableAnnotation(context.typeRef,
+                                    context.typePath, context.start,
+                                    context.end, context.index, readUTF8(v, c),
+                                    false));
+                }
+            }
+        }
+
+        // visits the code attributes
+        while (attributes != null) {
+            Attribute attr = attributes.next;
+            attributes.next = null;
+            mv.visitAttribute(attributes);
+            attributes = attr;
+        }
+
+        // visits the max stack and max locals values
+        mv.visitMaxs(maxStack, maxLocals);
+    }
+
+    /**
+     * Parses a type annotation table to find the labels, and to visit the try
+     * catch block annotations.
+     *
+     * @param u
+     *            the start offset of a type annotation table.
+     * @param mv
+     *            the method visitor to be used to visit the try catch block
+     *            annotations.
+     * @param context
+     *            information about the class being parsed.
+     * @param visible
+     *            if the type annotation table to parse contains runtime visible
+     *            annotations.
+     * @return the start offset of each type annotation in the parsed table.
+     */
+    private int[] readTypeAnnotations(final MethodVisitor mv,
+            final Context context, int u, boolean visible) {
+        char[] c = context.buffer;
+        int[] offsets = new int[readUnsignedShort(u)];
+        u += 2;
+        for (int i = 0; i < offsets.length; ++i) {
+            offsets[i] = u;
+            int target = readInt(u);
+            switch (target >>> 24) {
+            case 0x00: // CLASS_TYPE_PARAMETER
+            case 0x01: // METHOD_TYPE_PARAMETER
+            case 0x16: // METHOD_FORMAL_PARAMETER
+                u += 2;
+                break;
+            case 0x13: // FIELD
+            case 0x14: // METHOD_RETURN
+            case 0x15: // METHOD_RECEIVER
+                u += 1;
+                break;
+            case 0x40: // LOCAL_VARIABLE
+            case 0x41: // RESOURCE_VARIABLE
+                for (int j = readUnsignedShort(u + 1); j > 0; --j) {
+                    int start = readUnsignedShort(u + 3);
+                    int length = readUnsignedShort(u + 5);
+                    readLabel(start, context.labels);
+                    readLabel(start + length, context.labels);
+                    u += 6;
+                }
+                u += 3;
+                break;
+            case 0x47: // CAST
+            case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+            case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
+            case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+            case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
+                u += 4;
+                break;
+            // case 0x10: // CLASS_EXTENDS
+            // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
+            // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
+            // case 0x17: // THROWS
+            // case 0x42: // EXCEPTION_PARAMETER
+            // case 0x43: // INSTANCEOF
+            // case 0x44: // NEW
+            // case 0x45: // CONSTRUCTOR_REFERENCE
+            // case 0x46: // METHOD_REFERENCE
+            default:
+                u += 3;
+                break;
+            }
+            int pathLength = readByte(u);
+            if ((target >>> 24) == 0x42) {
+                TypePath path = pathLength == 0 ? null : new TypePath(b, u);
+                u += 1 + 2 * pathLength;
+                u = readAnnotationValues(u + 2, c, true,
+                        mv.visitTryCatchAnnotation(target, path,
+                                readUTF8(u, c), visible));
+            } else {
+                u = readAnnotationValues(u + 3 + 2 * pathLength, c, true, null);
+            }
+        }
+        return offsets;
+    }
+
+    /**
+     * Parses the header of a type annotation to extract its target_type and
+     * target_path (the result is stored in the given context), and returns the
+     * start offset of the rest of the type_annotation structure (i.e. the
+     * offset to the type_index field, which is followed by
+     * num_element_value_pairs and then the name,value pairs).
+     *
+     * @param context
+     *            information about the class being parsed. This is where the
+     *            extracted target_type and target_path must be stored.
+     * @param u
+     *            the start offset of a type_annotation structure.
+     * @return the start offset of the rest of the type_annotation structure.
+     */
+    private int readAnnotationTarget(final Context context, int u) {
+        int target = readInt(u);
+        switch (target >>> 24) {
+        case 0x00: // CLASS_TYPE_PARAMETER
+        case 0x01: // METHOD_TYPE_PARAMETER
+        case 0x16: // METHOD_FORMAL_PARAMETER
+            target &= 0xFFFF0000;
+            u += 2;
+            break;
+        case 0x13: // FIELD
+        case 0x14: // METHOD_RETURN
+        case 0x15: // METHOD_RECEIVER
+            target &= 0xFF000000;
+            u += 1;
+            break;
+        case 0x40: // LOCAL_VARIABLE
+        case 0x41: { // RESOURCE_VARIABLE
+            target &= 0xFF000000;
+            int n = readUnsignedShort(u + 1);
+            context.start = new Label[n];
+            context.end = new Label[n];
+            context.index = new int[n];
+            u += 3;
+            for (int i = 0; i < n; ++i) {
+                int start = readUnsignedShort(u);
+                int length = readUnsignedShort(u + 2);
+                context.start[i] = readLabel(start, context.labels);
+                context.end[i] = readLabel(start + length, context.labels);
+                context.index[i] = readUnsignedShort(u + 4);
+                u += 6;
+            }
+            break;
+        }
+        case 0x47: // CAST
+        case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+        case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
+        case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+        case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
+            target &= 0xFF0000FF;
+            u += 4;
+            break;
+        // case 0x10: // CLASS_EXTENDS
+        // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
+        // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
+        // case 0x17: // THROWS
+        // case 0x42: // EXCEPTION_PARAMETER
+        // case 0x43: // INSTANCEOF
+        // case 0x44: // NEW
+        // case 0x45: // CONSTRUCTOR_REFERENCE
+        // case 0x46: // METHOD_REFERENCE
+        default:
+            target &= (target >>> 24) < 0x43 ? 0xFFFFFF00 : 0xFF000000;
+            u += 3;
+            break;
+        }
+        int pathLength = readByte(u);
+        context.typeRef = target;
+        context.typePath = pathLength == 0 ? null : new TypePath(b, u);
+        return u + 1 + 2 * pathLength;
+    }
+
+    /**
      * Reads parameter annotations and makes the given visitor visit them.
      *
-     * @param v start offset in {@link #b b} of the annotations to be read.
-     * @param desc the method descriptor.
-     * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
-     *        {@link #readClass(int,char[]) readClass} or
-     *        {@link #readConst readConst}.
-     * @param visible <tt>true</tt> if the annotations to be read are visible
-     *        at runtime.
-     * @param mv the visitor that must visit the annotations.
+     * @param mv
+     *            the visitor that must visit the annotations.
+     * @param context
+     *            information about the class being parsed.
+     * @param v
+     *            start offset in {@link #b b} of the annotations to be read.
+     * @param visible
+     *            <tt>true</tt> if the annotations to be read are visible at
+     *            runtime.
      */
-    private void readParameterAnnotations(
-        int v,
-        final String desc,
-        final char[] buf,
-        final boolean visible,
-        final MethodVisitor mv)
-    {
+    private void readParameterAnnotations(final MethodVisitor mv,
+            final Context context, int v, final boolean visible) {
         int i;
         int n = b[v++] & 0xFF;
         // workaround for a bug in javac (javac compiler generates a parameter
@@ -1686,7 +1760,7 @@
         // equal to the number of parameters in the method descriptor - which
         // includes the synthetic parameters added by the compiler). This work-
         // around supposes that the synthetic parameters are the first ones.
-        int synthetics = Type.getArgumentTypes(desc).length - n;
+        int synthetics = Type.getArgumentTypes(context.desc).length - n;
         AnnotationVisitor av;
         for (i = 0; i < synthetics; ++i) {
             // virtual annotation to detect synthetic parameters in MethodWriter
@@ -1695,12 +1769,13 @@
                 av.visitEnd();
             }
         }
+        char[] c = context.buffer;
         for (; i < n + synthetics; ++i) {
             int j = readUnsignedShort(v);
             v += 2;
             for (; j > 0; --j) {
-                av = mv.visitParameterAnnotation(i, readUTF8(v, buf), visible);
-                v = readAnnotationValues(v + 2, buf, true, av);
+                av = mv.visitParameterAnnotation(i, readUTF8(v, c), visible);
+                v = readAnnotationValues(v + 2, c, true, av);
             }
         }
     }
@@ -1708,21 +1783,22 @@
     /**
      * Reads the values of an annotation and makes the given visitor visit them.
      *
-     * @param v the start offset in {@link #b b} of the values to be read
-     *        (including the unsigned short that gives the number of values).
-     * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
-     *        {@link #readClass(int,char[]) readClass} or
-     *        {@link #readConst readConst}.
-     * @param named if the annotation values are named or not.
-     * @param av the visitor that must visit the values.
+     * @param v
+     *            the start offset in {@link #b b} of the values to be read
+     *            (including the unsigned short that gives the number of
+     *            values).
+     * @param buf
+     *            buffer to be used to call {@link #readUTF8 readUTF8},
+     *            {@link #readClass(int,char[]) readClass} or {@link #readConst
+     *            readConst}.
+     * @param named
+     *            if the annotation values are named or not.
+     * @param av
+     *            the visitor that must visit the values.
      * @return the end offset of the annotation values.
      */
-    private int readAnnotationValues(
-        int v,
-        final char[] buf,
-        final boolean named,
-        final AnnotationVisitor av)
-    {
+    private int readAnnotationValues(int v, final char[] buf,
+            final boolean named, final AnnotationVisitor av) {
         int i = readUnsignedShort(v);
         v += 2;
         if (named) {
@@ -1743,210 +1819,368 @@
     /**
      * Reads a value of an annotation and makes the given visitor visit it.
      *
-     * @param v the start offset in {@link #b b} of the value to be read (<i>not
-     *        including the value name constant pool index</i>).
-     * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
-     *        {@link #readClass(int,char[]) readClass} or
-     *        {@link #readConst readConst}.
-     * @param name the name of the value to be read.
-     * @param av the visitor that must visit the value.
+     * @param v
+     *            the start offset in {@link #b b} of the value to be read
+     *            (<i>not including the value name constant pool index</i>).
+     * @param buf
+     *            buffer to be used to call {@link #readUTF8 readUTF8},
+     *            {@link #readClass(int,char[]) readClass} or {@link #readConst
+     *            readConst}.
+     * @param name
+     *            the name of the value to be read.
+     * @param av
+     *            the visitor that must visit the value.
      * @return the end offset of the annotation value.
      */
-    private int readAnnotationValue(
-        int v,
-        final char[] buf,
-        final String name,
-        final AnnotationVisitor av)
-    {
+    private int readAnnotationValue(int v, final char[] buf, final String name,
+            final AnnotationVisitor av) {
         int i;
         if (av == null) {
             switch (b[v] & 0xFF) {
-                case 'e': // enum_const_value
-                    return v + 5;
-                case '@': // annotation_value
-                    return readAnnotationValues(v + 3, buf, true, null);
-                case '[': // array_value
-                    return readAnnotationValues(v + 1, buf, false, null);
-                default:
-                    return v + 3;
+            case 'e': // enum_const_value
+                return v + 5;
+            case '@': // annotation_value
+                return readAnnotationValues(v + 3, buf, true, null);
+            case '[': // array_value
+                return readAnnotationValues(v + 1, buf, false, null);
+            default:
+                return v + 3;
             }
         }
         switch (b[v++] & 0xFF) {
-            case 'I': // pointer to CONSTANT_Integer
-            case 'J': // pointer to CONSTANT_Long
-            case 'F': // pointer to CONSTANT_Float
-            case 'D': // pointer to CONSTANT_Double
-                av.visit(name, readConst(readUnsignedShort(v), buf));
-                v += 2;
-                break;
-            case 'B': // pointer to CONSTANT_Byte
-                av.visit(name,
-                        new Byte((byte) readInt(items[readUnsignedShort(v)])));
-                v += 2;
-                break;
-            case 'Z': // pointer to CONSTANT_Boolean
-                av.visit(name, readInt(items[readUnsignedShort(v)]) == 0
-                        ? Boolean.FALSE
-                        : Boolean.TRUE);
-                v += 2;
-                break;
-            case 'S': // pointer to CONSTANT_Short
-                av.visit(name,
-                        new Short((short) readInt(items[readUnsignedShort(v)])));
-                v += 2;
-                break;
-            case 'C': // pointer to CONSTANT_Char
-                av.visit(name,
-                        new Character((char) readInt(items[readUnsignedShort(v)])));
-                v += 2;
-                break;
-            case 's': // pointer to CONSTANT_Utf8
-                av.visit(name, readUTF8(v, buf));
-                v += 2;
-                break;
-            case 'e': // enum_const_value
-                av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf));
-                v += 4;
-                break;
-            case 'c': // class_info
-                av.visit(name, Type.getType(readUTF8(v, buf)));
-                v += 2;
-                break;
-            case '@': // annotation_value
-                v = readAnnotationValues(v + 2,
-                        buf,
-                        true,
-                        av.visitAnnotation(name, readUTF8(v, buf)));
-                break;
-            case '[': // array_value
-                int size = readUnsignedShort(v);
-                v += 2;
-                if (size == 0) {
-                    return readAnnotationValues(v - 2,
-                            buf,
-                            false,
-                            av.visitArray(name));
+        case 'I': // pointer to CONSTANT_Integer
+        case 'J': // pointer to CONSTANT_Long
+        case 'F': // pointer to CONSTANT_Float
+        case 'D': // pointer to CONSTANT_Double
+            av.visit(name, readConst(readUnsignedShort(v), buf));
+            v += 2;
+            break;
+        case 'B': // pointer to CONSTANT_Byte
+            av.visit(name,
+                    new Byte((byte) readInt(items[readUnsignedShort(v)])));
+            v += 2;
+            break;
+        case 'Z': // pointer to CONSTANT_Boolean
+            av.visit(name,
+                    readInt(items[readUnsignedShort(v)]) == 0 ? Boolean.FALSE
+                            : Boolean.TRUE);
+            v += 2;
+            break;
+        case 'S': // pointer to CONSTANT_Short
+            av.visit(name, new Short(
+                    (short) readInt(items[readUnsignedShort(v)])));
+            v += 2;
+            break;
+        case 'C': // pointer to CONSTANT_Char
+            av.visit(name, new Character(
+                    (char) readInt(items[readUnsignedShort(v)])));
+            v += 2;
+            break;
+        case 's': // pointer to CONSTANT_Utf8
+            av.visit(name, readUTF8(v, buf));
+            v += 2;
+            break;
+        case 'e': // enum_const_value
+            av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf));
+            v += 4;
+            break;
+        case 'c': // class_info
+            av.visit(name, Type.getType(readUTF8(v, buf)));
+            v += 2;
+            break;
+        case '@': // annotation_value
+            v = readAnnotationValues(v + 2, buf, true,
+                    av.visitAnnotation(name, readUTF8(v, buf)));
+            break;
+        case '[': // array_value
+            int size = readUnsignedShort(v);
+            v += 2;
+            if (size == 0) {
+                return readAnnotationValues(v - 2, buf, false,
+                        av.visitArray(name));
+            }
+            switch (this.b[v++] & 0xFF) {
+            case 'B':
+                byte[] bv = new byte[size];
+                for (i = 0; i < size; i++) {
+                    bv[i] = (byte) readInt(items[readUnsignedShort(v)]);
+                    v += 3;
                 }
-                switch (this.b[v++] & 0xFF) {
-                    case 'B':
-                        byte[] bv = new byte[size];
-                        for (i = 0; i < size; i++) {
-                            bv[i] = (byte) readInt(items[readUnsignedShort(v)]);
-                            v += 3;
-                        }
-                        av.visit(name, bv);
-                        --v;
-                        break;
-                    case 'Z':
-                        boolean[] zv = new boolean[size];
-                        for (i = 0; i < size; i++) {
-                            zv[i] = readInt(items[readUnsignedShort(v)]) != 0;
-                            v += 3;
-                        }
-                        av.visit(name, zv);
-                        --v;
-                        break;
-                    case 'S':
-                        short[] sv = new short[size];
-                        for (i = 0; i < size; i++) {
-                            sv[i] = (short) readInt(items[readUnsignedShort(v)]);
-                            v += 3;
-                        }
-                        av.visit(name, sv);
-                        --v;
-                        break;
-                    case 'C':
-                        char[] cv = new char[size];
-                        for (i = 0; i < size; i++) {
-                            cv[i] = (char) readInt(items[readUnsignedShort(v)]);
-                            v += 3;
-                        }
-                        av.visit(name, cv);
-                        --v;
-                        break;
-                    case 'I':
-                        int[] iv = new int[size];
-                        for (i = 0; i < size; i++) {
-                            iv[i] = readInt(items[readUnsignedShort(v)]);
-                            v += 3;
-                        }
-                        av.visit(name, iv);
-                        --v;
-                        break;
-                    case 'J':
-                        long[] lv = new long[size];
-                        for (i = 0; i < size; i++) {
-                            lv[i] = readLong(items[readUnsignedShort(v)]);
-                            v += 3;
-                        }
-                        av.visit(name, lv);
-                        --v;
-                        break;
-                    case 'F':
-                        float[] fv = new float[size];
-                        for (i = 0; i < size; i++) {
-                            fv[i] = Float.intBitsToFloat(readInt(items[readUnsignedShort(v)]));
-                            v += 3;
-                        }
-                        av.visit(name, fv);
-                        --v;
-                        break;
-                    case 'D':
-                        double[] dv = new double[size];
-                        for (i = 0; i < size; i++) {
-                            dv[i] = Double.longBitsToDouble(readLong(items[readUnsignedShort(v)]));
-                            v += 3;
-                        }
-                        av.visit(name, dv);
-                        --v;
-                        break;
-                    default:
-                        v = readAnnotationValues(v - 3,
-                                buf,
-                                false,
-                                av.visitArray(name));
+                av.visit(name, bv);
+                --v;
+                break;
+            case 'Z':
+                boolean[] zv = new boolean[size];
+                for (i = 0; i < size; i++) {
+                    zv[i] = readInt(items[readUnsignedShort(v)]) != 0;
+                    v += 3;
                 }
+                av.visit(name, zv);
+                --v;
+                break;
+            case 'S':
+                short[] sv = new short[size];
+                for (i = 0; i < size; i++) {
+                    sv[i] = (short) readInt(items[readUnsignedShort(v)]);
+                    v += 3;
+                }
+                av.visit(name, sv);
+                --v;
+                break;
+            case 'C':
+                char[] cv = new char[size];
+                for (i = 0; i < size; i++) {
+                    cv[i] = (char) readInt(items[readUnsignedShort(v)]);
+                    v += 3;
+                }
+                av.visit(name, cv);
+                --v;
+                break;
+            case 'I':
+                int[] iv = new int[size];
+                for (i = 0; i < size; i++) {
+                    iv[i] = readInt(items[readUnsignedShort(v)]);
+                    v += 3;
+                }
+                av.visit(name, iv);
+                --v;
+                break;
+            case 'J':
+                long[] lv = new long[size];
+                for (i = 0; i < size; i++) {
+                    lv[i] = readLong(items[readUnsignedShort(v)]);
+                    v += 3;
+                }
+                av.visit(name, lv);
+                --v;
+                break;
+            case 'F':
+                float[] fv = new float[size];
+                for (i = 0; i < size; i++) {
+                    fv[i] = Float
+                            .intBitsToFloat(readInt(items[readUnsignedShort(v)]));
+                    v += 3;
+                }
+                av.visit(name, fv);
+                --v;
+                break;
+            case 'D':
+                double[] dv = new double[size];
+                for (i = 0; i < size; i++) {
+                    dv[i] = Double
+                            .longBitsToDouble(readLong(items[readUnsignedShort(v)]));
+                    v += 3;
+                }
+                av.visit(name, dv);
+                --v;
+                break;
+            default:
+                v = readAnnotationValues(v - 3, buf, false, av.visitArray(name));
+            }
         }
         return v;
     }
 
-    private int readFrameType(
-        final Object[] frame,
-        final int index,
-        int v,
-        final char[] buf,
-        final Label[] labels)
-    {
+    /**
+     * Computes the implicit frame of the method currently being parsed (as
+     * defined in the given {@link Context}) and stores it in the given context.
+     *
+     * @param frame
+     *            information about the class being parsed.
+     */
+    private void getImplicitFrame(final Context frame) {
+        String desc = frame.desc;
+        Object[] locals = frame.local;
+        int local = 0;
+        if ((frame.access & Opcodes.ACC_STATIC) == 0) {
+            if ("<init>".equals(frame.name)) {
+                locals[local++] = Opcodes.UNINITIALIZED_THIS;
+            } else {
+                locals[local++] = readClass(header + 2, frame.buffer);
+            }
+        }
+        int i = 1;
+        loop: while (true) {
+            int j = i;
+            switch (desc.charAt(i++)) {
+            case 'Z':
+            case 'C':
+            case 'B':
+            case 'S':
+            case 'I':
+                locals[local++] = Opcodes.INTEGER;
+                break;
+            case 'F':
+                locals[local++] = Opcodes.FLOAT;
+                break;
+            case 'J':
+                locals[local++] = Opcodes.LONG;
+                break;
+            case 'D':
+                locals[local++] = Opcodes.DOUBLE;
+                break;
+            case '[':
+                while (desc.charAt(i) == '[') {
+                    ++i;
+                }
+                if (desc.charAt(i) == 'L') {
+                    ++i;
+                    while (desc.charAt(i) != ';') {
+                        ++i;
+                    }
+                }
+                locals[local++] = desc.substring(j, ++i);
+                break;
+            case 'L':
+                while (desc.charAt(i) != ';') {
+                    ++i;
+                }
+                locals[local++] = desc.substring(j + 1, i++);
+                break;
+            default:
+                break loop;
+            }
+        }
+        frame.localCount = local;
+    }
+
+    /**
+     * Reads a stack map frame and stores the result in the given
+     * {@link Context} object.
+     *
+     * @param stackMap
+     *            the start offset of a stack map frame in the class file.
+     * @param zip
+     *            if the stack map frame at stackMap is compressed or not.
+     * @param unzip
+     *            if the stack map frame must be uncompressed.
+     * @param frame
+     *            where the parsed stack map frame must be stored.
+     * @return the offset of the first byte following the parsed frame.
+     */
+    private int readFrame(int stackMap, boolean zip, boolean unzip,
+            Context frame) {
+        char[] c = frame.buffer;
+        Label[] labels = frame.labels;
+        int tag;
+        int delta;
+        if (zip) {
+            tag = b[stackMap++] & 0xFF;
+        } else {
+            tag = MethodWriter.FULL_FRAME;
+            frame.offset = -1;
+        }
+        frame.localDiff = 0;
+        if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME) {
+            delta = tag;
+            frame.mode = Opcodes.F_SAME;
+            frame.stackCount = 0;
+        } else if (tag < MethodWriter.RESERVED) {
+            delta = tag - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME;
+            stackMap = readFrameType(frame.stack, 0, stackMap, c, labels);
+            frame.mode = Opcodes.F_SAME1;
+            frame.stackCount = 1;
+        } else {
+            delta = readUnsignedShort(stackMap);
+            stackMap += 2;
+            if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
+                stackMap = readFrameType(frame.stack, 0, stackMap, c, labels);
+                frame.mode = Opcodes.F_SAME1;
+                frame.stackCount = 1;
+            } else if (tag >= MethodWriter.CHOP_FRAME
+                    && tag < MethodWriter.SAME_FRAME_EXTENDED) {
+                frame.mode = Opcodes.F_CHOP;
+                frame.localDiff = MethodWriter.SAME_FRAME_EXTENDED - tag;
+                frame.localCount -= frame.localDiff;
+                frame.stackCount = 0;
+            } else if (tag == MethodWriter.SAME_FRAME_EXTENDED) {
+                frame.mode = Opcodes.F_SAME;
+                frame.stackCount = 0;
+            } else if (tag < MethodWriter.FULL_FRAME) {
+                int local = unzip ? frame.localCount : 0;
+                for (int i = tag - MethodWriter.SAME_FRAME_EXTENDED; i > 0; i--) {
+                    stackMap = readFrameType(frame.local, local++, stackMap, c,
+                            labels);
+                }
+                frame.mode = Opcodes.F_APPEND;
+                frame.localDiff = tag - MethodWriter.SAME_FRAME_EXTENDED;
+                frame.localCount += frame.localDiff;
+                frame.stackCount = 0;
+            } else { // if (tag == FULL_FRAME) {
+                frame.mode = Opcodes.F_FULL;
+                int n = readUnsignedShort(stackMap);
+                stackMap += 2;
+                frame.localDiff = n;
+                frame.localCount = n;
+                for (int local = 0; n > 0; n--) {
+                    stackMap = readFrameType(frame.local, local++, stackMap, c,
+                            labels);
+                }
+                n = readUnsignedShort(stackMap);
+                stackMap += 2;
+                frame.stackCount = n;
+                for (int stack = 0; n > 0; n--) {
+                    stackMap = readFrameType(frame.stack, stack++, stackMap, c,
+                            labels);
+                }
+            }
+        }
+        frame.offset += delta + 1;
+        readLabel(frame.offset, labels);
+        return stackMap;
+    }
+
+    /**
+     * Reads a stack map frame type and stores it at the given index in the
+     * given array.
+     *
+     * @param frame
+     *            the array where the parsed type must be stored.
+     * @param index
+     *            the index in 'frame' where the parsed type must be stored.
+     * @param v
+     *            the start offset of the stack map frame type to read.
+     * @param buf
+     *            a buffer to read strings.
+     * @param labels
+     *            the labels of the method currently being parsed, indexed by
+     *            their offset. If the parsed type is an Uninitialized type, a
+     *            new label for the corresponding NEW instruction is stored in
+     *            this array if it does not already exist.
+     * @return the offset of the first byte after the parsed type.
+     */
+    private int readFrameType(final Object[] frame, final int index, int v,
+            final char[] buf, final Label[] labels) {
         int type = b[v++] & 0xFF;
         switch (type) {
-            case 0:
-                frame[index] = Opcodes.TOP;
-                break;
-            case 1:
-                frame[index] = Opcodes.INTEGER;
-                break;
-            case 2:
-                frame[index] = Opcodes.FLOAT;
-                break;
-            case 3:
-                frame[index] = Opcodes.DOUBLE;
-                break;
-            case 4:
-                frame[index] = Opcodes.LONG;
-                break;
-            case 5:
-                frame[index] = Opcodes.NULL;
-                break;
-            case 6:
-                frame[index] = Opcodes.UNINITIALIZED_THIS;
-                break;
-            case 7: // Object
-                frame[index] = readClass(v, buf);
-                v += 2;
-                break;
-            default: // Uninitialized
-                frame[index] = readLabel(readUnsignedShort(v), labels);
-                v += 2;
+        case 0:
+            frame[index] = Opcodes.TOP;
+            break;
+        case 1:
+            frame[index] = Opcodes.INTEGER;
+            break;
+        case 2:
+            frame[index] = Opcodes.FLOAT;
+            break;
+        case 3:
+            frame[index] = Opcodes.DOUBLE;
+            break;
+        case 4:
+            frame[index] = Opcodes.LONG;
+            break;
+        case 5:
+            frame[index] = Opcodes.NULL;
+            break;
+        case 6:
+            frame[index] = Opcodes.UNINITIALIZED_THIS;
+            break;
+        case 7: // Object
+            frame[index] = readClass(v, buf);
+            v += 2;
+            break;
+        default: // Uninitialized
+            frame[index] = readLabel(readUnsignedShort(v), labels);
+            v += 2;
         }
         return v;
     }
@@ -1956,10 +2190,12 @@
      * implementation of this method creates a label for the given offset if it
      * has not been already created.
      *
-     * @param offset a bytecode offset in a method.
-     * @param labels the already created labels, indexed by their offset. If a
-     *        label already exists for offset this method must not create a new
-     *        one. Otherwise it must store the new label in this array.
+     * @param offset
+     *            a bytecode offset in a method.
+     * @param labels
+     *            the already created labels, indexed by their offset. If a
+     *            label already exists for offset this method must not create a
+     *            new one. Otherwise it must store the new label in this array.
      * @return a non null Label, which must be equal to labels[offset].
      */
     protected Label readLabel(int offset, Label[] labels) {
@@ -1970,39 +2206,67 @@
     }
 
     /**
+     * Returns the start index of the attribute_info structure of this class.
+     *
+     * @return the start index of the attribute_info structure of this class.
+     */
+    private int getAttributes() {
+        // skips the header
+        int u = header + 8 + readUnsignedShort(header + 6) * 2;
+        // skips fields and methods
+        for (int i = readUnsignedShort(u); i > 0; --i) {
+            for (int j = readUnsignedShort(u + 8); j > 0; --j) {
+                u += 6 + readInt(u + 12);
+            }
+            u += 8;
+        }
+        u += 2;
+        for (int i = readUnsignedShort(u); i > 0; --i) {
+            for (int j = readUnsignedShort(u + 8); j > 0; --j) {
+                u += 6 + readInt(u + 12);
+            }
+            u += 8;
+        }
+        // the attribute_info structure starts just after the methods
+        return u + 2;
+    }
+
+    /**
      * Reads an attribute in {@link #b b}.
      *
-     * @param attrs prototypes of the attributes that must be parsed during the
-     *        visit of the class. Any attribute whose type is not equal to the
-     *        type of one the prototypes is ignored (i.e. an empty
-     *        {@link Attribute} instance is returned).
-     * @param type the type of the attribute.
-     * @param off index of the first byte of the attribute's content in
-     *        {@link #b b}. The 6 attribute header bytes, containing the type
-     *        and the length of the attribute, are not taken into account here
-     *        (they have already been read).
-     * @param len the length of the attribute's content.
-     * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
-     *        {@link #readClass(int,char[]) readClass} or
-     *        {@link #readConst readConst}.
-     * @param codeOff index of the first byte of code's attribute content in
-     *        {@link #b b}, or -1 if the attribute to be read is not a code
-     *        attribute. The 6 attribute header bytes, containing the type and
-     *        the length of the attribute, are not taken into account here.
-     * @param labels the labels of the method's code, or <tt>null</tt> if the
-     *        attribute to be read is not a code attribute.
+     * @param attrs
+     *            prototypes of the attributes that must be parsed during the
+     *            visit of the class. Any attribute whose type is not equal to
+     *            the type of one the prototypes is ignored (i.e. an empty
+     *            {@link Attribute} instance is returned).
+     * @param type
+     *            the type of the attribute.
+     * @param off
+     *            index of the first byte of the attribute's content in
+     *            {@link #b b}. The 6 attribute header bytes, containing the
+     *            type and the length of the attribute, are not taken into
+     *            account here (they have already been read).
+     * @param len
+     *            the length of the attribute's content.
+     * @param buf
+     *            buffer to be used to call {@link #readUTF8 readUTF8},
+     *            {@link #readClass(int,char[]) readClass} or {@link #readConst
+     *            readConst}.
+     * @param codeOff
+     *            index of the first byte of code's attribute content in
+     *            {@link #b b}, or -1 if the attribute to be read is not a code
+     *            attribute. The 6 attribute header bytes, containing the type
+     *            and the length of the attribute, are not taken into account
+     *            here.
+     * @param labels
+     *            the labels of the method's code, or <tt>null</tt> if the
+     *            attribute to be read is not a code attribute.
      * @return the attribute that has been read, or <tt>null</tt> to skip this
      *         attribute.
      */
-    private Attribute readAttribute(
-        final Attribute[] attrs,
-        final String type,
-        final int off,
-        final int len,
-        final char[] buf,
-        final int codeOff,
-        final Label[] labels)
-    {
+    private Attribute readAttribute(final Attribute[] attrs, final String type,
+            final int off, final int len, final char[] buf, final int codeOff,
+            final Label[] labels) {
         for (int i = 0; i < attrs.length; ++i) {
             if (attrs[i].type.equals(type)) {
                 return attrs[i].read(this, off, len, buf, codeOff, labels);
@@ -2016,9 +2280,9 @@
     // ------------------------------------------------------------------------
 
     /**
-     *  Returns the number of constant pool items in {@link #b b}.
+     * Returns the number of constant pool items in {@link #b b}.
      *
-     *  @return the number of constant pool items in {@link #b b}.
+     * @return the number of constant pool items in {@link #b b}.
      */
     public int getItemCount() {
         return items.length;
@@ -2029,7 +2293,8 @@
      * one. <i>This method is intended for {@link Attribute} sub classes, and is
      * normally not needed by class generators or adapters.</i>
      *
-     * @param item the index a constant pool item.
+     * @param item
+     *            the index a constant pool item.
      * @return the start index of the constant pool item in {@link #b b}, plus
      *         one.
      */
@@ -2053,7 +2318,8 @@
      * {@link Attribute} sub classes, and is normally not needed by class
      * generators or adapters.</i>
      *
-     * @param index the start index of the value to be read in {@link #b b}.
+     * @param index
+     *            the start index of the value to be read in {@link #b b}.
      * @return the read value.
      */
     public int readByte(final int index) {
@@ -2061,11 +2327,12 @@
     }
 
     /**
-     * Reads an unsigned short value in {@link #b b}. <i>This method is
-     * intended for {@link Attribute} sub classes, and is normally not needed by
-     * class generators or adapters.</i>
+     * Reads an unsigned short value in {@link #b b}. <i>This method is intended
+     * for {@link Attribute} sub classes, and is normally not needed by class
+     * generators or adapters.</i>
      *
-     * @param index the start index of the value to be read in {@link #b b}.
+     * @param index
+     *            the start index of the value to be read in {@link #b b}.
      * @return the read value.
      */
     public int readUnsignedShort(final int index) {
@@ -2078,7 +2345,8 @@
      * for {@link Attribute} sub classes, and is normally not needed by class
      * generators or adapters.</i>
      *
-     * @param index the start index of the value to be read in {@link #b b}.
+     * @param index
+     *            the start index of the value to be read in {@link #b b}.
      * @return the read value.
      */
     public short readShort(final int index) {
@@ -2091,7 +2359,8 @@
      * {@link Attribute} sub classes, and is normally not needed by class
      * generators or adapters.</i>
      *
-     * @param index the start index of the value to be read in {@link #b b}.
+     * @param index
+     *            the start index of the value to be read in {@link #b b}.
      * @return the read value.
      */
     public int readInt(final int index) {
@@ -2101,11 +2370,12 @@
     }
 
     /**
-     * Reads a signed long value in {@link #b b}. <i>This method is intended
-     * for {@link Attribute} sub classes, and is normally not needed by class
+     * Reads a signed long value in {@link #b b}. <i>This method is intended for
+     * {@link Attribute} sub classes, and is normally not needed by class
      * generators or adapters.</i>
      *
-     * @param index the start index of the value to be read in {@link #b b}.
+     * @param index
+     *            the start index of the value to be read in {@link #b b}.
      * @return the read value.
      */
     public long readLong(final int index) {
@@ -2119,14 +2389,19 @@
      * is intended for {@link Attribute} sub classes, and is normally not needed
      * by class generators or adapters.</i>
      *
-     * @param index the start index of an unsigned short value in {@link #b b},
-     *        whose value is the index of an UTF8 constant pool item.
-     * @param buf buffer to be used to read the item. This buffer must be
-     *        sufficiently large. It is not automatically resized.
+     * @param index
+     *            the start index of an unsigned short value in {@link #b b},
+     *            whose value is the index of an UTF8 constant pool item.
+     * @param buf
+     *            buffer to be used to read the item. This buffer must be
+     *            sufficiently large. It is not automatically resized.
      * @return the String corresponding to the specified UTF8 item.
      */
     public String readUTF8(int index, final char[] buf) {
         int item = readUnsignedShort(index);
+        if (index == 0 || item == 0) {
+            return null;
+        }
         String s = strings[item];
         if (s != null) {
             return s;
@@ -2138,10 +2413,13 @@
     /**
      * Reads UTF8 string in {@link #b b}.
      *
-     * @param index start offset of the UTF8 string to be read.
-     * @param utfLen length of the UTF8 string to be read.
-     * @param buf buffer to be used to read the string. This buffer must be
-     *        sufficiently large. It is not automatically resized.
+     * @param index
+     *            start offset of the UTF8 string to be read.
+     * @param utfLen
+     *            length of the UTF8 string to be read.
+     * @param buf
+     *            buffer to be used to read the string. This buffer must be
+     *            sufficiently large. It is not automatically resized.
      * @return the String corresponding to the specified UTF8 string.
      */
     private String readUTF(int index, final int utfLen, final char[] buf) {
@@ -2154,28 +2432,28 @@
         while (index < endIndex) {
             c = b[index++];
             switch (st) {
-                case 0:
-                    c = c & 0xFF;
-                    if (c < 0x80) {  // 0xxxxxxx
-                        buf[strLen++] = (char) c;
-                    } else if (c < 0xE0 && c > 0xBF) {  // 110x xxxx 10xx xxxx
-                        cc = (char) (c & 0x1F);
-                        st = 1;
-                    } else {  // 1110 xxxx 10xx xxxx 10xx xxxx
-                        cc = (char) (c & 0x0F);
-                        st = 2;
-                    }
-                    break;
-
-                case 1:  // byte 2 of 2-byte char or byte 3 of 3-byte char
-                    buf[strLen++] = (char) ((cc << 6) | (c & 0x3F));
-                    st = 0;
-                    break;
-
-                case 2:  // byte 2 of 3-byte char
-                    cc = (char) ((cc << 6) | (c & 0x3F));
+            case 0:
+                c = c & 0xFF;
+                if (c < 0x80) { // 0xxxxxxx
+                    buf[strLen++] = (char) c;
+                } else if (c < 0xE0 && c > 0xBF) { // 110x xxxx 10xx xxxx
+                    cc = (char) (c & 0x1F);
                     st = 1;
-                    break;
+                } else { // 1110 xxxx 10xx xxxx 10xx xxxx
+                    cc = (char) (c & 0x0F);
+                    st = 2;
+                }
+                break;
+
+            case 1: // byte 2 of 2-byte char or byte 3 of 3-byte char
+                buf[strLen++] = (char) ((cc << 6) | (c & 0x3F));
+                st = 0;
+                break;
+
+            case 2: // byte 2 of 3-byte char
+                cc = (char) ((cc << 6) | (c & 0x3F));
+                st = 1;
+                break;
             }
         }
         return new String(buf, 0, strLen);
@@ -2186,10 +2464,12 @@
      * intended for {@link Attribute} sub classes, and is normally not needed by
      * class generators or adapters.</i>
      *
-     * @param index the start index of an unsigned short value in {@link #b b},
-     *        whose value is the index of a class constant pool item.
-     * @param buf buffer to be used to read the item. This buffer must be
-     *        sufficiently large. It is not automatically resized.
+     * @param index
+     *            the start index of an unsigned short value in {@link #b b},
+     *            whose value is the index of a class constant pool item.
+     * @param buf
+     *            buffer to be used to read the item. This buffer must be
+     *            sufficiently large. It is not automatically resized.
      * @return the String corresponding to the specified class item.
      */
     public String readClass(final int index, final char[] buf) {
@@ -2204,9 +2484,11 @@
      * method is intended for {@link Attribute} sub classes, and is normally not
      * needed by class generators or adapters.</i>
      *
-     * @param item the index of a constant pool item.
-     * @param buf buffer to be used to read the item. This buffer must be
-     *        sufficiently large. It is not automatically resized.
+     * @param item
+     *            the index of a constant pool item.
+     * @param buf
+     *            buffer to be used to read the item. This buffer must be
+     *            sufficiently large. It is not automatically resized.
      * @return the {@link Integer}, {@link Float}, {@link Long}, {@link Double},
      *         {@link String}, {@link Type} or {@link Handle} corresponding to
      *         the given constant pool item.
@@ -2214,32 +2496,29 @@
     public Object readConst(final int item, final char[] buf) {
         int index = items[item];
         switch (b[index - 1]) {
-            case ClassWriter.INT:
-                return new Integer(readInt(index));
-            case ClassWriter.FLOAT:
-                return new Float(Float.intBitsToFloat(readInt(index)));
-            case ClassWriter.LONG:
-                return new Long(readLong(index));
-            case ClassWriter.DOUBLE:
-                return new Double(Double.longBitsToDouble(readLong(index)));
-            case ClassWriter.CLASS:
-                return Type.getObjectType(readUTF8(index, buf));
-            case ClassWriter.STR:
-                return readUTF8(index, buf);
-            case ClassWriter.MTYPE:
-                return Type.getMethodType(readUTF8(index, buf));
-
-            //case ClassWriter.HANDLE_BASE + [1..9]:
-            default: {
-                int tag = readByte(index);
-                int[] items = this.items;
-                int cpIndex = items[readUnsignedShort(index + 1)];
-                String owner = readClass(cpIndex, buf);
-                cpIndex = items[readUnsignedShort(cpIndex + 2)];
-                String name = readUTF8(cpIndex, buf);
-                String desc = readUTF8(cpIndex + 2, buf);
-                return new Handle(tag, owner, name, desc);
-            }
+        case ClassWriter.INT:
+            return new Integer(readInt(index));
+        case ClassWriter.FLOAT:
+            return new Float(Float.intBitsToFloat(readInt(index)));
+        case ClassWriter.LONG:
+            return new Long(readLong(index));
+        case ClassWriter.DOUBLE:
+            return new Double(Double.longBitsToDouble(readLong(index)));
+        case ClassWriter.CLASS:
+            return Type.getObjectType(readUTF8(index, buf));
+        case ClassWriter.STR:
+            return readUTF8(index, buf);
+        case ClassWriter.MTYPE:
+            return Type.getMethodType(readUTF8(index, buf));
+        default: // case ClassWriter.HANDLE_BASE + [1..9]:
+            int tag = readByte(index);
+            int[] items = this.items;
+            int cpIndex = items[readUnsignedShort(index + 1)];
+            String owner = readClass(cpIndex, buf);
+            cpIndex = items[readUnsignedShort(cpIndex + 2)];
+            String name = readUTF8(cpIndex, buf);
+            String desc = readUTF8(cpIndex + 2, buf);
+            return new Handle(tag, owner, name, desc);
         }
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassVisitor.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassVisitor.java
index 73096fa..f95597e 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassVisitor.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassVisitor.java
@@ -59,11 +59,12 @@
 package jdk.internal.org.objectweb.asm;
 
 /**
- * A visitor to visit a Java class. The methods of this class must be called
- * in the following order: <tt>visit</tt> [ <tt>visitSource</tt> ] [
+ * A visitor to visit a Java class. The methods of this class must be called in
+ * the following order: <tt>visit</tt> [ <tt>visitSource</tt> ] [
  * <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
- * <tt>visitAttribute</tt> )* ( <tt>visitInnerClass</tt> |
- * <tt>visitField</tt> | <tt>visitMethod</tt> )* <tt>visitEnd</tt>.
+ * <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* (
+ * <tt>visitInnerClass</tt> | <tt>visitField</tt> | <tt>visitMethod</tt> )*
+ * <tt>visitEnd</tt>.
  *
  * @author Eric Bruneton
  */
@@ -71,7 +72,7 @@
 
     /**
      * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4}.
+     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
      */
     protected final int api;
 
@@ -84,8 +85,9 @@
     /**
      * Constructs a new {@link ClassVisitor}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
      */
     public ClassVisitor(final int api) {
         this(api, null);
@@ -94,15 +96,17 @@
     /**
      * Constructs a new {@link ClassVisitor}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
-     * @param cv the class visitor to which this visitor must delegate method
-     *        calls. May be null.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param cv
+     *            the class visitor to which this visitor must delegate method
+     *            calls. May be null.
      */
     public ClassVisitor(final int api, final ClassVisitor cv) {
-        /*if (api != Opcodes.ASM4) {
+        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
             throw new IllegalArgumentException();
-        }*/
+        }
         this.api = api;
         this.cv = cv;
     }
@@ -110,30 +114,30 @@
     /**
      * Visits the header of the class.
      *
-     * @param version the class version.
-     * @param access the class's access flags (see {@link Opcodes}). This
-     *        parameter also indicates if the class is deprecated.
-     * @param name the internal name of the class (see
-     *        {@link Type#getInternalName() getInternalName}).
-     * @param signature the signature of this class. May be <tt>null</tt> if
-     *        the class is not a generic one, and does not extend or implement
-     *        generic classes or interfaces.
-     * @param superName the internal of name of the super class (see
-     *        {@link Type#getInternalName() getInternalName}). For interfaces,
-     *        the super class is {@link Object}. May be <tt>null</tt>, but
-     *        only for the {@link Object} class.
-     * @param interfaces the internal names of the class's interfaces (see
-     *        {@link Type#getInternalName() getInternalName}). May be
-     *        <tt>null</tt>.
+     * @param version
+     *            the class version.
+     * @param access
+     *            the class's access flags (see {@link Opcodes}). This parameter
+     *            also indicates if the class is deprecated.
+     * @param name
+     *            the internal name of the class (see
+     *            {@link Type#getInternalName() getInternalName}).
+     * @param signature
+     *            the signature of this class. May be <tt>null</tt> if the class
+     *            is not a generic one, and does not extend or implement generic
+     *            classes or interfaces.
+     * @param superName
+     *            the internal of name of the super class (see
+     *            {@link Type#getInternalName() getInternalName}). For
+     *            interfaces, the super class is {@link Object}. May be
+     *            <tt>null</tt>, but only for the {@link Object} class.
+     * @param interfaces
+     *            the internal names of the class's interfaces (see
+     *            {@link Type#getInternalName() getInternalName}). May be
+     *            <tt>null</tt>.
      */
-    public void visit(
-        int version,
-        int access,
-        String name,
-        String signature,
-        String superName,
-        String[] interfaces)
-    {
+    public void visit(int version, int access, String name, String signature,
+            String superName, String[] interfaces) {
         if (cv != null) {
             cv.visit(version, access, name, signature, superName, interfaces);
         }
@@ -142,11 +146,13 @@
     /**
      * Visits the source of the class.
      *
-     * @param source the name of the source file from which the class was
-     *        compiled. May be <tt>null</tt>.
-     * @param debug additional debug information to compute the correspondance
-     *        between source and compiled elements of the class. May be
-     *        <tt>null</tt>.
+     * @param source
+     *            the name of the source file from which the class was compiled.
+     *            May be <tt>null</tt>.
+     * @param debug
+     *            additional debug information to compute the correspondance
+     *            between source and compiled elements of the class. May be
+     *            <tt>null</tt>.
      */
     public void visitSource(String source, String debug) {
         if (cv != null) {
@@ -158,16 +164,19 @@
      * Visits the enclosing class of the class. This method must be called only
      * if the class has an enclosing class.
      *
-     * @param owner internal name of the enclosing class of the class.
-     * @param name the name of the method that contains the class, or
-     *        <tt>null</tt> if the class is not enclosed in a method of its
-     *        enclosing class.
-     * @param desc the descriptor of the method that contains the class, or
-     *        <tt>null</tt> if the class is not enclosed in a method of its
-     *        enclosing class.
+     * @param owner
+     *            internal name of the enclosing class of the class.
+     * @param name
+     *            the name of the method that contains the class, or
+     *            <tt>null</tt> if the class is not enclosed in a method of its
+     *            enclosing class.
+     * @param desc
+     *            the descriptor of the method that contains the class, or
+     *            <tt>null</tt> if the class is not enclosed in a method of its
+     *            enclosing class.
      */
     public void visitOuterClass(String owner, String name, String desc) {
-        if (cv != null)  {
+        if (cv != null) {
             cv.visitOuterClass(owner, name, desc);
         }
     }
@@ -175,8 +184,10 @@
     /**
      * Visits an annotation of the class.
      *
-     * @param desc the class descriptor of the annotation class.
-     * @param visible <tt>true</tt> if the annotation is visible at runtime.
+     * @param desc
+     *            the class descriptor of the annotation class.
+     * @param visible
+     *            <tt>true</tt> if the annotation is visible at runtime.
      * @return a visitor to visit the annotation values, or <tt>null</tt> if
      *         this visitor is not interested in visiting this annotation.
      */
@@ -188,9 +199,43 @@
     }
 
     /**
+     * Visits an annotation on a type in the class signature.
+     *
+     * @param typeRef
+     *            a reference to the annotated type. The sort of this type
+     *            reference must be {@link TypeReference#CLASS_TYPE_PARAMETER
+     *            CLASS_TYPE_PARAMETER},
+     *            {@link TypeReference#CLASS_TYPE_PARAMETER_BOUND
+     *            CLASS_TYPE_PARAMETER_BOUND} or
+     *            {@link TypeReference#CLASS_EXTENDS CLASS_EXTENDS}. See
+     *            {@link TypeReference}.
+     * @param typePath
+     *            the path to the annotated type argument, wildcard bound, array
+     *            element type, or static inner type within 'typeRef'. May be
+     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
+     * @param desc
+     *            the class descriptor of the annotation class.
+     * @param visible
+     *            <tt>true</tt> if the annotation is visible at runtime.
+     * @return a visitor to visit the annotation values, or <tt>null</tt> if
+     *         this visitor is not interested in visiting this annotation.
+     */
+    public AnnotationVisitor visitTypeAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        if (api < Opcodes.ASM5) {
+            throw new RuntimeException();
+        }
+        if (cv != null) {
+            return cv.visitTypeAnnotation(typeRef, typePath, desc, visible);
+        }
+        return null;
+    }
+
+    /**
      * Visits a non standard attribute of the class.
      *
-     * @param attr an attribute.
+     * @param attr
+     *            an attribute.
      */
     public void visitAttribute(Attribute attr) {
         if (cv != null) {
@@ -202,23 +247,22 @@
      * Visits information about an inner class. This inner class is not
      * necessarily a member of the class being visited.
      *
-     * @param name the internal name of an inner class (see
-     *        {@link Type#getInternalName() getInternalName}).
-     * @param outerName the internal name of the class to which the inner class
-     *        belongs (see {@link Type#getInternalName() getInternalName}). May
-     *        be <tt>null</tt> for not member classes.
-     * @param innerName the (simple) name of the inner class inside its
-     *        enclosing class. May be <tt>null</tt> for anonymous inner
-     *        classes.
-     * @param access the access flags of the inner class as originally declared
-     *        in the enclosing class.
+     * @param name
+     *            the internal name of an inner class (see
+     *            {@link Type#getInternalName() getInternalName}).
+     * @param outerName
+     *            the internal name of the class to which the inner class
+     *            belongs (see {@link Type#getInternalName() getInternalName}).
+     *            May be <tt>null</tt> for not member classes.
+     * @param innerName
+     *            the (simple) name of the inner class inside its enclosing
+     *            class. May be <tt>null</tt> for anonymous inner classes.
+     * @param access
+     *            the access flags of the inner class as originally declared in
+     *            the enclosing class.
      */
-    public void visitInnerClass(
-        String name,
-        String outerName,
-        String innerName,
-        int access)
-    {
+    public void visitInnerClass(String name, String outerName,
+            String innerName, int access) {
         if (cv != null) {
             cv.visitInnerClass(name, outerName, innerName, access);
         }
@@ -227,33 +271,32 @@
     /**
      * Visits a field of the class.
      *
-     * @param access the field's access flags (see {@link Opcodes}). This
-     *        parameter also indicates if the field is synthetic and/or
-     *        deprecated.
-     * @param name the field's name.
-     * @param desc the field's descriptor (see {@link Type Type}).
-     * @param signature the field's signature. May be <tt>null</tt> if the
-     *        field's type does not use generic types.
-     * @param value the field's initial value. This parameter, which may be
-     *        <tt>null</tt> if the field does not have an initial value, must
-     *        be an {@link Integer}, a {@link Float}, a {@link Long}, a
-     *        {@link Double} or a {@link String} (for <tt>int</tt>,
-     *        <tt>float</tt>, <tt>long</tt> or <tt>String</tt> fields
-     *        respectively). <i>This parameter is only used for static fields</i>.
-     *        Its value is ignored for non static fields, which must be
-     *        initialized through bytecode instructions in constructors or
-     *        methods.
+     * @param access
+     *            the field's access flags (see {@link Opcodes}). This parameter
+     *            also indicates if the field is synthetic and/or deprecated.
+     * @param name
+     *            the field's name.
+     * @param desc
+     *            the field's descriptor (see {@link Type Type}).
+     * @param signature
+     *            the field's signature. May be <tt>null</tt> if the field's
+     *            type does not use generic types.
+     * @param value
+     *            the field's initial value. This parameter, which may be
+     *            <tt>null</tt> if the field does not have an initial value,
+     *            must be an {@link Integer}, a {@link Float}, a {@link Long}, a
+     *            {@link Double} or a {@link String} (for <tt>int</tt>,
+     *            <tt>float</tt>, <tt>long</tt> or <tt>String</tt> fields
+     *            respectively). <i>This parameter is only used for static
+     *            fields</i>. Its value is ignored for non static fields, which
+     *            must be initialized through bytecode instructions in
+     *            constructors or methods.
      * @return a visitor to visit field annotations and attributes, or
-     *         <tt>null</tt> if this class visitor is not interested in
-     *         visiting these annotations and attributes.
+     *         <tt>null</tt> if this class visitor is not interested in visiting
+     *         these annotations and attributes.
      */
-    public FieldVisitor visitField(
-        int access,
-        String name,
-        String desc,
-        String signature,
-        Object value)
-    {
+    public FieldVisitor visitField(int access, String name, String desc,
+            String signature, Object value) {
         if (cv != null) {
             return cv.visitField(access, name, desc, signature, value);
         }
@@ -262,31 +305,31 @@
 
     /**
      * Visits a method of the class. This method <i>must</i> return a new
-     * {@link MethodVisitor} instance (or <tt>null</tt>) each time it is
-     * called, i.e., it should not return a previously returned visitor.
+     * {@link MethodVisitor} instance (or <tt>null</tt>) each time it is called,
+     * i.e., it should not return a previously returned visitor.
      *
-     * @param access the method's access flags (see {@link Opcodes}). This
-     *        parameter also indicates if the method is synthetic and/or
-     *        deprecated.
-     * @param name the method's name.
-     * @param desc the method's descriptor (see {@link Type Type}).
-     * @param signature the method's signature. May be <tt>null</tt> if the
-     *        method parameters, return type and exceptions do not use generic
-     *        types.
-     * @param exceptions the internal names of the method's exception classes
-     *        (see {@link Type#getInternalName() getInternalName}). May be
-     *        <tt>null</tt>.
+     * @param access
+     *            the method's access flags (see {@link Opcodes}). This
+     *            parameter also indicates if the method is synthetic and/or
+     *            deprecated.
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor (see {@link Type Type}).
+     * @param signature
+     *            the method's signature. May be <tt>null</tt> if the method
+     *            parameters, return type and exceptions do not use generic
+     *            types.
+     * @param exceptions
+     *            the internal names of the method's exception classes (see
+     *            {@link Type#getInternalName() getInternalName}). May be
+     *            <tt>null</tt>.
      * @return an object to visit the byte code of the method, or <tt>null</tt>
      *         if this class visitor is not interested in visiting the code of
      *         this method.
      */
-    public MethodVisitor visitMethod(
-        int access,
-        String name,
-        String desc,
-        String signature,
-        String[] exceptions)
-    {
+    public MethodVisitor visitMethod(int access, String name, String desc,
+            String signature, String[] exceptions) {
         if (cv != null) {
             return cv.visitMethod(access, name, desc, signature, exceptions);
         }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java
index 33c9829..d5d8fa4 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java
@@ -95,12 +95,18 @@
     public static final int COMPUTE_FRAMES = 2;
 
     /**
-     * Pseudo access flag to distinguish between the synthetic attribute and
-     * the synthetic access flag.
+     * Pseudo access flag to distinguish between the synthetic attribute and the
+     * synthetic access flag.
      */
     static final int ACC_SYNTHETIC_ATTRIBUTE = 0x40000;
 
     /**
+     * Factor to convert from ACC_SYNTHETIC_ATTRIBUTE to Opcode.ACC_SYNTHETIC.
+     */
+    static final int TO_ACC_SYNTHETIC = ACC_SYNTHETIC_ATTRIBUTE
+            / Opcodes.ACC_SYNTHETIC;
+
+    /**
      * The type of instructions without any argument.
      */
     static final int NOARG_INSN = 0;
@@ -267,8 +273,8 @@
 
     /**
      * The base value for all CONSTANT_MethodHandle constant pool items.
-     * Internally, ASM store the 9 variations of CONSTANT_MethodHandle into
-     * 9 different items.
+     * Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 9
+     * different items.
      */
     static final int HANDLE_BASE = 20;
 
@@ -295,9 +301,8 @@
     static final int TYPE_MERGED = 32;
 
     /**
-     * The type of BootstrapMethods items. These items are stored in a
-     * special class attribute named BootstrapMethods and
-     * not in the constant pool.
+     * The type of BootstrapMethods items. These items are stored in a special
+     * class attribute named BootstrapMethods and not in the constant pool.
      */
     static final int BSM = 33;
 
@@ -356,10 +361,10 @@
      * necessarily be stored in the constant pool. This type table is used by
      * the control flow and data flow analysis algorithm used to compute stack
      * map frames from scratch. This array associates to each index <tt>i</tt>
-     * the Item whose index is <tt>i</tt>. All Item objects stored in this
-     * array are also stored in the {@link #items} hash table. These two arrays
-     * allow to retrieve an Item from its index or, conversely, to get the index
-     * of an Item from its value. Each Item stores an internal name in its
+     * the Item whose index is <tt>i</tt>. All Item objects stored in this array
+     * are also stored in the {@link #items} hash table. These two arrays allow
+     * to retrieve an Item from its index or, conversely, to get the index of an
+     * Item from its value. Each Item stores an internal name in its
      * {@link Item#strVal1} field.
      */
     Item[] typeTable;
@@ -441,6 +446,16 @@
     private AnnotationWriter ianns;
 
     /**
+     * The runtime visible type annotations of this class.
+     */
+    private AnnotationWriter tanns;
+
+    /**
+     * The runtime invisible type annotations of this class.
+     */
+    private AnnotationWriter itanns;
+
+    /**
      * The non standard attributes of this class.
      */
     private Attribute attrs;
@@ -468,16 +483,16 @@
     /**
      * The fields of this class. These fields are stored in a linked list of
      * {@link FieldWriter} objects, linked to each other by their
-     * {@link FieldWriter#fv} field. This field stores the first element of
-     * this list.
+     * {@link FieldWriter#fv} field. This field stores the first element of this
+     * list.
      */
     FieldWriter firstField;
 
     /**
      * The fields of this class. These fields are stored in a linked list of
      * {@link FieldWriter} objects, linked to each other by their
-     * {@link FieldWriter#fv} field. This field stores the last element of
-     * this list.
+     * {@link FieldWriter#fv} field. This field stores the last element of this
+     * list.
      */
     FieldWriter lastField;
 
@@ -492,8 +507,8 @@
     /**
      * The methods of this class. These methods are stored in a linked list of
      * {@link MethodWriter} objects, linked to each other by their
-     * {@link MethodWriter#mv} field. This field stores the last element of
-     * this list.
+     * {@link MethodWriter#mv} field. This field stores the last element of this
+     * list.
      */
     MethodWriter lastMethod;
 
@@ -613,11 +628,13 @@
     /**
      * Constructs a new {@link ClassWriter} object.
      *
-     * @param flags option flags that can be used to modify the default behavior
-     *        of this class. See {@link #COMPUTE_MAXS}, {@link #COMPUTE_FRAMES}.
+     * @param flags
+     *            option flags that can be used to modify the default behavior
+     *            of this class. See {@link #COMPUTE_MAXS},
+     *            {@link #COMPUTE_FRAMES}.
      */
     public ClassWriter(final int flags) {
-        super(Opcodes.ASM4);
+        super(Opcodes.ASM5);
         index = 1;
         pool = new ByteVector();
         items = new Item[256];
@@ -635,26 +652,32 @@
      * "mostly add" bytecode transformations. These optimizations are the
      * following:
      *
-     * <ul> <li>The constant pool from the original class is copied as is in the
-     * new class, which saves time. New constant pool entries will be added at
-     * the end if necessary, but unused constant pool entries <i>won't be
-     * removed</i>.</li> <li>Methods that are not transformed are copied as is
-     * in the new class, directly from the original class bytecode (i.e. without
-     * emitting visit events for all the method instructions), which saves a
-     * <i>lot</i> of time. Untransformed methods are detected by the fact that
-     * the {@link ClassReader} receives {@link MethodVisitor} objects that come
-     * from a {@link ClassWriter} (and not from any other {@link ClassVisitor}
-     * instance).</li> </ul>
+     * <ul>
+     * <li>The constant pool from the original class is copied as is in the new
+     * class, which saves time. New constant pool entries will be added at the
+     * end if necessary, but unused constant pool entries <i>won't be
+     * removed</i>.</li>
+     * <li>Methods that are not transformed are copied as is in the new class,
+     * directly from the original class bytecode (i.e. without emitting visit
+     * events for all the method instructions), which saves a <i>lot</i> of
+     * time. Untransformed methods are detected by the fact that the
+     * {@link ClassReader} receives {@link MethodVisitor} objects that come from
+     * a {@link ClassWriter} (and not from any other {@link ClassVisitor}
+     * instance).</li>
+     * </ul>
      *
-     * @param classReader the {@link ClassReader} used to read the original
-     *        class. It will be used to copy the entire constant pool from the
-     *        original class and also to copy other fragments of original
-     *        bytecode where applicable.
-     * @param flags option flags that can be used to modify the default behavior
-     *        of this class. <i>These option flags do not affect methods that
-     *        are copied as is in the new class. This means that the maximum
-     *        stack size nor the stack frames will be computed for these
-     *        methods</i>. See {@link #COMPUTE_MAXS}, {@link #COMPUTE_FRAMES}.
+     * @param classReader
+     *            the {@link ClassReader} used to read the original class. It
+     *            will be used to copy the entire constant pool from the
+     *            original class and also to copy other fragments of original
+     *            bytecode where applicable.
+     * @param flags
+     *            option flags that can be used to modify the default behavior
+     *            of this class. <i>These option flags do not affect methods
+     *            that are copied as is in the new class. This means that the
+     *            maximum stack size nor the stack frames will be computed for
+     *            these methods</i>. See {@link #COMPUTE_MAXS},
+     *            {@link #COMPUTE_FRAMES}.
      */
     public ClassWriter(final ClassReader classReader, final int flags) {
         this(flags);
@@ -667,14 +690,9 @@
     // ------------------------------------------------------------------------
 
     @Override
-    public final void visit(
-        final int version,
-        final int access,
-        final String name,
-        final String signature,
-        final String superName,
-        final String[] interfaces)
-    {
+    public final void visit(final int version, final int access,
+            final String name, final String signature, final String superName,
+            final String[] interfaces) {
         this.version = version;
         this.access = access;
         this.name = newClass(name);
@@ -703,11 +721,8 @@
     }
 
     @Override
-    public final void visitOuterClass(
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public final void visitOuterClass(final String owner, final String name,
+            final String desc) {
         enclosingMethodOwner = newClass(owner);
         if (name != null && desc != null) {
             enclosingMethod = newNameType(name, desc);
@@ -715,10 +730,8 @@
     }
 
     @Override
-    public final AnnotationVisitor visitAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public final AnnotationVisitor visitAnnotation(final String desc,
+            final boolean visible) {
         if (!ClassReader.ANNOTATIONS) {
             return null;
         }
@@ -737,18 +750,37 @@
     }
 
     @Override
+    public final AnnotationVisitor visitTypeAnnotation(int typeRef,
+            TypePath typePath, final String desc, final boolean visible) {
+        if (!ClassReader.ANNOTATIONS) {
+            return null;
+        }
+        ByteVector bv = new ByteVector();
+        // write target_type and target_info
+        AnnotationWriter.putTarget(typeRef, typePath, bv);
+        // write type, and reserve space for values count
+        bv.putShort(newUTF8(desc)).putShort(0);
+        AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv,
+                bv.length - 2);
+        if (visible) {
+            aw.next = tanns;
+            tanns = aw;
+        } else {
+            aw.next = itanns;
+            itanns = aw;
+        }
+        return aw;
+    }
+
+    @Override
     public final void visitAttribute(final Attribute attr) {
         attr.next = attrs;
         attrs = attr;
     }
 
     @Override
-    public final void visitInnerClass(
-        final String name,
-        final String outerName,
-        final String innerName,
-        final int access)
-    {
+    public final void visitInnerClass(final String name,
+            final String outerName, final String innerName, final int access) {
         if (innerClasses == null) {
             innerClasses = new ByteVector();
         }
@@ -760,32 +792,16 @@
     }
 
     @Override
-    public final FieldVisitor visitField(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final Object value)
-    {
+    public final FieldVisitor visitField(final int access, final String name,
+            final String desc, final String signature, final Object value) {
         return new FieldWriter(this, access, name, desc, signature, value);
     }
 
     @Override
-    public final MethodVisitor visitMethod(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final String[] exceptions)
-    {
-        return new MethodWriter(this,
-                access,
-                name,
-                desc,
-                signature,
-                exceptions,
-                computeMaxs,
-                computeFrames);
+    public final MethodVisitor visitMethod(final int access, final String name,
+            final String desc, final String signature, final String[] exceptions) {
+        return new MethodWriter(this, access, name, desc, signature,
+                exceptions, computeMaxs, computeFrames);
     }
 
     @Override
@@ -802,7 +818,7 @@
      * @return the bytecode of the class that was build with this class writer.
      */
     public byte[] toByteArray() {
-        if (index > Short.MAX_VALUE) {
+        if (index > 0xFFFF) {
             throw new RuntimeException("Class file too large!");
         }
         // computes the real size of the bytecode of this class
@@ -822,8 +838,9 @@
             mb = (MethodWriter) mb.mv;
         }
         int attributeCount = 0;
-        if (bootstrapMethods != null) {  // we put it as first argument in order
-                                         // to improve a bit ClassReader.copyBootstrapMethods
+        if (bootstrapMethods != null) {
+            // we put it as first attribute in order to improve a bit
+            // ClassReader.copyBootstrapMethods
             ++attributeCount;
             size += 8 + bootstrapMethods.length;
             newUTF8("BootstrapMethods");
@@ -853,12 +870,13 @@
             size += 6;
             newUTF8("Deprecated");
         }
-        if ((access & Opcodes.ACC_SYNTHETIC) != 0
-                && ((version & 0xFFFF) < Opcodes.V1_5 || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0))
-        {
-            ++attributeCount;
-            size += 6;
-            newUTF8("Synthetic");
+        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+            if ((version & 0xFFFF) < Opcodes.V1_5
+                    || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+                ++attributeCount;
+                size += 6;
+                newUTF8("Synthetic");
+            }
         }
         if (innerClasses != null) {
             ++attributeCount;
@@ -875,6 +893,16 @@
             size += 8 + ianns.getSize();
             newUTF8("RuntimeInvisibleAnnotations");
         }
+        if (ClassReader.ANNOTATIONS && tanns != null) {
+            ++attributeCount;
+            size += 8 + tanns.getSize();
+            newUTF8("RuntimeVisibleTypeAnnotations");
+        }
+        if (ClassReader.ANNOTATIONS && itanns != null) {
+            ++attributeCount;
+            size += 8 + itanns.getSize();
+            newUTF8("RuntimeInvisibleTypeAnnotations");
+        }
         if (attrs != null) {
             attributeCount += attrs.getCount();
             size += attrs.getSize(this, null, 0, -1, -1);
@@ -885,9 +913,8 @@
         ByteVector out = new ByteVector(size);
         out.putInt(0xCAFEBABE).putInt(version);
         out.putShort(index).putByteArray(pool.data, 0, pool.length);
-        int mask = Opcodes.ACC_DEPRECATED
-                | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
-                | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / (ClassWriter.ACC_SYNTHETIC_ATTRIBUTE / Opcodes.ACC_SYNTHETIC));
+        int mask = Opcodes.ACC_DEPRECATED | ACC_SYNTHETIC_ATTRIBUTE
+                | ((access & ACC_SYNTHETIC_ATTRIBUTE) / TO_ACC_SYNTHETIC);
         out.putShort(access & ~mask).putShort(name).putShort(superName);
         out.putShort(interfaceCount);
         for (int i = 0; i < interfaceCount; ++i) {
@@ -906,9 +933,10 @@
             mb = (MethodWriter) mb.mv;
         }
         out.putShort(attributeCount);
-        if (bootstrapMethods != null) {   // should be the first class attribute ?
+        if (bootstrapMethods != null) {
             out.putShort(newUTF8("BootstrapMethods"));
-            out.putInt(bootstrapMethods.length + 2).putShort(bootstrapMethodsCount);
+            out.putInt(bootstrapMethods.length + 2).putShort(
+                    bootstrapMethodsCount);
             out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length);
         }
         if (ClassReader.SIGNATURES && signature != 0) {
@@ -929,10 +957,11 @@
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             out.putShort(newUTF8("Deprecated")).putInt(0);
         }
-        if ((access & Opcodes.ACC_SYNTHETIC) != 0
-                && ((version & 0xFFFF) < Opcodes.V1_5 || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0))
-        {
-            out.putShort(newUTF8("Synthetic")).putInt(0);
+        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+            if ((version & 0xFFFF) < Opcodes.V1_5
+                    || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+                out.putShort(newUTF8("Synthetic")).putInt(0);
+            }
         }
         if (innerClasses != null) {
             out.putShort(newUTF8("InnerClasses"));
@@ -947,6 +976,14 @@
             out.putShort(newUTF8("RuntimeInvisibleAnnotations"));
             ianns.put(out);
         }
+        if (ClassReader.ANNOTATIONS && tanns != null) {
+            out.putShort(newUTF8("RuntimeVisibleTypeAnnotations"));
+            tanns.put(out);
+        }
+        if (ClassReader.ANNOTATIONS && itanns != null) {
+            out.putShort(newUTF8("RuntimeInvisibleTypeAnnotations"));
+            itanns.put(out);
+        }
         if (attrs != null) {
             attrs.put(this, null, 0, -1, -1, out);
         }
@@ -966,10 +1003,11 @@
      * Adds a number or string constant to the constant pool of the class being
      * build. Does nothing if the constant pool already contains a similar item.
      *
-     * @param cst the value of the constant to be added to the constant pool.
-     *        This parameter must be an {@link Integer}, a {@link Float}, a
-     *        {@link Long}, a {@link Double}, a {@link String} or a
-     *        {@link Type}.
+     * @param cst
+     *            the value of the constant to be added to the constant pool.
+     *            This parameter must be an {@link Integer}, a {@link Float}, a
+     *            {@link Long}, a {@link Double}, a {@link String} or a
+     *            {@link Type}.
      * @return a new or already existing constant item with the given value.
      */
     Item newConstItem(final Object cst) {
@@ -1002,12 +1040,12 @@
         } else if (cst instanceof Type) {
             Type t = (Type) cst;
             int s = t.getSort();
-            if (s == Type.ARRAY) {
-                return newClassItem(t.getDescriptor());
-            } else if (s == Type.OBJECT) {
+            if (s == Type.OBJECT) {
                 return newClassItem(t.getInternalName());
-            } else { // s == Type.METHOD
+            } else if (s == Type.METHOD) {
                 return newMethodTypeItem(t.getDescriptor());
+            } else { // s == primitive type or array
+                return newClassItem(t.getDescriptor());
             }
         } else if (cst instanceof Handle) {
             Handle h = (Handle) cst;
@@ -1023,9 +1061,10 @@
      * <i>This method is intended for {@link Attribute} sub classes, and is
      * normally not needed by class generators or adapters.</i>
      *
-     * @param cst the value of the constant to be added to the constant pool.
-     *        This parameter must be an {@link Integer}, a {@link Float}, a
-     *        {@link Long}, a {@link Double} or a {@link String}.
+     * @param cst
+     *            the value of the constant to be added to the constant pool.
+     *            This parameter must be an {@link Integer}, a {@link Float}, a
+     *            {@link Long}, a {@link Double} or a {@link String}.
      * @return the index of a new or already existing constant item with the
      *         given value.
      */
@@ -1039,7 +1078,8 @@
      * method is intended for {@link Attribute} sub classes, and is normally not
      * needed by class generators or adapters.</i>
      *
-     * @param value the String value.
+     * @param value
+     *            the String value.
      * @return the index of a new or already existing UTF8 item.
      */
     public int newUTF8(final String value) {
@@ -1059,7 +1099,8 @@
      * <i>This method is intended for {@link Attribute} sub classes, and is
      * normally not needed by class generators or adapters.</i>
      *
-     * @param value the internal name of the class.
+     * @param value
+     *            the internal name of the class.
      * @return a new or already existing class reference item.
      */
     Item newClassItem(final String value) {
@@ -1079,7 +1120,8 @@
      * <i>This method is intended for {@link Attribute} sub classes, and is
      * normally not needed by class generators or adapters.</i>
      *
-     * @param value the internal name of the class.
+     * @param value
+     *            the internal name of the class.
      * @return the index of a new or already existing class reference item.
      */
     public int newClass(final String value) {
@@ -1092,7 +1134,8 @@
      * <i>This method is intended for {@link Attribute} sub classes, and is
      * normally not needed by class generators or adapters.</i>
      *
-     * @param methodDesc method descriptor of the method type.
+     * @param methodDesc
+     *            method descriptor of the method type.
      * @return a new or already existing method type reference item.
      */
     Item newMethodTypeItem(final String methodDesc) {
@@ -1112,7 +1155,8 @@
      * <i>This method is intended for {@link Attribute} sub classes, and is
      * normally not needed by class generators or adapters.</i>
      *
-     * @param methodDesc method descriptor of the method type.
+     * @param methodDesc
+     *            method descriptor of the method type.
      * @return the index of a new or already existing method type reference
      *         item.
      */
@@ -1126,33 +1170,34 @@
      * intended for {@link Attribute} sub classes, and is normally not needed by
      * class generators or adapters.</i>
      *
-     * @param tag the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
-     *        {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
-     *        {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
-     *        {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL},
-     *        {@link Opcodes#H_NEWINVOKESPECIAL} or
-     *        {@link Opcodes#H_INVOKEINTERFACE}.
-     * @param owner the internal name of the field or method owner class.
-     * @param name the name of the field or method.
-     * @param desc the descriptor of the field or method.
+     * @param tag
+     *            the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
+     *            {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
+     *            {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
+     *            {@link Opcodes#H_INVOKESTATIC},
+     *            {@link Opcodes#H_INVOKESPECIAL},
+     *            {@link Opcodes#H_NEWINVOKESPECIAL} or
+     *            {@link Opcodes#H_INVOKEINTERFACE}.
+     * @param owner
+     *            the internal name of the field or method owner class.
+     * @param name
+     *            the name of the field or method.
+     * @param desc
+     *            the descriptor of the field or method.
      * @return a new or an already existing method type reference item.
      */
-    Item newHandleItem(
-        final int tag,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    Item newHandleItem(final int tag, final String owner, final String name,
+            final String desc) {
         key4.set(HANDLE_BASE + tag, owner, name, desc);
         Item result = get(key4);
         if (result == null) {
             if (tag <= Opcodes.H_PUTSTATIC) {
                 put112(HANDLE, tag, newField(owner, name, desc));
             } else {
-                put112(HANDLE, tag, newMethod(owner,
-                        name,
-                        desc,
-                        tag == Opcodes.H_INVOKEINTERFACE));
+                put112(HANDLE,
+                        tag,
+                        newMethod(owner, name, desc,
+                                tag == Opcodes.H_INVOKEINTERFACE));
             }
             result = new Item(index++, key4);
             put(result);
@@ -1161,29 +1206,30 @@
     }
 
     /**
-     * Adds a handle to the constant pool of the class being
-     * build. Does nothing if the constant pool already contains a similar item.
-     * <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
+     * Adds a handle to the constant pool of the class being build. Does nothing
+     * if the constant pool already contains a similar item. <i>This method is
+     * intended for {@link Attribute} sub classes, and is normally not needed by
+     * class generators or adapters.</i>
      *
-     * @param tag the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
-     *        {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
-     *        {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
-     *        {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL},
-     *        {@link Opcodes#H_NEWINVOKESPECIAL} or
-     *        {@link Opcodes#H_INVOKEINTERFACE}.
-     * @param owner the internal name of the field or method owner class.
-     * @param name the name of the field or method.
-     * @param desc the descriptor of the field or method.
+     * @param tag
+     *            the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
+     *            {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
+     *            {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
+     *            {@link Opcodes#H_INVOKESTATIC},
+     *            {@link Opcodes#H_INVOKESPECIAL},
+     *            {@link Opcodes#H_NEWINVOKESPECIAL} or
+     *            {@link Opcodes#H_INVOKEINTERFACE}.
+     * @param owner
+     *            the internal name of the field or method owner class.
+     * @param name
+     *            the name of the field or method.
+     * @param desc
+     *            the descriptor of the field or method.
      * @return the index of a new or already existing method type reference
      *         item.
      */
-    public int newHandle(
-        final int tag,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public int newHandle(final int tag, final String owner, final String name,
+            final String desc) {
         return newHandleItem(tag, owner, name, desc).index;
     }
 
@@ -1193,19 +1239,19 @@
      * <i>This method is intended for {@link Attribute} sub classes, and is
      * normally not needed by class generators or adapters.</i>
      *
-     * @param name name of the invoked method.
-     * @param desc descriptor of the invoke method.
-     * @param bsm the bootstrap method.
-     * @param bsmArgs the bootstrap method constant arguments.
+     * @param name
+     *            name of the invoked method.
+     * @param desc
+     *            descriptor of the invoke method.
+     * @param bsm
+     *            the bootstrap method.
+     * @param bsmArgs
+     *            the bootstrap method constant arguments.
      *
      * @return a new or an already existing invokedynamic type reference item.
      */
-    Item newInvokeDynamicItem(
-        final String name,
-        final String desc,
-        final Handle bsm,
-        final Object... bsmArgs)
-    {
+    Item newInvokeDynamicItem(final String name, final String desc,
+            final Handle bsm, final Object... bsmArgs) {
         // cache for performance
         ByteVector bootstrapMethods = this.bootstrapMethods;
         if (bootstrapMethods == null) {
@@ -1215,9 +1261,7 @@
         int position = bootstrapMethods.length; // record current position
 
         int hashCode = bsm.hashCode();
-        bootstrapMethods.putShort(newHandle(bsm.tag,
-                bsm.owner,
-                bsm.name,
+        bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name,
                 bsm.desc));
 
         int argsLength = bsmArgs.length;
@@ -1279,20 +1323,20 @@
      * <i>This method is intended for {@link Attribute} sub classes, and is
      * normally not needed by class generators or adapters.</i>
      *
-     * @param name name of the invoked method.
-     * @param desc descriptor of the invoke method.
-     * @param bsm the bootstrap method.
-     * @param bsmArgs the bootstrap method constant arguments.
+     * @param name
+     *            name of the invoked method.
+     * @param desc
+     *            descriptor of the invoke method.
+     * @param bsm
+     *            the bootstrap method.
+     * @param bsmArgs
+     *            the bootstrap method constant arguments.
      *
-     * @return the index of a new or already existing invokedynamic
-     *         reference item.
+     * @return the index of a new or already existing invokedynamic reference
+     *         item.
      */
-    public int newInvokeDynamic(
-        final String name,
-        final String desc,
-        final Handle bsm,
-        final Object... bsmArgs)
-    {
+    public int newInvokeDynamic(final String name, final String desc,
+            final Handle bsm, final Object... bsmArgs) {
         return newInvokeDynamicItem(name, desc, bsm, bsmArgs).index;
     }
 
@@ -1300,13 +1344,15 @@
      * Adds a field reference to the constant pool of the class being build.
      * Does nothing if the constant pool already contains a similar item.
      *
-     * @param owner the internal name of the field's owner class.
-     * @param name the field's name.
-     * @param desc the field's descriptor.
+     * @param owner
+     *            the internal name of the field's owner class.
+     * @param name
+     *            the field's name.
+     * @param desc
+     *            the field's descriptor.
      * @return a new or already existing field reference item.
      */
-    Item newFieldItem(final String owner, final String name, final String desc)
-    {
+    Item newFieldItem(final String owner, final String name, final String desc) {
         key3.set(FIELD, owner, name, desc);
         Item result = get(key3);
         if (result == null) {
@@ -1323,13 +1369,15 @@
      * <i>This method is intended for {@link Attribute} sub classes, and is
      * normally not needed by class generators or adapters.</i>
      *
-     * @param owner the internal name of the field's owner class.
-     * @param name the field's name.
-     * @param desc the field's descriptor.
+     * @param owner
+     *            the internal name of the field's owner class.
+     * @param name
+     *            the field's name.
+     * @param desc
+     *            the field's descriptor.
      * @return the index of a new or already existing field reference item.
      */
-    public int newField(final String owner, final String name, final String desc)
-    {
+    public int newField(final String owner, final String name, final String desc) {
         return newFieldItem(owner, name, desc).index;
     }
 
@@ -1337,18 +1385,18 @@
      * Adds a method reference to the constant pool of the class being build.
      * Does nothing if the constant pool already contains a similar item.
      *
-     * @param owner the internal name of the method's owner class.
-     * @param name the method's name.
-     * @param desc the method's descriptor.
-     * @param itf <tt>true</tt> if <tt>owner</tt> is an interface.
+     * @param owner
+     *            the internal name of the method's owner class.
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor.
+     * @param itf
+     *            <tt>true</tt> if <tt>owner</tt> is an interface.
      * @return a new or already existing method reference item.
      */
-    Item newMethodItem(
-        final String owner,
-        final String name,
-        final String desc,
-        final boolean itf)
-    {
+    Item newMethodItem(final String owner, final String name,
+            final String desc, final boolean itf) {
         int type = itf ? IMETH : METH;
         key3.set(type, owner, name, desc);
         Item result = get(key3);
@@ -1366,18 +1414,18 @@
      * <i>This method is intended for {@link Attribute} sub classes, and is
      * normally not needed by class generators or adapters.</i>
      *
-     * @param owner the internal name of the method's owner class.
-     * @param name the method's name.
-     * @param desc the method's descriptor.
-     * @param itf <tt>true</tt> if <tt>owner</tt> is an interface.
+     * @param owner
+     *            the internal name of the method's owner class.
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor.
+     * @param itf
+     *            <tt>true</tt> if <tt>owner</tt> is an interface.
      * @return the index of a new or already existing method reference item.
      */
-    public int newMethod(
-        final String owner,
-        final String name,
-        final String desc,
-        final boolean itf)
-    {
+    public int newMethod(final String owner, final String name,
+            final String desc, final boolean itf) {
         return newMethodItem(owner, name, desc, itf).index;
     }
 
@@ -1385,7 +1433,8 @@
      * Adds an integer to the constant pool of the class being build. Does
      * nothing if the constant pool already contains a similar item.
      *
-     * @param value the int value.
+     * @param value
+     *            the int value.
      * @return a new or already existing int item.
      */
     Item newInteger(final int value) {
@@ -1403,7 +1452,8 @@
      * Adds a float to the constant pool of the class being build. Does nothing
      * if the constant pool already contains a similar item.
      *
-     * @param value the float value.
+     * @param value
+     *            the float value.
      * @return a new or already existing float item.
      */
     Item newFloat(final float value) {
@@ -1421,7 +1471,8 @@
      * Adds a long to the constant pool of the class being build. Does nothing
      * if the constant pool already contains a similar item.
      *
-     * @param value the long value.
+     * @param value
+     *            the long value.
      * @return a new or already existing long item.
      */
     Item newLong(final long value) {
@@ -1440,7 +1491,8 @@
      * Adds a double to the constant pool of the class being build. Does nothing
      * if the constant pool already contains a similar item.
      *
-     * @param value the double value.
+     * @param value
+     *            the double value.
      * @return a new or already existing double item.
      */
     Item newDouble(final double value) {
@@ -1459,7 +1511,8 @@
      * Adds a string to the constant pool of the class being build. Does nothing
      * if the constant pool already contains a similar item.
      *
-     * @param value the String value.
+     * @param value
+     *            the String value.
      * @return a new or already existing string item.
      */
     private Item newString(final String value) {
@@ -1479,8 +1532,10 @@
      * method is intended for {@link Attribute} sub classes, and is normally not
      * needed by class generators or adapters.</i>
      *
-     * @param name a name.
-     * @param desc a type descriptor.
+     * @param name
+     *            a name.
+     * @param desc
+     *            a type descriptor.
      * @return the index of a new or already existing name and type item.
      */
     public int newNameType(final String name, final String desc) {
@@ -1491,8 +1546,10 @@
      * Adds a name and type to the constant pool of the class being build. Does
      * nothing if the constant pool already contains a similar item.
      *
-     * @param name a name.
-     * @param desc a type descriptor.
+     * @param name
+     *            a name.
+     * @param desc
+     *            a type descriptor.
      * @return a new or already existing name and type item.
      */
     Item newNameTypeItem(final String name, final String desc) {
@@ -1510,7 +1567,8 @@
      * Adds the given internal name to {@link #typeTable} and returns its index.
      * Does nothing if the type table already contains this internal name.
      *
-     * @param type the internal name to be added to the type table.
+     * @param type
+     *            the internal name to be added to the type table.
      * @return the index of this internal name in the type table.
      */
     int addType(final String type) {
@@ -1527,9 +1585,11 @@
      * index. This method is used for UNINITIALIZED types, made of an internal
      * name and a bytecode offset.
      *
-     * @param type the internal name to be added to the type table.
-     * @param offset the bytecode offset of the NEW instruction that created
-     *        this UNINITIALIZED type value.
+     * @param type
+     *            the internal name to be added to the type table.
+     * @param offset
+     *            the bytecode offset of the NEW instruction that created this
+     *            UNINITIALIZED type value.
      * @return the index of this internal name in the type table.
      */
     int addUninitializedType(final String type, final int offset) {
@@ -1547,7 +1607,8 @@
     /**
      * Adds the given Item to {@link #typeTable}.
      *
-     * @param item the value to be added to the type table.
+     * @param item
+     *            the value to be added to the type table.
      * @return the added Item, which a new Item instance with the same value as
      *         the given Item.
      */
@@ -1573,8 +1634,10 @@
      * {@link #items} hash table to speedup future calls with the same
      * parameters.
      *
-     * @param type1 index of an internal name in {@link #typeTable}.
-     * @param type2 index of an internal name in {@link #typeTable}.
+     * @param type1
+     *            index of an internal name in {@link #typeTable}.
+     * @param type2
+     *            index of an internal name in {@link #typeTable}.
      * @return the index of the common super type of the two given types.
      */
     int getMergedType(final int type1, final int type2) {
@@ -1594,20 +1657,21 @@
 
     /**
      * Returns the common super type of the two given types. The default
-     * implementation of this method <i>loads<i> the two given classes and uses
+     * implementation of this method <i>loads</i> the two given classes and uses
      * the java.lang.Class methods to find the common super class. It can be
      * overridden to compute this common super type in other ways, in particular
      * without actually loading any class, or to take into account the class
      * that is currently being generated by this ClassWriter, which can of
      * course not be loaded since it is under construction.
      *
-     * @param type1 the internal name of a class.
-     * @param type2 the internal name of another class.
+     * @param type1
+     *            the internal name of a class.
+     * @param type2
+     *            the internal name of another class.
      * @return the internal name of the common super class of the two given
      *         classes.
      */
-    protected String getCommonSuperClass(final String type1, final String type2)
-    {
+    protected String getCommonSuperClass(final String type1, final String type2) {
         Class<?> c, d;
         ClassLoader classLoader = getClass().getClassLoader();
         try {
@@ -1636,7 +1700,8 @@
      * Returns the constant pool's hash table item which is equal to the given
      * item.
      *
-     * @param key a constant pool item.
+     * @param key
+     *            a constant pool item.
      * @return the constant pool's hash table item which is equal to the given
      *         item, or <tt>null</tt> if there is no such item.
      */
@@ -1652,7 +1717,8 @@
      * Puts the given item in the constant pool's hash table. The hash table
      * <i>must</i> not already contains this item.
      *
-     * @param i the item to be added to the constant pool's hash table.
+     * @param i
+     *            the item to be added to the constant pool's hash table.
      */
     private void put(final Item i) {
         if (index + typeCount > threshold) {
@@ -1680,9 +1746,12 @@
     /**
      * Puts one byte and two shorts into the constant pool.
      *
-     * @param b a byte.
-     * @param s1 a short.
-     * @param s2 another short.
+     * @param b
+     *            a byte.
+     * @param s1
+     *            a short.
+     * @param s2
+     *            another short.
      */
     private void put122(final int b, final int s1, final int s2) {
         pool.put12(b, s1).putShort(s2);
@@ -1691,9 +1760,12 @@
     /**
      * Puts two bytes and one short into the constant pool.
      *
-     * @param b1 a byte.
-     * @param b2 another byte.
-     * @param s a short.
+     * @param b1
+     *            a byte.
+     * @param b2
+     *            another byte.
+     * @param s
+     *            a short.
      */
     private void put112(final int b1, final int b2, final int s) {
         pool.put11(b1, b2).putShort(s);
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Context.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Context.java
new file mode 100644
index 0000000..e515e57
--- /dev/null
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Context.java
@@ -0,0 +1,174 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm;
+
+/**
+ * Information about a class being parsed in a {@link ClassReader}.
+ *
+ * @author Eric Bruneton
+ */
+class Context {
+
+    /**
+     * Prototypes of the attributes that must be parsed for this class.
+     */
+    Attribute[] attrs;
+
+    /**
+     * The {@link ClassReader} option flags for the parsing of this class.
+     */
+    int flags;
+
+    /**
+     * The buffer used to read strings.
+     */
+    char[] buffer;
+
+    /**
+     * The start index of each bootstrap method.
+     */
+    int[] bootstrapMethods;
+
+    /**
+     * The access flags of the method currently being parsed.
+     */
+    int access;
+
+    /**
+     * The name of the method currently being parsed.
+     */
+    String name;
+
+    /**
+     * The descriptor of the method currently being parsed.
+     */
+    String desc;
+
+    /**
+     * The label objects, indexed by bytecode offset, of the method currently
+     * being parsed (only bytecode offsets for which a label is needed have a
+     * non null associated Label object).
+     */
+    Label[] labels;
+
+    /**
+     * The target of the type annotation currently being parsed.
+     */
+    int typeRef;
+
+    /**
+     * The path of the type annotation currently being parsed.
+     */
+    TypePath typePath;
+
+    /**
+     * The offset of the latest stack map frame that has been parsed.
+     */
+    int offset;
+
+    /**
+     * The labels corresponding to the start of the local variable ranges in the
+     * local variable type annotation currently being parsed.
+     */
+    Label[] start;
+
+    /**
+     * The labels corresponding to the end of the local variable ranges in the
+     * local variable type annotation currently being parsed.
+     */
+    Label[] end;
+
+    /**
+     * The local variable indices for each local variable range in the local
+     * variable type annotation currently being parsed.
+     */
+    int[] index;
+
+    /**
+     * The encoding of the latest stack map frame that has been parsed.
+     */
+    int mode;
+
+    /**
+     * The number of locals in the latest stack map frame that has been parsed.
+     */
+    int localCount;
+
+    /**
+     * The number locals in the latest stack map frame that has been parsed,
+     * minus the number of locals in the previous frame.
+     */
+    int localDiff;
+
+    /**
+     * The local values of the latest stack map frame that has been parsed.
+     */
+    Object[] local;
+
+    /**
+     * The stack size of the latest stack map frame that has been parsed.
+     */
+    int stackCount;
+
+    /**
+     * The stack values of the latest stack map frame that has been parsed.
+     */
+    Object[] stack;
+}
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/FieldVisitor.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/FieldVisitor.java
index 116be9f..7f16c4e 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/FieldVisitor.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/FieldVisitor.java
@@ -59,9 +59,9 @@
 package jdk.internal.org.objectweb.asm;
 
 /**
- * A visitor to visit a Java field. The methods of this class must be called
- * in the following order: ( <tt>visitAnnotation</tt> |
- * <tt>visitAttribute</tt> )* <tt>visitEnd</tt>.
+ * A visitor to visit a Java field. The methods of this class must be called in
+ * the following order: ( <tt>visitAnnotation</tt> |
+ * <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* <tt>visitEnd</tt>.
  *
  * @author Eric Bruneton
  */
@@ -69,7 +69,7 @@
 
     /**
      * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4}.
+     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
      */
     protected final int api;
 
@@ -82,8 +82,9 @@
     /**
      * Constructs a new {@link FieldVisitor}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
      */
     public FieldVisitor(final int api) {
         this(api, null);
@@ -92,15 +93,17 @@
     /**
      * Constructs a new {@link FieldVisitor}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
-     * @param fv the field visitor to which this visitor must delegate method
-     *        calls. May be null.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param fv
+     *            the field visitor to which this visitor must delegate method
+     *            calls. May be null.
      */
     public FieldVisitor(final int api, final FieldVisitor fv) {
-        /*if (api != Opcodes.ASM4) {
+        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
             throw new IllegalArgumentException();
-        }*/
+        }
         this.api = api;
         this.fv = fv;
     }
@@ -108,8 +111,10 @@
     /**
      * Visits an annotation of the field.
      *
-     * @param desc the class descriptor of the annotation class.
-     * @param visible <tt>true</tt> if the annotation is visible at runtime.
+     * @param desc
+     *            the class descriptor of the annotation class.
+     * @param visible
+     *            <tt>true</tt> if the annotation is visible at runtime.
      * @return a visitor to visit the annotation values, or <tt>null</tt> if
      *         this visitor is not interested in visiting this annotation.
      */
@@ -121,9 +126,39 @@
     }
 
     /**
+     * Visits an annotation on the type of the field.
+     *
+     * @param typeRef
+     *            a reference to the annotated type. The sort of this type
+     *            reference must be {@link TypeReference#FIELD FIELD}. See
+     *            {@link TypeReference}.
+     * @param typePath
+     *            the path to the annotated type argument, wildcard bound, array
+     *            element type, or static inner type within 'typeRef'. May be
+     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
+     * @param desc
+     *            the class descriptor of the annotation class.
+     * @param visible
+     *            <tt>true</tt> if the annotation is visible at runtime.
+     * @return a visitor to visit the annotation values, or <tt>null</tt> if
+     *         this visitor is not interested in visiting this annotation.
+     */
+    public AnnotationVisitor visitTypeAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        if (api < Opcodes.ASM5) {
+            throw new RuntimeException();
+        }
+        if (fv != null) {
+            return fv.visitTypeAnnotation(typeRef, typePath, desc, visible);
+        }
+        return null;
+    }
+
+    /**
      * Visits a non standard attribute of the field.
      *
-     * @param attr an attribute.
+     * @param attr
+     *            an attribute.
      */
     public void visitAttribute(Attribute attr) {
         if (fv != null) {
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/FieldWriter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/FieldWriter.java
index 53d3fa2..b30eeac 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/FieldWriter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/FieldWriter.java
@@ -110,6 +110,17 @@
     private AnnotationWriter ianns;
 
     /**
+     * The runtime visible type annotations of this field. May be <tt>null</tt>.
+     */
+    private AnnotationWriter tanns;
+
+    /**
+     * The runtime invisible type annotations of this field. May be
+     * <tt>null</tt>.
+     */
+    private AnnotationWriter itanns;
+
+    /**
      * The non standard attributes of this field. May be <tt>null</tt>.
      */
     private Attribute attrs;
@@ -121,22 +132,22 @@
     /**
      * Constructs a new {@link FieldWriter}.
      *
-     * @param cw the class writer to which this field must be added.
-     * @param access the field's access flags (see {@link Opcodes}).
-     * @param name the field's name.
-     * @param desc the field's descriptor (see {@link Type}).
-     * @param signature the field's signature. May be <tt>null</tt>.
-     * @param value the field's constant value. May be <tt>null</tt>.
+     * @param cw
+     *            the class writer to which this field must be added.
+     * @param access
+     *            the field's access flags (see {@link Opcodes}).
+     * @param name
+     *            the field's name.
+     * @param desc
+     *            the field's descriptor (see {@link Type}).
+     * @param signature
+     *            the field's signature. May be <tt>null</tt>.
+     * @param value
+     *            the field's constant value. May be <tt>null</tt>.
      */
-    FieldWriter(
-        final ClassWriter cw,
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final Object value)
-    {
-        super(Opcodes.ASM4);
+    FieldWriter(final ClassWriter cw, final int access, final String name,
+            final String desc, final String signature, final Object value) {
+        super(Opcodes.ASM5);
         if (cw.firstField == null) {
             cw.firstField = this;
         } else {
@@ -160,10 +171,8 @@
     // ------------------------------------------------------------------------
 
     @Override
-    public AnnotationVisitor visitAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public AnnotationVisitor visitAnnotation(final String desc,
+            final boolean visible) {
         if (!ClassReader.ANNOTATIONS) {
             return null;
         }
@@ -182,6 +191,29 @@
     }
 
     @Override
+    public AnnotationVisitor visitTypeAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        if (!ClassReader.ANNOTATIONS) {
+            return null;
+        }
+        ByteVector bv = new ByteVector();
+        // write target_type and target_info
+        AnnotationWriter.putTarget(typeRef, typePath, bv);
+        // write type, and reserve space for values count
+        bv.putShort(cw.newUTF8(desc)).putShort(0);
+        AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+                bv.length - 2);
+        if (visible) {
+            aw.next = tanns;
+            tanns = aw;
+        } else {
+            aw.next = itanns;
+            itanns = aw;
+        }
+        return aw;
+    }
+
+    @Override
     public void visitAttribute(final Attribute attr) {
         attr.next = attrs;
         attrs = attr;
@@ -206,11 +238,12 @@
             cw.newUTF8("ConstantValue");
             size += 8;
         }
-        if ((access & Opcodes.ACC_SYNTHETIC) != 0
-                && ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0))
-        {
-            cw.newUTF8("Synthetic");
-            size += 6;
+        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+            if ((cw.version & 0xFFFF) < Opcodes.V1_5
+                    || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+                cw.newUTF8("Synthetic");
+                size += 6;
+            }
         }
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             cw.newUTF8("Deprecated");
@@ -228,6 +261,14 @@
             cw.newUTF8("RuntimeInvisibleAnnotations");
             size += 8 + ianns.getSize();
         }
+        if (ClassReader.ANNOTATIONS && tanns != null) {
+            cw.newUTF8("RuntimeVisibleTypeAnnotations");
+            size += 8 + tanns.getSize();
+        }
+        if (ClassReader.ANNOTATIONS && itanns != null) {
+            cw.newUTF8("RuntimeInvisibleTypeAnnotations");
+            size += 8 + itanns.getSize();
+        }
         if (attrs != null) {
             size += attrs.getSize(cw, null, 0, -1, -1);
         }
@@ -237,21 +278,23 @@
     /**
      * Puts the content of this field into the given byte vector.
      *
-     * @param out where the content of this field must be put.
+     * @param out
+     *            where the content of this field must be put.
      */
     void put(final ByteVector out) {
-        int mask = Opcodes.ACC_DEPRECATED
-                | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
-                | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / (ClassWriter.ACC_SYNTHETIC_ATTRIBUTE / Opcodes.ACC_SYNTHETIC));
+        final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC;
+        int mask = Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
+                | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR);
         out.putShort(access & ~mask).putShort(name).putShort(desc);
         int attributeCount = 0;
         if (value != 0) {
             ++attributeCount;
         }
-        if ((access & Opcodes.ACC_SYNTHETIC) != 0
-                && ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0))
-        {
-            ++attributeCount;
+        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+            if ((cw.version & 0xFFFF) < Opcodes.V1_5
+                    || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+                ++attributeCount;
+            }
         }
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             ++attributeCount;
@@ -265,6 +308,12 @@
         if (ClassReader.ANNOTATIONS && ianns != null) {
             ++attributeCount;
         }
+        if (ClassReader.ANNOTATIONS && tanns != null) {
+            ++attributeCount;
+        }
+        if (ClassReader.ANNOTATIONS && itanns != null) {
+            ++attributeCount;
+        }
         if (attrs != null) {
             attributeCount += attrs.getCount();
         }
@@ -273,10 +322,11 @@
             out.putShort(cw.newUTF8("ConstantValue"));
             out.putInt(2).putShort(value);
         }
-        if ((access & Opcodes.ACC_SYNTHETIC) != 0
-                && ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0))
-        {
-            out.putShort(cw.newUTF8("Synthetic")).putInt(0);
+        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+            if ((cw.version & 0xFFFF) < Opcodes.V1_5
+                    || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+                out.putShort(cw.newUTF8("Synthetic")).putInt(0);
+            }
         }
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             out.putShort(cw.newUTF8("Deprecated")).putInt(0);
@@ -293,6 +343,14 @@
             out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
             ianns.put(out);
         }
+        if (ClassReader.ANNOTATIONS && tanns != null) {
+            out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
+            tanns.put(out);
+        }
+        if (ClassReader.ANNOTATIONS && itanns != null) {
+            out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
+            itanns.put(out);
+        }
         if (attrs != null) {
             attrs.put(cw, null, 0, -1, -1, out);
         }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Frame.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Frame.java
index 48e331d..20a94b2 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Frame.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Frame.java
@@ -109,13 +109,13 @@
      * table contains only internal type names (array type descriptors are
      * forbidden - dimensions must be represented through the DIM field).
      *
-     * The LONG and DOUBLE types are always represented by using two slots (LONG +
-     * TOP or DOUBLE + TOP), for local variable types as well as in the operand
-     * stack. This is necessary to be able to simulate DUPx_y instructions,
-     * whose effect would be dependent on the actual type values if types were
-     * always represented by a single slot in the stack (and this is not
-     * possible, since actual type values are not always known - cf LOCAL and
-     * STACK type kinds).
+     * The LONG and DOUBLE types are always represented by using two slots (LONG
+     * + TOP or DOUBLE + TOP), for local variable types as well as in the
+     * operand stack. This is necessary to be able to simulate DUPx_y
+     * instructions, whose effect would be dependent on the actual type values
+     * if types were always represented by a single slot in the stack (and this
+     * is not possible, since actual type values are not always known - cf LOCAL
+     * and STACK type kinds).
      */
 
     /**
@@ -146,9 +146,9 @@
     /**
      * Flag used for LOCAL and STACK types. Indicates that if this type happens
      * to be a long or double type (during the computations of input frames),
-     * then it must be set to TOP because the second word of this value has
-     * been reused to store other data in the basic block. Hence the first word
-     * no longer stores a valid long or double value.
+     * then it must be set to TOP because the second word of this value has been
+     * reused to store other data in the basic block. Hence the first word no
+     * longer stores a valid long or double value.
      */
     static final int TOP_IF_LONG_OR_DOUBLE = 0x800000;
 
@@ -552,7 +552,8 @@
     /**
      * Returns the output frame local variable type at the given index.
      *
-     * @param local the index of the local that must be returned.
+     * @param local
+     *            the index of the local that must be returned.
      * @return the output frame local variable type at the given index.
      */
     private int get(final int local) {
@@ -574,8 +575,10 @@
     /**
      * Sets the output frame local variable type at the given index.
      *
-     * @param local the index of the local that must be set.
-     * @param type the value of the local that must be set.
+     * @param local
+     *            the index of the local that must be set.
+     * @param type
+     *            the value of the local that must be set.
      */
     private void set(final int local, final int type) {
         // creates and/or resizes the output local variables array if necessary
@@ -595,7 +598,8 @@
     /**
      * Pushes a new type onto the output frame stack.
      *
-     * @param type the type that must be pushed.
+     * @param type
+     *            the type that must be pushed.
      */
     private void push(final int type) {
         // creates and/or resizes the output stack array if necessary
@@ -620,10 +624,12 @@
     /**
      * Pushes a new type onto the output frame stack.
      *
-     * @param cw the ClassWriter to which this label belongs.
-     * @param desc the descriptor of the type to be pushed. Can also be a method
-     *        descriptor (in this case this method pushes its return type onto
-     *        the output frame stack).
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param desc
+     *            the descriptor of the type to be pushed. Can also be a method
+     *            descriptor (in this case this method pushes its return type
+     *            onto the output frame stack).
      */
     private void push(final ClassWriter cw, final String desc) {
         int type = type(cw, desc);
@@ -638,72 +644,74 @@
     /**
      * Returns the int encoding of the given type.
      *
-     * @param cw the ClassWriter to which this label belongs.
-     * @param desc a type descriptor.
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param desc
+     *            a type descriptor.
      * @return the int encoding of the given type.
      */
     private static int type(final ClassWriter cw, final String desc) {
         String t;
         int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
         switch (desc.charAt(index)) {
-            case 'V':
-                return 0;
+        case 'V':
+            return 0;
+        case 'Z':
+        case 'C':
+        case 'B':
+        case 'S':
+        case 'I':
+            return INTEGER;
+        case 'F':
+            return FLOAT;
+        case 'J':
+            return LONG;
+        case 'D':
+            return DOUBLE;
+        case 'L':
+            // stores the internal name, not the descriptor!
+            t = desc.substring(index + 1, desc.length() - 1);
+            return OBJECT | cw.addType(t);
+            // case '[':
+        default:
+            // extracts the dimensions and the element type
+            int data;
+            int dims = index + 1;
+            while (desc.charAt(dims) == '[') {
+                ++dims;
+            }
+            switch (desc.charAt(dims)) {
             case 'Z':
+                data = BOOLEAN;
+                break;
             case 'C':
+                data = CHAR;
+                break;
             case 'B':
+                data = BYTE;
+                break;
             case 'S':
+                data = SHORT;
+                break;
             case 'I':
-                return INTEGER;
+                data = INTEGER;
+                break;
             case 'F':
-                return FLOAT;
+                data = FLOAT;
+                break;
             case 'J':
-                return LONG;
+                data = LONG;
+                break;
             case 'D':
-                return DOUBLE;
-            case 'L':
-                // stores the internal name, not the descriptor!
-                t = desc.substring(index + 1, desc.length() - 1);
-                return OBJECT | cw.addType(t);
-                // case '[':
+                data = DOUBLE;
+                break;
+            // case 'L':
             default:
-                // extracts the dimensions and the element type
-                int data;
-                int dims = index + 1;
-                while (desc.charAt(dims) == '[') {
-                    ++dims;
-                }
-                switch (desc.charAt(dims)) {
-                    case 'Z':
-                        data = BOOLEAN;
-                        break;
-                    case 'C':
-                        data = CHAR;
-                        break;
-                    case 'B':
-                        data = BYTE;
-                        break;
-                    case 'S':
-                        data = SHORT;
-                        break;
-                    case 'I':
-                        data = INTEGER;
-                        break;
-                    case 'F':
-                        data = FLOAT;
-                        break;
-                    case 'J':
-                        data = LONG;
-                        break;
-                    case 'D':
-                        data = DOUBLE;
-                        break;
-                    // case 'L':
-                    default:
-                        // stores the internal name, not the descriptor
-                        t = desc.substring(dims + 1, desc.length() - 1);
-                        data = OBJECT | cw.addType(t);
-                }
-                return (dims - index) << 28 | data;
+                // stores the internal name, not the descriptor
+                t = desc.substring(dims + 1, desc.length() - 1);
+                data = OBJECT | cw.addType(t);
+            }
+            return (dims - index) << 28 | data;
         }
     }
 
@@ -724,7 +732,8 @@
     /**
      * Pops the given number of types from the output frame stack.
      *
-     * @param elements the number of types that must be popped.
+     * @param elements
+     *            the number of types that must be popped.
      */
     private void pop(final int elements) {
         if (outputStackTop >= elements) {
@@ -741,9 +750,10 @@
     /**
      * Pops a type from the output frame stack.
      *
-     * @param desc the descriptor of the type to be popped. Can also be a method
-     *        descriptor (in this case this method pops the types corresponding
-     *        to the method arguments).
+     * @param desc
+     *            the descriptor of the type to be popped. Can also be a method
+     *            descriptor (in this case this method pops the types
+     *            corresponding to the method arguments).
      */
     private void pop(final String desc) {
         char c = desc.charAt(0);
@@ -760,7 +770,8 @@
      * Adds a new type to the list of types on which a constructor is invoked in
      * the basic block.
      *
-     * @param var a type on a which a constructor is invoked.
+     * @param var
+     *            a type on a which a constructor is invoked.
      */
     private void init(final int var) {
         // creates and/or resizes the initializations array if necessary
@@ -781,8 +792,10 @@
      * Replaces the given type with the appropriate type if it is one of the
      * types on which a constructor is invoked in the basic block.
      *
-     * @param cw the ClassWriter to which this label belongs.
-     * @param t a type
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param t
+     *            a type
      * @return t or, if t is one of the types on which a constructor is invoked
      *         in the basic block, the type corresponding to this constructor.
      */
@@ -816,17 +829,17 @@
      * Initializes the input frame of the first basic block from the method
      * descriptor.
      *
-     * @param cw the ClassWriter to which this label belongs.
-     * @param access the access flags of the method to which this label belongs.
-     * @param args the formal parameter types of this method.
-     * @param maxLocals the maximum number of local variables of this method.
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param access
+     *            the access flags of the method to which this label belongs.
+     * @param args
+     *            the formal parameter types of this method.
+     * @param maxLocals
+     *            the maximum number of local variables of this method.
      */
-    void initInputFrame(
-        final ClassWriter cw,
-        final int access,
-        final Type[] args,
-        final int maxLocals)
-    {
+    void initInputFrame(final ClassWriter cw, final int access,
+            final Type[] args, final int maxLocals) {
         inputLocals = new int[maxLocals];
         inputStack = new int[0];
         int i = 0;
@@ -852,435 +865,435 @@
     /**
      * Simulates the action of the given instruction on the output stack frame.
      *
-     * @param opcode the opcode of the instruction.
-     * @param arg the operand of the instruction, if any.
-     * @param cw the class writer to which this label belongs.
-     * @param item the operand of the instructions, if any.
+     * @param opcode
+     *            the opcode of the instruction.
+     * @param arg
+     *            the operand of the instruction, if any.
+     * @param cw
+     *            the class writer to which this label belongs.
+     * @param item
+     *            the operand of the instructions, if any.
      */
-    void execute(
-        final int opcode,
-        final int arg,
-        final ClassWriter cw,
-        final Item item)
-    {
+    void execute(final int opcode, final int arg, final ClassWriter cw,
+            final Item item) {
         int t1, t2, t3, t4;
         switch (opcode) {
-            case Opcodes.NOP:
-            case Opcodes.INEG:
-            case Opcodes.LNEG:
-            case Opcodes.FNEG:
-            case Opcodes.DNEG:
-            case Opcodes.I2B:
-            case Opcodes.I2C:
-            case Opcodes.I2S:
-            case Opcodes.GOTO:
-            case Opcodes.RETURN:
-                break;
-            case Opcodes.ACONST_NULL:
-                push(NULL);
-                break;
-            case Opcodes.ICONST_M1:
-            case Opcodes.ICONST_0:
-            case Opcodes.ICONST_1:
-            case Opcodes.ICONST_2:
-            case Opcodes.ICONST_3:
-            case Opcodes.ICONST_4:
-            case Opcodes.ICONST_5:
-            case Opcodes.BIPUSH:
-            case Opcodes.SIPUSH:
-            case Opcodes.ILOAD:
+        case Opcodes.NOP:
+        case Opcodes.INEG:
+        case Opcodes.LNEG:
+        case Opcodes.FNEG:
+        case Opcodes.DNEG:
+        case Opcodes.I2B:
+        case Opcodes.I2C:
+        case Opcodes.I2S:
+        case Opcodes.GOTO:
+        case Opcodes.RETURN:
+            break;
+        case Opcodes.ACONST_NULL:
+            push(NULL);
+            break;
+        case Opcodes.ICONST_M1:
+        case Opcodes.ICONST_0:
+        case Opcodes.ICONST_1:
+        case Opcodes.ICONST_2:
+        case Opcodes.ICONST_3:
+        case Opcodes.ICONST_4:
+        case Opcodes.ICONST_5:
+        case Opcodes.BIPUSH:
+        case Opcodes.SIPUSH:
+        case Opcodes.ILOAD:
+            push(INTEGER);
+            break;
+        case Opcodes.LCONST_0:
+        case Opcodes.LCONST_1:
+        case Opcodes.LLOAD:
+            push(LONG);
+            push(TOP);
+            break;
+        case Opcodes.FCONST_0:
+        case Opcodes.FCONST_1:
+        case Opcodes.FCONST_2:
+        case Opcodes.FLOAD:
+            push(FLOAT);
+            break;
+        case Opcodes.DCONST_0:
+        case Opcodes.DCONST_1:
+        case Opcodes.DLOAD:
+            push(DOUBLE);
+            push(TOP);
+            break;
+        case Opcodes.LDC:
+            switch (item.type) {
+            case ClassWriter.INT:
                 push(INTEGER);
                 break;
-            case Opcodes.LCONST_0:
-            case Opcodes.LCONST_1:
-            case Opcodes.LLOAD:
+            case ClassWriter.LONG:
                 push(LONG);
                 push(TOP);
                 break;
-            case Opcodes.FCONST_0:
-            case Opcodes.FCONST_1:
-            case Opcodes.FCONST_2:
-            case Opcodes.FLOAD:
+            case ClassWriter.FLOAT:
                 push(FLOAT);
                 break;
-            case Opcodes.DCONST_0:
-            case Opcodes.DCONST_1:
-            case Opcodes.DLOAD:
+            case ClassWriter.DOUBLE:
                 push(DOUBLE);
                 push(TOP);
                 break;
-            case Opcodes.LDC:
-                switch (item.type) {
-                    case ClassWriter.INT:
-                        push(INTEGER);
-                        break;
-                    case ClassWriter.LONG:
-                        push(LONG);
-                        push(TOP);
-                        break;
-                    case ClassWriter.FLOAT:
-                        push(FLOAT);
-                        break;
-                    case ClassWriter.DOUBLE:
-                        push(DOUBLE);
-                        push(TOP);
-                        break;
-                    case ClassWriter.CLASS:
-                        push(OBJECT | cw.addType("java/lang/Class"));
-                        break;
-                    case ClassWriter.STR:
-                        push(OBJECT | cw.addType("java/lang/String"));
-                        break;
-                    case ClassWriter.MTYPE:
-                        push(OBJECT | cw.addType("java/lang/invoke/MethodType"));
-                        break;
-                    // case ClassWriter.HANDLE_BASE + [1..9]:
-                    default:
-                        push(OBJECT | cw.addType("java/lang/invoke/MethodHandle"));
-                }
+            case ClassWriter.CLASS:
+                push(OBJECT | cw.addType("java/lang/Class"));
                 break;
-            case Opcodes.ALOAD:
-                push(get(arg));
+            case ClassWriter.STR:
+                push(OBJECT | cw.addType("java/lang/String"));
                 break;
-            case Opcodes.IALOAD:
-            case Opcodes.BALOAD:
-            case Opcodes.CALOAD:
-            case Opcodes.SALOAD:
-                pop(2);
-                push(INTEGER);
+            case ClassWriter.MTYPE:
+                push(OBJECT | cw.addType("java/lang/invoke/MethodType"));
                 break;
-            case Opcodes.LALOAD:
-            case Opcodes.D2L:
-                pop(2);
-                push(LONG);
-                push(TOP);
-                break;
-            case Opcodes.FALOAD:
-                pop(2);
-                push(FLOAT);
-                break;
-            case Opcodes.DALOAD:
-            case Opcodes.L2D:
-                pop(2);
-                push(DOUBLE);
-                push(TOP);
-                break;
-            case Opcodes.AALOAD:
-                pop(1);
-                t1 = pop();
-                push(ELEMENT_OF + t1);
-                break;
-            case Opcodes.ISTORE:
-            case Opcodes.FSTORE:
-            case Opcodes.ASTORE:
-                t1 = pop();
-                set(arg, t1);
-                if (arg > 0) {
-                    t2 = get(arg - 1);
-                    // if t2 is of kind STACK or LOCAL we cannot know its size!
-                    if (t2 == LONG || t2 == DOUBLE) {
-                        set(arg - 1, TOP);
-                    } else if ((t2 & KIND) != BASE) {
-                        set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
-                    }
-                }
-                break;
-            case Opcodes.LSTORE:
-            case Opcodes.DSTORE:
-                pop(1);
-                t1 = pop();
-                set(arg, t1);
-                set(arg + 1, TOP);
-                if (arg > 0) {
-                    t2 = get(arg - 1);
-                    // if t2 is of kind STACK or LOCAL we cannot know its size!
-                    if (t2 == LONG || t2 == DOUBLE) {
-                        set(arg - 1, TOP);
-                    } else if ((t2 & KIND) != BASE) {
-                        set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
-                    }
-                }
-                break;
-            case Opcodes.IASTORE:
-            case Opcodes.BASTORE:
-            case Opcodes.CASTORE:
-            case Opcodes.SASTORE:
-            case Opcodes.FASTORE:
-            case Opcodes.AASTORE:
-                pop(3);
-                break;
-            case Opcodes.LASTORE:
-            case Opcodes.DASTORE:
-                pop(4);
-                break;
-            case Opcodes.POP:
-            case Opcodes.IFEQ:
-            case Opcodes.IFNE:
-            case Opcodes.IFLT:
-            case Opcodes.IFGE:
-            case Opcodes.IFGT:
-            case Opcodes.IFLE:
-            case Opcodes.IRETURN:
-            case Opcodes.FRETURN:
-            case Opcodes.ARETURN:
-            case Opcodes.TABLESWITCH:
-            case Opcodes.LOOKUPSWITCH:
-            case Opcodes.ATHROW:
-            case Opcodes.MONITORENTER:
-            case Opcodes.MONITOREXIT:
-            case Opcodes.IFNULL:
-            case Opcodes.IFNONNULL:
-                pop(1);
-                break;
-            case Opcodes.POP2:
-            case Opcodes.IF_ICMPEQ:
-            case Opcodes.IF_ICMPNE:
-            case Opcodes.IF_ICMPLT:
-            case Opcodes.IF_ICMPGE:
-            case Opcodes.IF_ICMPGT:
-            case Opcodes.IF_ICMPLE:
-            case Opcodes.IF_ACMPEQ:
-            case Opcodes.IF_ACMPNE:
-            case Opcodes.LRETURN:
-            case Opcodes.DRETURN:
-                pop(2);
-                break;
-            case Opcodes.DUP:
-                t1 = pop();
-                push(t1);
-                push(t1);
-                break;
-            case Opcodes.DUP_X1:
-                t1 = pop();
-                t2 = pop();
-                push(t1);
-                push(t2);
-                push(t1);
-                break;
-            case Opcodes.DUP_X2:
-                t1 = pop();
-                t2 = pop();
-                t3 = pop();
-                push(t1);
-                push(t3);
-                push(t2);
-                push(t1);
-                break;
-            case Opcodes.DUP2:
-                t1 = pop();
-                t2 = pop();
-                push(t2);
-                push(t1);
-                push(t2);
-                push(t1);
-                break;
-            case Opcodes.DUP2_X1:
-                t1 = pop();
-                t2 = pop();
-                t3 = pop();
-                push(t2);
-                push(t1);
-                push(t3);
-                push(t2);
-                push(t1);
-                break;
-            case Opcodes.DUP2_X2:
-                t1 = pop();
-                t2 = pop();
-                t3 = pop();
-                t4 = pop();
-                push(t2);
-                push(t1);
-                push(t4);
-                push(t3);
-                push(t2);
-                push(t1);
-                break;
-            case Opcodes.SWAP:
-                t1 = pop();
-                t2 = pop();
-                push(t1);
-                push(t2);
-                break;
-            case Opcodes.IADD:
-            case Opcodes.ISUB:
-            case Opcodes.IMUL:
-            case Opcodes.IDIV:
-            case Opcodes.IREM:
-            case Opcodes.IAND:
-            case Opcodes.IOR:
-            case Opcodes.IXOR:
-            case Opcodes.ISHL:
-            case Opcodes.ISHR:
-            case Opcodes.IUSHR:
-            case Opcodes.L2I:
-            case Opcodes.D2I:
-            case Opcodes.FCMPL:
-            case Opcodes.FCMPG:
-                pop(2);
-                push(INTEGER);
-                break;
-            case Opcodes.LADD:
-            case Opcodes.LSUB:
-            case Opcodes.LMUL:
-            case Opcodes.LDIV:
-            case Opcodes.LREM:
-            case Opcodes.LAND:
-            case Opcodes.LOR:
-            case Opcodes.LXOR:
-                pop(4);
-                push(LONG);
-                push(TOP);
-                break;
-            case Opcodes.FADD:
-            case Opcodes.FSUB:
-            case Opcodes.FMUL:
-            case Opcodes.FDIV:
-            case Opcodes.FREM:
-            case Opcodes.L2F:
-            case Opcodes.D2F:
-                pop(2);
-                push(FLOAT);
-                break;
-            case Opcodes.DADD:
-            case Opcodes.DSUB:
-            case Opcodes.DMUL:
-            case Opcodes.DDIV:
-            case Opcodes.DREM:
-                pop(4);
-                push(DOUBLE);
-                push(TOP);
-                break;
-            case Opcodes.LSHL:
-            case Opcodes.LSHR:
-            case Opcodes.LUSHR:
-                pop(3);
-                push(LONG);
-                push(TOP);
-                break;
-            case Opcodes.IINC:
-                set(arg, INTEGER);
-                break;
-            case Opcodes.I2L:
-            case Opcodes.F2L:
-                pop(1);
-                push(LONG);
-                push(TOP);
-                break;
-            case Opcodes.I2F:
-                pop(1);
-                push(FLOAT);
-                break;
-            case Opcodes.I2D:
-            case Opcodes.F2D:
-                pop(1);
-                push(DOUBLE);
-                push(TOP);
-                break;
-            case Opcodes.F2I:
-            case Opcodes.ARRAYLENGTH:
-            case Opcodes.INSTANCEOF:
-                pop(1);
-                push(INTEGER);
-                break;
-            case Opcodes.LCMP:
-            case Opcodes.DCMPL:
-            case Opcodes.DCMPG:
-                pop(4);
-                push(INTEGER);
-                break;
-            case Opcodes.JSR:
-            case Opcodes.RET:
-                throw new RuntimeException("JSR/RET are not supported with computeFrames option");
-            case Opcodes.GETSTATIC:
-                push(cw, item.strVal3);
-                break;
-            case Opcodes.PUTSTATIC:
-                pop(item.strVal3);
-                break;
-            case Opcodes.GETFIELD:
-                pop(1);
-                push(cw, item.strVal3);
-                break;
-            case Opcodes.PUTFIELD:
-                pop(item.strVal3);
-                pop();
-                break;
-            case Opcodes.INVOKEVIRTUAL:
-            case Opcodes.INVOKESPECIAL:
-            case Opcodes.INVOKESTATIC:
-            case Opcodes.INVOKEINTERFACE:
-                pop(item.strVal3);
-                if (opcode != Opcodes.INVOKESTATIC) {
-                    t1 = pop();
-                    if (opcode == Opcodes.INVOKESPECIAL
-                            && item.strVal2.charAt(0) == '<')
-                    {
-                        init(t1);
-                    }
-                }
-                push(cw, item.strVal3);
-                break;
-            case Opcodes.INVOKEDYNAMIC:
-                pop(item.strVal2);
-                push(cw, item.strVal2);
-                break;
-            case Opcodes.NEW:
-                push(UNINITIALIZED | cw.addUninitializedType(item.strVal1, arg));
-                break;
-            case Opcodes.NEWARRAY:
-                pop();
-                switch (arg) {
-                    case Opcodes.T_BOOLEAN:
-                        push(ARRAY_OF | BOOLEAN);
-                        break;
-                    case Opcodes.T_CHAR:
-                        push(ARRAY_OF | CHAR);
-                        break;
-                    case Opcodes.T_BYTE:
-                        push(ARRAY_OF | BYTE);
-                        break;
-                    case Opcodes.T_SHORT:
-                        push(ARRAY_OF | SHORT);
-                        break;
-                    case Opcodes.T_INT:
-                        push(ARRAY_OF | INTEGER);
-                        break;
-                    case Opcodes.T_FLOAT:
-                        push(ARRAY_OF | FLOAT);
-                        break;
-                    case Opcodes.T_DOUBLE:
-                        push(ARRAY_OF | DOUBLE);
-                        break;
-                    // case Opcodes.T_LONG:
-                    default:
-                        push(ARRAY_OF | LONG);
-                        break;
-                }
-                break;
-            case Opcodes.ANEWARRAY:
-                String s = item.strVal1;
-                pop();
-                if (s.charAt(0) == '[') {
-                    push(cw, '[' + s);
-                } else {
-                    push(ARRAY_OF | OBJECT | cw.addType(s));
-                }
-                break;
-            case Opcodes.CHECKCAST:
-                s = item.strVal1;
-                pop();
-                if (s.charAt(0) == '[') {
-                    push(cw, s);
-                } else {
-                    push(OBJECT | cw.addType(s));
-                }
-                break;
-            // case Opcodes.MULTIANEWARRAY:
+            // case ClassWriter.HANDLE_BASE + [1..9]:
             default:
-                pop(arg);
-                push(cw, item.strVal1);
+                push(OBJECT | cw.addType("java/lang/invoke/MethodHandle"));
+            }
+            break;
+        case Opcodes.ALOAD:
+            push(get(arg));
+            break;
+        case Opcodes.IALOAD:
+        case Opcodes.BALOAD:
+        case Opcodes.CALOAD:
+        case Opcodes.SALOAD:
+            pop(2);
+            push(INTEGER);
+            break;
+        case Opcodes.LALOAD:
+        case Opcodes.D2L:
+            pop(2);
+            push(LONG);
+            push(TOP);
+            break;
+        case Opcodes.FALOAD:
+            pop(2);
+            push(FLOAT);
+            break;
+        case Opcodes.DALOAD:
+        case Opcodes.L2D:
+            pop(2);
+            push(DOUBLE);
+            push(TOP);
+            break;
+        case Opcodes.AALOAD:
+            pop(1);
+            t1 = pop();
+            push(ELEMENT_OF + t1);
+            break;
+        case Opcodes.ISTORE:
+        case Opcodes.FSTORE:
+        case Opcodes.ASTORE:
+            t1 = pop();
+            set(arg, t1);
+            if (arg > 0) {
+                t2 = get(arg - 1);
+                // if t2 is of kind STACK or LOCAL we cannot know its size!
+                if (t2 == LONG || t2 == DOUBLE) {
+                    set(arg - 1, TOP);
+                } else if ((t2 & KIND) != BASE) {
+                    set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
+                }
+            }
+            break;
+        case Opcodes.LSTORE:
+        case Opcodes.DSTORE:
+            pop(1);
+            t1 = pop();
+            set(arg, t1);
+            set(arg + 1, TOP);
+            if (arg > 0) {
+                t2 = get(arg - 1);
+                // if t2 is of kind STACK or LOCAL we cannot know its size!
+                if (t2 == LONG || t2 == DOUBLE) {
+                    set(arg - 1, TOP);
+                } else if ((t2 & KIND) != BASE) {
+                    set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
+                }
+            }
+            break;
+        case Opcodes.IASTORE:
+        case Opcodes.BASTORE:
+        case Opcodes.CASTORE:
+        case Opcodes.SASTORE:
+        case Opcodes.FASTORE:
+        case Opcodes.AASTORE:
+            pop(3);
+            break;
+        case Opcodes.LASTORE:
+        case Opcodes.DASTORE:
+            pop(4);
+            break;
+        case Opcodes.POP:
+        case Opcodes.IFEQ:
+        case Opcodes.IFNE:
+        case Opcodes.IFLT:
+        case Opcodes.IFGE:
+        case Opcodes.IFGT:
+        case Opcodes.IFLE:
+        case Opcodes.IRETURN:
+        case Opcodes.FRETURN:
+        case Opcodes.ARETURN:
+        case Opcodes.TABLESWITCH:
+        case Opcodes.LOOKUPSWITCH:
+        case Opcodes.ATHROW:
+        case Opcodes.MONITORENTER:
+        case Opcodes.MONITOREXIT:
+        case Opcodes.IFNULL:
+        case Opcodes.IFNONNULL:
+            pop(1);
+            break;
+        case Opcodes.POP2:
+        case Opcodes.IF_ICMPEQ:
+        case Opcodes.IF_ICMPNE:
+        case Opcodes.IF_ICMPLT:
+        case Opcodes.IF_ICMPGE:
+        case Opcodes.IF_ICMPGT:
+        case Opcodes.IF_ICMPLE:
+        case Opcodes.IF_ACMPEQ:
+        case Opcodes.IF_ACMPNE:
+        case Opcodes.LRETURN:
+        case Opcodes.DRETURN:
+            pop(2);
+            break;
+        case Opcodes.DUP:
+            t1 = pop();
+            push(t1);
+            push(t1);
+            break;
+        case Opcodes.DUP_X1:
+            t1 = pop();
+            t2 = pop();
+            push(t1);
+            push(t2);
+            push(t1);
+            break;
+        case Opcodes.DUP_X2:
+            t1 = pop();
+            t2 = pop();
+            t3 = pop();
+            push(t1);
+            push(t3);
+            push(t2);
+            push(t1);
+            break;
+        case Opcodes.DUP2:
+            t1 = pop();
+            t2 = pop();
+            push(t2);
+            push(t1);
+            push(t2);
+            push(t1);
+            break;
+        case Opcodes.DUP2_X1:
+            t1 = pop();
+            t2 = pop();
+            t3 = pop();
+            push(t2);
+            push(t1);
+            push(t3);
+            push(t2);
+            push(t1);
+            break;
+        case Opcodes.DUP2_X2:
+            t1 = pop();
+            t2 = pop();
+            t3 = pop();
+            t4 = pop();
+            push(t2);
+            push(t1);
+            push(t4);
+            push(t3);
+            push(t2);
+            push(t1);
+            break;
+        case Opcodes.SWAP:
+            t1 = pop();
+            t2 = pop();
+            push(t1);
+            push(t2);
+            break;
+        case Opcodes.IADD:
+        case Opcodes.ISUB:
+        case Opcodes.IMUL:
+        case Opcodes.IDIV:
+        case Opcodes.IREM:
+        case Opcodes.IAND:
+        case Opcodes.IOR:
+        case Opcodes.IXOR:
+        case Opcodes.ISHL:
+        case Opcodes.ISHR:
+        case Opcodes.IUSHR:
+        case Opcodes.L2I:
+        case Opcodes.D2I:
+        case Opcodes.FCMPL:
+        case Opcodes.FCMPG:
+            pop(2);
+            push(INTEGER);
+            break;
+        case Opcodes.LADD:
+        case Opcodes.LSUB:
+        case Opcodes.LMUL:
+        case Opcodes.LDIV:
+        case Opcodes.LREM:
+        case Opcodes.LAND:
+        case Opcodes.LOR:
+        case Opcodes.LXOR:
+            pop(4);
+            push(LONG);
+            push(TOP);
+            break;
+        case Opcodes.FADD:
+        case Opcodes.FSUB:
+        case Opcodes.FMUL:
+        case Opcodes.FDIV:
+        case Opcodes.FREM:
+        case Opcodes.L2F:
+        case Opcodes.D2F:
+            pop(2);
+            push(FLOAT);
+            break;
+        case Opcodes.DADD:
+        case Opcodes.DSUB:
+        case Opcodes.DMUL:
+        case Opcodes.DDIV:
+        case Opcodes.DREM:
+            pop(4);
+            push(DOUBLE);
+            push(TOP);
+            break;
+        case Opcodes.LSHL:
+        case Opcodes.LSHR:
+        case Opcodes.LUSHR:
+            pop(3);
+            push(LONG);
+            push(TOP);
+            break;
+        case Opcodes.IINC:
+            set(arg, INTEGER);
+            break;
+        case Opcodes.I2L:
+        case Opcodes.F2L:
+            pop(1);
+            push(LONG);
+            push(TOP);
+            break;
+        case Opcodes.I2F:
+            pop(1);
+            push(FLOAT);
+            break;
+        case Opcodes.I2D:
+        case Opcodes.F2D:
+            pop(1);
+            push(DOUBLE);
+            push(TOP);
+            break;
+        case Opcodes.F2I:
+        case Opcodes.ARRAYLENGTH:
+        case Opcodes.INSTANCEOF:
+            pop(1);
+            push(INTEGER);
+            break;
+        case Opcodes.LCMP:
+        case Opcodes.DCMPL:
+        case Opcodes.DCMPG:
+            pop(4);
+            push(INTEGER);
+            break;
+        case Opcodes.JSR:
+        case Opcodes.RET:
+            throw new RuntimeException(
+                    "JSR/RET are not supported with computeFrames option");
+        case Opcodes.GETSTATIC:
+            push(cw, item.strVal3);
+            break;
+        case Opcodes.PUTSTATIC:
+            pop(item.strVal3);
+            break;
+        case Opcodes.GETFIELD:
+            pop(1);
+            push(cw, item.strVal3);
+            break;
+        case Opcodes.PUTFIELD:
+            pop(item.strVal3);
+            pop();
+            break;
+        case Opcodes.INVOKEVIRTUAL:
+        case Opcodes.INVOKESPECIAL:
+        case Opcodes.INVOKESTATIC:
+        case Opcodes.INVOKEINTERFACE:
+            pop(item.strVal3);
+            if (opcode != Opcodes.INVOKESTATIC) {
+                t1 = pop();
+                if (opcode == Opcodes.INVOKESPECIAL
+                        && item.strVal2.charAt(0) == '<') {
+                    init(t1);
+                }
+            }
+            push(cw, item.strVal3);
+            break;
+        case Opcodes.INVOKEDYNAMIC:
+            pop(item.strVal2);
+            push(cw, item.strVal2);
+            break;
+        case Opcodes.NEW:
+            push(UNINITIALIZED | cw.addUninitializedType(item.strVal1, arg));
+            break;
+        case Opcodes.NEWARRAY:
+            pop();
+            switch (arg) {
+            case Opcodes.T_BOOLEAN:
+                push(ARRAY_OF | BOOLEAN);
                 break;
+            case Opcodes.T_CHAR:
+                push(ARRAY_OF | CHAR);
+                break;
+            case Opcodes.T_BYTE:
+                push(ARRAY_OF | BYTE);
+                break;
+            case Opcodes.T_SHORT:
+                push(ARRAY_OF | SHORT);
+                break;
+            case Opcodes.T_INT:
+                push(ARRAY_OF | INTEGER);
+                break;
+            case Opcodes.T_FLOAT:
+                push(ARRAY_OF | FLOAT);
+                break;
+            case Opcodes.T_DOUBLE:
+                push(ARRAY_OF | DOUBLE);
+                break;
+            // case Opcodes.T_LONG:
+            default:
+                push(ARRAY_OF | LONG);
+                break;
+            }
+            break;
+        case Opcodes.ANEWARRAY:
+            String s = item.strVal1;
+            pop();
+            if (s.charAt(0) == '[') {
+                push(cw, '[' + s);
+            } else {
+                push(ARRAY_OF | OBJECT | cw.addType(s));
+            }
+            break;
+        case Opcodes.CHECKCAST:
+            s = item.strVal1;
+            pop();
+            if (s.charAt(0) == '[') {
+                push(cw, s);
+            } else {
+                push(OBJECT | cw.addType(s));
+            }
+            break;
+        // case Opcodes.MULTIANEWARRAY:
+        default:
+            pop(arg);
+            push(cw, item.strVal1);
+            break;
         }
     }
 
@@ -1289,10 +1302,13 @@
      * frames of this basic block. Returns <tt>true</tt> if the input frame of
      * the given label has been changed by this operation.
      *
-     * @param cw the ClassWriter to which this label belongs.
-     * @param frame the basic block whose input frame must be updated.
-     * @param edge the kind of the {@link Edge} between this label and 'label'.
-     *        See {@link Edge#info}.
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param frame
+     *            the basic block whose input frame must be updated.
+     * @param edge
+     *            the kind of the {@link Edge} between this label and 'label'.
+     *            See {@link Edge#info}.
      * @return <tt>true</tt> if the input frame of the given label has been
      *         changed by this operation.
      */
@@ -1323,7 +1339,8 @@
                         } else {
                             t = dim + inputStack[nStack - (s & VALUE)];
                         }
-                        if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 && (t == LONG || t == DOUBLE)) {
+                        if ((s & TOP_IF_LONG_OR_DOUBLE) != 0
+                                && (t == LONG || t == DOUBLE)) {
                             t = TOP;
                         }
                     }
@@ -1375,7 +1392,8 @@
                 } else {
                     t = dim + inputStack[nStack - (s & VALUE)];
                 }
-                if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 && (t == LONG || t == DOUBLE)) {
+                if ((s & TOP_IF_LONG_OR_DOUBLE) != 0
+                        && (t == LONG || t == DOUBLE)) {
                     t = TOP;
                 }
             }
@@ -1392,19 +1410,19 @@
      * type. Returns <tt>true</tt> if the type array has been modified by this
      * operation.
      *
-     * @param cw the ClassWriter to which this label belongs.
-     * @param t the type with which the type array element must be merged.
-     * @param types an array of types.
-     * @param index the index of the type that must be merged in 'types'.
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param t
+     *            the type with which the type array element must be merged.
+     * @param types
+     *            an array of types.
+     * @param index
+     *            the index of the type that must be merged in 'types'.
      * @return <tt>true</tt> if the type array has been modified by this
      *         operation.
      */
-    private static boolean merge(
-        final ClassWriter cw,
-        int t,
-        final int[] types,
-        final int index)
-    {
+    private static boolean merge(final ClassWriter cw, int t,
+            final int[] types, final int index) {
         int u = types[index];
         if (u == t) {
             // if the types are equal, merge(u,t)=u, so there is no change
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Handle.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Handle.java
index a70e385..f262f9a 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Handle.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Handle.java
@@ -95,18 +95,23 @@
     /**
      * Constructs a new field or method handle.
      *
-     * @param tag the kind of field or method designated by this Handle. Must be
-     *        {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
-     *        {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
-     *        {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC},
-     *        {@link Opcodes#H_INVOKESPECIAL},
-     *        {@link Opcodes#H_NEWINVOKESPECIAL} or
-     *        {@link Opcodes#H_INVOKEINTERFACE}.
-     * @param owner the internal name of the field or method designed by this
-     *        handle.
-     * @param name the name of the field or method designated by this handle.
-     * @param desc the descriptor of the field or method designated by this
-     *        handle.
+     * @param tag
+     *            the kind of field or method designated by this Handle. Must be
+     *            {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
+     *            {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
+     *            {@link Opcodes#H_INVOKEVIRTUAL},
+     *            {@link Opcodes#H_INVOKESTATIC},
+     *            {@link Opcodes#H_INVOKESPECIAL},
+     *            {@link Opcodes#H_NEWINVOKESPECIAL} or
+     *            {@link Opcodes#H_INVOKEINTERFACE}.
+     * @param owner
+     *            the internal name of the field or method designed by this
+     *            handle.
+     * @param name
+     *            the name of the field or method designated by this handle.
+     * @param desc
+     *            the descriptor of the field or method designated by this
+     *            handle.
      */
     public Handle(int tag, String owner, String name, String desc) {
         this.tag = tag;
@@ -130,11 +135,9 @@
     }
 
     /**
-     * Returns the internal name of the field or method designed by this
-     * handle.
+     * Returns the internal name of the field or method designed by this handle.
      *
-     * @return the internal name of the field or method designed by this
-     *         handle.
+     * @return the internal name of the field or method designed by this handle.
      */
     public String getOwner() {
         return owner;
@@ -167,8 +170,8 @@
             return false;
         }
         Handle h = (Handle) obj;
-        return tag == h.tag && owner.equals(h.owner)
-                && name.equals(h.name) && desc.equals(h.desc);
+        return tag == h.tag && owner.equals(h.owner) && name.equals(h.name)
+                && desc.equals(h.desc);
     }
 
     @Override
@@ -178,8 +181,13 @@
 
     /**
      * Returns the textual representation of this handle. The textual
-     * representation is: <pre>owner '.' name desc ' ' '(' tag ')'</pre>. As
-     * this format is unambiguous, it can be parsed if necessary.
+     * representation is:
+     *
+     * <pre>
+     * owner '.' name desc ' ' '(' tag ')'
+     * </pre>
+     *
+     * . As this format is unambiguous, it can be parsed if necessary.
      */
     @Override
     public String toString() {
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Handler.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Handler.java
index 72211a3..72a30b2 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Handler.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Handler.java
@@ -101,9 +101,12 @@
      * Removes the range between start and end from the given exception
      * handlers.
      *
-     * @param h an exception handler list.
-     * @param start the start of the range to be removed.
-     * @param end the end of the range to be removed. Maybe null.
+     * @param h
+     *            an exception handler list.
+     * @param start
+     *            the start of the range to be removed.
+     * @param end
+     *            the end of the range to be removed. Maybe null.
      * @return the exception handler list with the start-end range removed.
      */
     static Handler remove(Handler h, Label start, Label end) {
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Item.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Item.java
index 97b56f7..90ff743 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Item.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Item.java
@@ -82,8 +82,8 @@
      * {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
      * {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
      *
-     * MethodHandle constant 9 variations are stored using a range
-     * of 9 values from {@link ClassWriter#HANDLE_BASE} + 1 to
+     * MethodHandle constant 9 variations are stored using a range of 9 values
+     * from {@link ClassWriter#HANDLE_BASE} + 1 to
      * {@link ClassWriter#HANDLE_BASE} + 9.
      *
      * Special Item types are used for Items that are stored in the ClassWriter
@@ -144,7 +144,8 @@
      * Constructs an uninitialized {@link Item} for constant pool element at
      * given position.
      *
-     * @param index index of the item to be constructed.
+     * @param index
+     *            index of the item to be constructed.
      */
     Item(final int index) {
         this.index = index;
@@ -153,8 +154,10 @@
     /**
      * Constructs a copy of the given item.
      *
-     * @param index index of the item to be constructed.
-     * @param i the item that must be copied into the item to be constructed.
+     * @param index
+     *            index of the item to be constructed.
+     * @param i
+     *            the item that must be copied into the item to be constructed.
      */
     Item(final int index, final Item i) {
         this.index = index;
@@ -170,7 +173,8 @@
     /**
      * Sets this item to an integer item.
      *
-     * @param intVal the value of this item.
+     * @param intVal
+     *            the value of this item.
      */
     void set(final int intVal) {
         this.type = ClassWriter.INT;
@@ -181,7 +185,8 @@
     /**
      * Sets this item to a long item.
      *
-     * @param longVal the value of this item.
+     * @param longVal
+     *            the value of this item.
      */
     void set(final long longVal) {
         this.type = ClassWriter.LONG;
@@ -192,7 +197,8 @@
     /**
      * Sets this item to a float item.
      *
-     * @param floatVal the value of this item.
+     * @param floatVal
+     *            the value of this item.
      */
     void set(final float floatVal) {
         this.type = ClassWriter.FLOAT;
@@ -203,7 +209,8 @@
     /**
      * Sets this item to a double item.
      *
-     * @param doubleVal the value of this item.
+     * @param doubleVal
+     *            the value of this item.
      */
     void set(final double doubleVal) {
         this.type = ClassWriter.DOUBLE;
@@ -214,49 +221,53 @@
     /**
      * Sets this item to an item that do not hold a primitive value.
      *
-     * @param type the type of this item.
-     * @param strVal1 first part of the value of this item.
-     * @param strVal2 second part of the value of this item.
-     * @param strVal3 third part of the value of this item.
+     * @param type
+     *            the type of this item.
+     * @param strVal1
+     *            first part of the value of this item.
+     * @param strVal2
+     *            second part of the value of this item.
+     * @param strVal3
+     *            third part of the value of this item.
      */
-    void set(
-        final int type,
-        final String strVal1,
-        final String strVal2,
-        final String strVal3)
-    {
+    void set(final int type, final String strVal1, final String strVal2,
+            final String strVal3) {
         this.type = type;
         this.strVal1 = strVal1;
         this.strVal2 = strVal2;
         this.strVal3 = strVal3;
         switch (type) {
-            case ClassWriter.UTF8:
-            case ClassWriter.STR:
-            case ClassWriter.CLASS:
-            case ClassWriter.MTYPE:
-            case ClassWriter.TYPE_NORMAL:
-                hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
-                return;
-            case ClassWriter.NAME_TYPE:
-                hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
-                        * strVal2.hashCode());
-                return;
-                // ClassWriter.FIELD:
-                // ClassWriter.METH:
-                // ClassWriter.IMETH:
-                // ClassWriter.HANDLE_BASE + 1..9
-            default:
-                hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
-                        * strVal2.hashCode() * strVal3.hashCode());
+        case ClassWriter.UTF8:
+        case ClassWriter.STR:
+        case ClassWriter.CLASS:
+        case ClassWriter.MTYPE:
+        case ClassWriter.TYPE_NORMAL:
+            hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
+            return;
+        case ClassWriter.NAME_TYPE: {
+            hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
+                    * strVal2.hashCode());
+            return;
+        }
+        // ClassWriter.FIELD:
+        // ClassWriter.METH:
+        // ClassWriter.IMETH:
+        // ClassWriter.HANDLE_BASE + 1..9
+        default:
+            hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
+                    * strVal2.hashCode() * strVal3.hashCode());
         }
     }
 
     /**
      * Sets the item to an InvokeDynamic item.
      *
-     * @param name invokedynamic's name.
-     * @param desc invokedynamic's desc.
-     * @param bsmIndex zero based index into the class attribute BootrapMethods.
+     * @param name
+     *            invokedynamic's name.
+     * @param desc
+     *            invokedynamic's desc.
+     * @param bsmIndex
+     *            zero based index into the class attribute BootrapMethods.
      */
     void set(String name, String desc, int bsmIndex) {
         this.type = ClassWriter.INDY;
@@ -270,10 +281,12 @@
     /**
      * Sets the item to a BootstrapMethod item.
      *
-     * @param position position in byte in the class attribute BootrapMethods.
-     * @param hashCode hashcode of the item. This hashcode is processed from
-     *        the hashcode of the bootstrap method and the hashcode of
-     *        all bootstrap arguments.
+     * @param position
+     *            position in byte in the class attribute BootrapMethods.
+     * @param hashCode
+     *            hashcode of the item. This hashcode is processed from the
+     *            hashcode of the bootstrap method and the hashcode of all
+     *            bootstrap arguments.
      */
     void set(int position, int hashCode) {
         this.type = ClassWriter.BSM;
@@ -285,41 +298,42 @@
      * Indicates if the given item is equal to this one. <i>This method assumes
      * that the two items have the same {@link #type}</i>.
      *
-     * @param i the item to be compared to this one. Both items must have the
-     *       same {@link #type}.
+     * @param i
+     *            the item to be compared to this one. Both items must have the
+     *            same {@link #type}.
      * @return <tt>true</tt> if the given item if equal to this one,
      *         <tt>false</tt> otherwise.
      */
     boolean isEqualTo(final Item i) {
         switch (type) {
-            case ClassWriter.UTF8:
-            case ClassWriter.STR:
-            case ClassWriter.CLASS:
-            case ClassWriter.MTYPE:
-            case ClassWriter.TYPE_NORMAL:
-                return i.strVal1.equals(strVal1);
-            case ClassWriter.TYPE_MERGED:
-            case ClassWriter.LONG:
-            case ClassWriter.DOUBLE:
-                return i.longVal == longVal;
-            case ClassWriter.INT:
-            case ClassWriter.FLOAT:
-                return i.intVal == intVal;
-            case ClassWriter.TYPE_UNINIT:
-                return i.intVal == intVal && i.strVal1.equals(strVal1);
-            case ClassWriter.NAME_TYPE:
-                return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2);
-            case ClassWriter.INDY:
-                return i.longVal == longVal && i.strVal1.equals(strVal1)
-                        && i.strVal2.equals(strVal2);
-
-            // case ClassWriter.FIELD:
-            // case ClassWriter.METH:
-            // case ClassWriter.IMETH:
-            // case ClassWriter.HANDLE_BASE + 1..9
-            default:
-                return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2)
-                        && i.strVal3.equals(strVal3);
+        case ClassWriter.UTF8:
+        case ClassWriter.STR:
+        case ClassWriter.CLASS:
+        case ClassWriter.MTYPE:
+        case ClassWriter.TYPE_NORMAL:
+            return i.strVal1.equals(strVal1);
+        case ClassWriter.TYPE_MERGED:
+        case ClassWriter.LONG:
+        case ClassWriter.DOUBLE:
+            return i.longVal == longVal;
+        case ClassWriter.INT:
+        case ClassWriter.FLOAT:
+            return i.intVal == intVal;
+        case ClassWriter.TYPE_UNINIT:
+            return i.intVal == intVal && i.strVal1.equals(strVal1);
+        case ClassWriter.NAME_TYPE:
+            return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2);
+        case ClassWriter.INDY: {
+            return i.longVal == longVal && i.strVal1.equals(strVal1)
+                    && i.strVal2.equals(strVal2);
+        }
+        // case ClassWriter.FIELD:
+        // case ClassWriter.METH:
+        // case ClassWriter.IMETH:
+        // case ClassWriter.HANDLE_BASE + 1..9
+        default:
+            return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2)
+                    && i.strVal3.equals(strVal3);
         }
     }
 
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Label.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Label.java
index 220a6e3..f4bc30d 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Label.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Label.java
@@ -61,9 +61,9 @@
 /**
  * A label represents a position in the bytecode of a method. Labels are used
  * for jump, goto, and switch instructions, and for try catch blocks. A label
- * designates the <i>instruction</i> that is just after. Note however that
- * there can be other elements between a label and the instruction it
- * designates (such as other labels, stack map frames, line numbers, etc.).
+ * designates the <i>instruction</i> that is just after. Note however that there
+ * can be other elements between a label and the instruction it designates (such
+ * as other labels, stack map frames, line numbers, etc.).
  *
  * @author Eric Bruneton
  */
@@ -139,8 +139,8 @@
     /**
      * Field used to associate user information to a label. Warning: this field
      * is used by the ASM tree package. In order to use it with the ASM tree
-     * package you must override the {@link
-     * jdk.internal.org.objectweb.asm.tree.MethodNode#getLabelNode} method.
+     * package you must override the
+     * {@link jdk.internal.org.objectweb.asm.tree.MethodNode#getLabelNode} method.
      */
     public Object info;
 
@@ -183,7 +183,7 @@
      * indicates if this reference uses 2 or 4 bytes, and its absolute value
      * gives the position of the bytecode instruction. This array is also used
      * as a bitset to store the subroutines to which a basic block belongs. This
-     * information is needed in {@linked  MethodWriter#visitMaxs}, after all
+     * information is needed in {@linked MethodWriter#visitMaxs}, after all
      * forward references have been resolved. Hence the same array can be used
      * for both purposes without problems.
      */
@@ -206,11 +206,11 @@
      * state of the local variables and the operand stack at the end of each
      * basic block, called the "output frame", <i>relatively</i> to the frame
      * state at the beginning of the basic block, which is called the "input
-     * frame", and which is <i>unknown</i> during this step. The second step,
-     * in {@link MethodWriter#visitMaxs}, is a fix point algorithm that
-     * computes information about the input frame of each basic block, from the
-     * input state of the first basic block (known from the method signature),
-     * and by the using the previously computed relative output frames.
+     * frame", and which is <i>unknown</i> during this step. The second step, in
+     * {@link MethodWriter#visitMaxs}, is a fix point algorithm that computes
+     * information about the input frame of each basic block, from the input
+     * state of the first basic block (known from the method signature), and by
+     * the using the previously computed relative output frames.
      *
      * The algorithm used to compute the maximum stack size only computes the
      * relative output and absolute input stack heights, while the algorithm
@@ -295,11 +295,13 @@
      * generators or adapters.</i>
      *
      * @return the offset corresponding to this label.
-     * @throws IllegalStateException if this label is not resolved yet.
+     * @throws IllegalStateException
+     *             if this label is not resolved yet.
      */
     public int getOffset() {
         if ((status & RESOLVED) == 0) {
-            throw new IllegalStateException("Label offset position has not been resolved yet");
+            throw new IllegalStateException(
+                    "Label offset position has not been resolved yet");
         }
         return position;
     }
@@ -310,21 +312,21 @@
      * directly. Otherwise, a null offset is written and a new forward reference
      * is declared for this label.
      *
-     * @param owner the code writer that calls this method.
-     * @param out the bytecode of the method.
-     * @param source the position of first byte of the bytecode instruction that
-     *        contains this label.
-     * @param wideOffset <tt>true</tt> if the reference must be stored in 4
-     *        bytes, or <tt>false</tt> if it must be stored with 2 bytes.
-     * @throws IllegalArgumentException if this label has not been created by
-     *         the given code writer.
+     * @param owner
+     *            the code writer that calls this method.
+     * @param out
+     *            the bytecode of the method.
+     * @param source
+     *            the position of first byte of the bytecode instruction that
+     *            contains this label.
+     * @param wideOffset
+     *            <tt>true</tt> if the reference must be stored in 4 bytes, or
+     *            <tt>false</tt> if it must be stored with 2 bytes.
+     * @throws IllegalArgumentException
+     *             if this label has not been created by the given code writer.
      */
-    void put(
-        final MethodWriter owner,
-        final ByteVector out,
-        final int source,
-        final boolean wideOffset)
-    {
+    void put(final MethodWriter owner, final ByteVector out, final int source,
+            final boolean wideOffset) {
         if ((status & RESOLVED) == 0) {
             if (wideOffset) {
                 addReference(-1 - source, out.length);
@@ -348,25 +350,21 @@
      * yet. For backward references, the offset of the reference can be, and
      * must be, computed and stored directly.
      *
-     * @param sourcePosition the position of the referencing instruction. This
-     *        position will be used to compute the offset of this forward
-     *        reference.
-     * @param referencePosition the position where the offset for this forward
-     *        reference must be stored.
+     * @param sourcePosition
+     *            the position of the referencing instruction. This position
+     *            will be used to compute the offset of this forward reference.
+     * @param referencePosition
+     *            the position where the offset for this forward reference must
+     *            be stored.
      */
-    private void addReference(
-        final int sourcePosition,
-        final int referencePosition)
-    {
+    private void addReference(final int sourcePosition,
+            final int referencePosition) {
         if (srcAndRefPositions == null) {
             srcAndRefPositions = new int[6];
         }
         if (referenceCount >= srcAndRefPositions.length) {
             int[] a = new int[srcAndRefPositions.length + 6];
-            System.arraycopy(srcAndRefPositions,
-                    0,
-                    a,
-                    0,
+            System.arraycopy(srcAndRefPositions, 0, a, 0,
                     srcAndRefPositions.length);
             srcAndRefPositions = a;
         }
@@ -380,9 +378,12 @@
      * position becomes known. This method fills in the blanks that where left
      * in the bytecode by each forward reference previously added to this label.
      *
-     * @param owner the code writer that calls this method.
-     * @param position the position of this label in the bytecode.
-     * @param data the bytecode of the method.
+     * @param owner
+     *            the code writer that calls this method.
+     * @param position
+     *            the position of this label in the bytecode.
+     * @param data
+     *            the bytecode of the method.
      * @return <tt>true</tt> if a blank that was left for this label was to
      *         small to store the offset. In such a case the corresponding jump
      *         instruction is replaced with a pseudo instruction (using unused
@@ -390,14 +391,12 @@
      *         instructions will need to be replaced with true instructions with
      *         wider offsets (4 bytes instead of 2). This is done in
      *         {@link MethodWriter#resizeInstructions}.
-     * @throws IllegalArgumentException if this label has already been resolved,
-     *         or if it has not been created by the given code writer.
+     * @throws IllegalArgumentException
+     *             if this label has already been resolved, or if it has not
+     *             been created by the given code writer.
      */
-    boolean resolve(
-        final MethodWriter owner,
-        final int position,
-        final byte[] data)
-    {
+    boolean resolve(final MethodWriter owner, final int position,
+            final byte[] data) {
         boolean needUpdate = false;
         this.status |= RESOLVED;
         this.position = position;
@@ -460,7 +459,8 @@
     /**
      * Returns true is this basic block belongs to the given subroutine.
      *
-     * @param id a subroutine id.
+     * @param id
+     *            a subroutine id.
      * @return true is this basic block belongs to the given subroutine.
      */
     boolean inSubroutine(final long id) {
@@ -474,7 +474,8 @@
      * Returns true if this basic block and the given one belong to a common
      * subroutine.
      *
-     * @param block another basic block.
+     * @param block
+     *            another basic block.
      * @return true if this basic block and the given one belong to a common
      *         subroutine.
      */
@@ -493,8 +494,10 @@
     /**
      * Marks this basic block as belonging to the given subroutine.
      *
-     * @param id a subroutine id.
-     * @param nbSubroutines the total number of subroutines in the method.
+     * @param id
+     *            a subroutine id.
+     * @param nbSubroutines
+     *            the total number of subroutines in the method.
      */
     void addToSubroutine(final long id, final int nbSubroutines) {
         if ((status & VISITED) == 0) {
@@ -510,14 +513,16 @@
      * flow graph to find all the blocks that are reachable from the current
      * block WITHOUT following any JSR target.
      *
-     * @param JSR a JSR block that jumps to this subroutine. If this JSR is not
-     *        null it is added to the successor of the RET blocks found in the
-     *        subroutine.
-     * @param id the id of this subroutine.
-     * @param nbSubroutines the total number of subroutines in the method.
+     * @param JSR
+     *            a JSR block that jumps to this subroutine. If this JSR is not
+     *            null it is added to the successor of the RET blocks found in
+     *            the subroutine.
+     * @param id
+     *            the id of this subroutine.
+     * @param nbSubroutines
+     *            the total number of subroutines in the method.
      */
-    void visitSubroutine(final Label JSR, final long id, final int nbSubroutines)
-    {
+    void visitSubroutine(final Label JSR, final long id, final int nbSubroutines) {
         // user managed stack of labels, to avoid using a recursive method
         // (recursivity can lead to stack overflow with very large methods)
         Label stack = this;
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java
index 241f4fb..f21519e 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java
@@ -59,19 +59,25 @@
 package jdk.internal.org.objectweb.asm;
 
 /**
- * A visitor to visit a Java method. The methods of this class must be
- * called in the following order: [ <tt>visitAnnotationDefault</tt> ] (
- * <tt>visitAnnotation</tt> | <tt>visitParameterAnnotation</tt> |
- * <tt>visitAttribute</tt> )* [ <tt>visitCode</tt> ( <tt>visitFrame</tt> |
- * <tt>visit</tt><i>X</i>Insn</tt> | <tt>visitLabel</tt> | <tt>visitTryCatchBlock</tt> |
- * <tt>visitLocalVariable</tt> | <tt>visitLineNumber</tt> )* <tt>visitMaxs</tt> ]
- * <tt>visitEnd</tt>. In addition, the <tt>visit</tt><i>X</i>Insn</tt>
- * and <tt>visitLabel</tt> methods must be called in the sequential order of
- * the bytecode instructions of the visited code, <tt>visitTryCatchBlock</tt>
- * must be called <i>before</i> the labels passed as arguments have been
- * visited, and the <tt>visitLocalVariable</tt> and <tt>visitLineNumber</tt>
- * methods must be called <i>after</i> the labels passed as arguments have been
- * visited.
+ * A visitor to visit a Java method. The methods of this class must be called in
+ * the following order: ( <tt>visitParameter</tt> )* [
+ * <tt>visitAnnotationDefault</tt> ] ( <tt>visitAnnotation</tt> |
+ * <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* [
+ * <tt>visitCode</tt> ( <tt>visitFrame</tt> | <tt>visit<i>X</i>Insn</tt> |
+ * <tt>visitLabel</tt> | <tt>visitInsnAnnotation</tt> |
+ * <tt>visitTryCatchBlock</tt> | <tt>visitTryCatchBlockAnnotation</tt> |
+ * <tt>visitLocalVariable</tt> | <tt>visitLocalVariableAnnotation</tt> |
+ * <tt>visitLineNumber</tt> )* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In
+ * addition, the <tt>visit<i>X</i>Insn</tt> and <tt>visitLabel</tt>
+ * methods must be called in the sequential order of the bytecode instructions
+ * of the visited code, <tt>visitInsnAnnotation</tt> must be called <i>after</i>
+ * the annotated instruction, <tt>visitTryCatchBlock</tt> must be called
+ * <i>before</i> the labels passed as arguments have been visited,
+ * <tt>visitTryCatchBlockAnnotation</tt> must be called <i>after</i> the
+ * corresponding try catch block has been visited, and the
+ * <tt>visitLocalVariable</tt>, <tt>visitLocalVariableAnnotation</tt> and
+ * <tt>visitLineNumber</tt> methods must be called <i>after</i> the labels
+ * passed as arguments have been visited.
  *
  * @author Eric Bruneton
  */
@@ -79,7 +85,7 @@
 
     /**
      * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4}.
+     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
      */
     protected final int api;
 
@@ -92,8 +98,9 @@
     /**
      * Constructs a new {@link MethodVisitor}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
      */
     public MethodVisitor(final int api) {
         this(api, null);
@@ -102,29 +109,50 @@
     /**
      * Constructs a new {@link MethodVisitor}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
-     * @param mv the method visitor to which this visitor must delegate method
-     *        calls. May be null.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param mv
+     *            the method visitor to which this visitor must delegate method
+     *            calls. May be null.
      */
     public MethodVisitor(final int api, final MethodVisitor mv) {
-        /*if (api != Opcodes.ASM4) {
+        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
             throw new IllegalArgumentException();
-        }*/
+        }
         this.api = api;
         this.mv = mv;
     }
 
     // -------------------------------------------------------------------------
-    // Annotations and non standard attributes
+    // Parameters, annotations and non standard attributes
     // -------------------------------------------------------------------------
 
     /**
+     * Visits a parameter of this method.
+     *
+     * @param name
+     *            parameter name or null if none is provided.
+     * @param access
+     *            the parameter's access flags, only <tt>ACC_FINAL</tt>,
+     *            <tt>ACC_SYNTHETIC</tt> or/and <tt>ACC_MANDATED</tt> are
+     *            allowed (see {@link Opcodes}).
+     */
+    public void visitParameter(String name, int access) {
+        if (api < Opcodes.ASM5) {
+            throw new RuntimeException();
+        }
+        if (mv != null) {
+            mv.visitParameter(name, access);
+        }
+    }
+
+    /**
      * Visits the default value of this annotation interface method.
      *
      * @return a visitor to the visit the actual default value of this
-     *         annotation interface method, or <tt>null</tt> if this visitor
-     *         is not interested in visiting this default value. The 'name'
+     *         annotation interface method, or <tt>null</tt> if this visitor is
+     *         not interested in visiting this default value. The 'name'
      *         parameters passed to the methods of this annotation visitor are
      *         ignored. Moreover, exacly one visit method must be called on this
      *         annotation visitor, followed by visitEnd.
@@ -139,8 +167,10 @@
     /**
      * Visits an annotation of this method.
      *
-     * @param desc the class descriptor of the annotation class.
-     * @param visible <tt>true</tt> if the annotation is visible at runtime.
+     * @param desc
+     *            the class descriptor of the annotation class.
+     * @param visible
+     *            <tt>true</tt> if the annotation is visible at runtime.
      * @return a visitor to visit the annotation values, or <tt>null</tt> if
      *         this visitor is not interested in visiting this annotation.
      */
@@ -152,19 +182,55 @@
     }
 
     /**
-     * Visits an annotation of a parameter this method.
+     * Visits an annotation on a type in the method signature.
      *
-     * @param parameter the parameter index.
-     * @param desc the class descriptor of the annotation class.
-     * @param visible <tt>true</tt> if the annotation is visible at runtime.
+     * @param typeRef
+     *            a reference to the annotated type. The sort of this type
+     *            reference must be {@link TypeReference#METHOD_TYPE_PARAMETER
+     *            METHOD_TYPE_PARAMETER},
+     *            {@link TypeReference#METHOD_TYPE_PARAMETER_BOUND
+     *            METHOD_TYPE_PARAMETER_BOUND},
+     *            {@link TypeReference#METHOD_RETURN METHOD_RETURN},
+     *            {@link TypeReference#METHOD_RECEIVER METHOD_RECEIVER},
+     *            {@link TypeReference#METHOD_FORMAL_PARAMETER
+     *            METHOD_FORMAL_PARAMETER} or {@link TypeReference#THROWS
+     *            THROWS}. See {@link TypeReference}.
+     * @param typePath
+     *            the path to the annotated type argument, wildcard bound, array
+     *            element type, or static inner type within 'typeRef'. May be
+     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
+     * @param desc
+     *            the class descriptor of the annotation class.
+     * @param visible
+     *            <tt>true</tt> if the annotation is visible at runtime.
      * @return a visitor to visit the annotation values, or <tt>null</tt> if
      *         this visitor is not interested in visiting this annotation.
      */
-    public AnnotationVisitor visitParameterAnnotation(
-        int parameter,
-        String desc,
-        boolean visible)
-    {
+    public AnnotationVisitor visitTypeAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        if (api < Opcodes.ASM5) {
+            throw new RuntimeException();
+        }
+        if (mv != null) {
+            return mv.visitTypeAnnotation(typeRef, typePath, desc, visible);
+        }
+        return null;
+    }
+
+    /**
+     * Visits an annotation of a parameter this method.
+     *
+     * @param parameter
+     *            the parameter index.
+     * @param desc
+     *            the class descriptor of the annotation class.
+     * @param visible
+     *            <tt>true</tt> if the annotation is visible at runtime.
+     * @return a visitor to visit the annotation values, or <tt>null</tt> if
+     *         this visitor is not interested in visiting this annotation.
+     */
+    public AnnotationVisitor visitParameterAnnotation(int parameter,
+            String desc, boolean visible) {
         if (mv != null) {
             return mv.visitParameterAnnotation(parameter, desc, visible);
         }
@@ -174,7 +240,8 @@
     /**
      * Visits a non standard attribute of this method.
      *
-     * @param attr an attribute.
+     * @param attr
+     *            an attribute.
      */
     public void visitAttribute(Attribute attr) {
         if (mv != null) {
@@ -198,57 +265,74 @@
      * such as GOTO or THROW, that is the target of a jump instruction, or that
      * starts an exception handler block. The visited types must describe the
      * values of the local variables and of the operand stack elements <i>just
-     * before</i> <b>i</b> is executed. <br> <br> (*) this is mandatory only
-     * for classes whose version is greater than or equal to
-     * {@link Opcodes#V1_6 V1_6}. <br> <br> Packed frames are basically
-     * "deltas" from the state of the previous frame (very first frame is
-     * implicitly defined by the method's parameters and access flags): <ul>
+     * before</i> <b>i</b> is executed.<br>
+     * <br>
+     * (*) this is mandatory only for classes whose version is greater than or
+     * equal to {@link Opcodes#V1_6 V1_6}. <br>
+     * <br>
+     * The frames of a method must be given either in expanded form, or in
+     * compressed form (all frames must use the same format, i.e. you must not
+     * mix expanded and compressed frames within a single method):
+     * <ul>
+     * <li>In expanded form, all frames must have the F_NEW type, and a first
+     * frame corresponding to the method signature must be explicitly visited
+     * before the first instruction.</li>
+     * <li>In compressed form, frames are basically "deltas" from the state of
+     * the previous frame (the first frame, corresponding to the method's
+     * parameters and access flags, is implicit in this form, and must not be
+     * visited):
+     * <ul>
      * <li>{@link Opcodes#F_SAME} representing frame with exactly the same
-     * locals as the previous frame and with the empty stack.</li> <li>{@link Opcodes#F_SAME1}
-     * representing frame with exactly the same locals as the previous frame and
-     * with single value on the stack (<code>nStack</code> is 1 and
-     * <code>stack[0]</code> contains value for the type of the stack item).</li>
+     * locals as the previous frame and with the empty stack.</li>
+     * <li>{@link Opcodes#F_SAME1} representing frame with exactly the same
+     * locals as the previous frame and with single value on the stack (
+     * <code>nStack</code> is 1 and <code>stack[0]</code> contains value for the
+     * type of the stack item).</li>
      * <li>{@link Opcodes#F_APPEND} representing frame with current locals are
      * the same as the locals in the previous frame, except that additional
      * locals are defined (<code>nLocal</code> is 1, 2 or 3 and
      * <code>local</code> elements contains values representing added types).</li>
-     * <li>{@link Opcodes#F_CHOP} representing frame with current locals are
-     * the same as the locals in the previous frame, except that the last 1-3
-     * locals are absent and with the empty stack (<code>nLocals</code> is 1,
-     * 2 or 3). </li> <li>{@link Opcodes#F_FULL} representing complete frame
-     * data.</li> </li> </ul>
+     * <li>{@link Opcodes#F_CHOP} representing frame with current locals are the
+     * same as the locals in the previous frame, except that the last 1-3 locals
+     * are absent and with the empty stack (<code>nLocals</code> is 1, 2 or 3).</li>
+     * <li>{@link Opcodes#F_FULL} representing complete frame data.</li>
+     * </ul></li>
+     * </ul>
      *
-     * @param type the type of this stack map frame. Must be
-     *        {@link Opcodes#F_NEW} for expanded frames, or
-     *        {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
-     *        {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
-     *        {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed
-     *        frames.
-     * @param nLocal the number of local variables in the visited frame.
-     * @param local the local variable types in this frame. This array must not
-     *        be modified. Primitive types are represented by
-     *        {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
-     *        {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
-     *        {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
-     *        {@link Opcodes#UNINITIALIZED_THIS} (long and double are
-     *        represented by a single element). Reference types are represented
-     *        by String objects (representing internal names), and uninitialized
-     *        types by Label objects (this label designates the NEW instruction
-     *        that created this uninitialized value).
-     * @param nStack the number of operand stack elements in the visited frame.
-     * @param stack the operand stack types in this frame. This array must not
-     *        be modified. Its content has the same format as the "local" array.
-     * @throws IllegalStateException if a frame is visited just after another
-     *        one, without any instruction between the two (unless this frame
-     *        is a Opcodes#F_SAME frame, in which case it is silently ignored).
+     * @param type
+     *            the type of this stack map frame. Must be
+     *            {@link Opcodes#F_NEW} for expanded frames, or
+     *            {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
+     *            {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
+     *            {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for
+     *            compressed frames.
+     * @param nLocal
+     *            the number of local variables in the visited frame.
+     * @param local
+     *            the local variable types in this frame. This array must not be
+     *            modified. Primitive types are represented by
+     *            {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
+     *            {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+     *            {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
+     *            {@link Opcodes#UNINITIALIZED_THIS} (long and double are
+     *            represented by a single element). Reference types are
+     *            represented by String objects (representing internal names),
+     *            and uninitialized types by Label objects (this label
+     *            designates the NEW instruction that created this uninitialized
+     *            value).
+     * @param nStack
+     *            the number of operand stack elements in the visited frame.
+     * @param stack
+     *            the operand stack types in this frame. This array must not be
+     *            modified. Its content has the same format as the "local"
+     *            array.
+     * @throws IllegalStateException
+     *             if a frame is visited just after another one, without any
+     *             instruction between the two (unless this frame is a
+     *             Opcodes#F_SAME frame, in which case it is silently ignored).
      */
-    public void visitFrame(
-        int type,
-        int nLocal,
-        Object[] local,
-        int nStack,
-        Object[] stack)
-    {
+    public void visitFrame(int type, int nLocal, Object[] local, int nStack,
+            Object[] stack) {
         if (mv != null) {
             mv.visitFrame(type, nLocal, local, nStack, stack);
         }
@@ -261,20 +345,22 @@
     /**
      * Visits a zero operand instruction.
      *
-     * @param opcode the opcode of the instruction to be visited. This opcode is
-     *        either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2,
-     *        ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, FCONST_0,
-     *        FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD, FALOAD,
-     *        DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE,
-     *        DASTORE, AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP,
-     *        DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP, IADD, LADD, FADD,
-     *        DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV,
-     *        FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL,
-     *        LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR,
-     *        I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B,
-     *        I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN,
-     *        FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW,
-     *        MONITORENTER, or MONITOREXIT.
+     * @param opcode
+     *            the opcode of the instruction to be visited. This opcode is
+     *            either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
+     *            ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1,
+     *            FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD,
+     *            LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD,
+     *            IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE,
+     *            SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1,
+     *            DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB,
+     *            IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM,
+     *            FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR,
+     *            IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D,
+     *            L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S,
+     *            LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
+     *            DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER,
+     *            or MONITOREXIT.
      */
     public void visitInsn(int opcode) {
         if (mv != null) {
@@ -285,17 +371,20 @@
     /**
      * Visits an instruction with a single int operand.
      *
-     * @param opcode the opcode of the instruction to be visited. This opcode is
-     *        either BIPUSH, SIPUSH or NEWARRAY.
-     * @param operand the operand of the instruction to be visited.<br> When
-     *        opcode is BIPUSH, operand value should be between Byte.MIN_VALUE
-     *        and Byte.MAX_VALUE.<br> When opcode is SIPUSH, operand value
-     *        should be between Short.MIN_VALUE and Short.MAX_VALUE.<br> When
-     *        opcode is NEWARRAY, operand value should be one of
-     *        {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
-     *        {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
-     *        {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
-     *        {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
+     * @param opcode
+     *            the opcode of the instruction to be visited. This opcode is
+     *            either BIPUSH, SIPUSH or NEWARRAY.
+     * @param operand
+     *            the operand of the instruction to be visited.<br>
+     *            When opcode is BIPUSH, operand value should be between
+     *            Byte.MIN_VALUE and Byte.MAX_VALUE.<br>
+     *            When opcode is SIPUSH, operand value should be between
+     *            Short.MIN_VALUE and Short.MAX_VALUE.<br>
+     *            When opcode is NEWARRAY, operand value should be one of
+     *            {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
+     *            {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
+     *            {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
+     *            {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
      */
     public void visitIntInsn(int opcode, int operand) {
         if (mv != null) {
@@ -307,11 +396,13 @@
      * Visits a local variable instruction. A local variable instruction is an
      * instruction that loads or stores the value of a local variable.
      *
-     * @param opcode the opcode of the local variable instruction to be visited.
-     *        This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE,
-     *        LSTORE, FSTORE, DSTORE, ASTORE or RET.
-     * @param var the operand of the instruction to be visited. This operand is
-     *        the index of a local variable.
+     * @param opcode
+     *            the opcode of the local variable instruction to be visited.
+     *            This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD,
+     *            ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
+     * @param var
+     *            the operand of the instruction to be visited. This operand is
+     *            the index of a local variable.
      */
     public void visitVarInsn(int opcode, int var) {
         if (mv != null) {
@@ -323,11 +414,13 @@
      * Visits a type instruction. A type instruction is an instruction that
      * takes the internal name of a class as parameter.
      *
-     * @param opcode the opcode of the type instruction to be visited. This
-     *        opcode is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
-     * @param type the operand of the instruction to be visited. This operand
-     *        must be the internal name of an object or array class (see {@link
-     *        Type#getInternalName() getInternalName}).
+     * @param opcode
+     *            the opcode of the type instruction to be visited. This opcode
+     *            is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
+     * @param type
+     *            the operand of the instruction to be visited. This operand
+     *            must be the internal name of an object or array class (see
+     *            {@link Type#getInternalName() getInternalName}).
      */
     public void visitTypeInsn(int opcode, String type) {
         if (mv != null) {
@@ -339,14 +432,19 @@
      * Visits a field instruction. A field instruction is an instruction that
      * loads or stores the value of a field of an object.
      *
-     * @param opcode the opcode of the type instruction to be visited. This
-     *        opcode is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
-     * @param owner the internal name of the field's owner class (see {@link
-     *        Type#getInternalName() getInternalName}).
-     * @param name the field's name.
-     * @param desc the field's descriptor (see {@link Type Type}).
+     * @param opcode
+     *            the opcode of the type instruction to be visited. This opcode
+     *            is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
+     * @param owner
+     *            the internal name of the field's owner class (see
+     *            {@link Type#getInternalName() getInternalName}).
+     * @param name
+     *            the field's name.
+     * @param desc
+     *            the field's descriptor (see {@link Type Type}).
      */
-    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
+    public void visitFieldInsn(int opcode, String owner, String name,
+            String desc) {
         if (mv != null) {
             mv.visitFieldInsn(opcode, owner, name, desc);
         }
@@ -356,15 +454,20 @@
      * Visits a method instruction. A method instruction is an instruction that
      * invokes a method.
      *
-     * @param opcode the opcode of the type instruction to be visited. This
-     *        opcode is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC
-     *        or INVOKEINTERFACE.
-     * @param owner the internal name of the method's owner class (see {@link
-     *        Type#getInternalName() getInternalName}).
-     * @param name the method's name.
-     * @param desc the method's descriptor (see {@link Type Type}).
+     * @param opcode
+     *            the opcode of the type instruction to be visited. This opcode
+     *            is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
+     *            INVOKEINTERFACE.
+     * @param owner
+     *            the internal name of the method's owner class (see
+     *            {@link Type#getInternalName() getInternalName}).
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor (see {@link Type Type}).
      */
-    public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+    public void visitMethodInsn(int opcode, String owner, String name,
+            String desc) {
         if (mv != null) {
             mv.visitMethodInsn(opcode, owner, name, desc);
         }
@@ -373,16 +476,21 @@
     /**
      * Visits an invokedynamic instruction.
      *
-     * @param name the method's name.
-     * @param desc the method's descriptor (see {@link Type Type}).
-     * @param bsm the bootstrap method.
-     * @param bsmArgs the bootstrap method constant arguments. Each argument
-     *        must be an {@link Integer}, {@link Float}, {@link Long},
-     *        {@link Double}, {@link String}, {@link Type} or {@link Handle}
-     *        value. This method is allowed to modify the content of the array
-     *        so a caller should expect that this array may change.
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor (see {@link Type Type}).
+     * @param bsm
+     *            the bootstrap method.
+     * @param bsmArgs
+     *            the bootstrap method constant arguments. Each argument must be
+     *            an {@link Integer}, {@link Float}, {@link Long},
+     *            {@link Double}, {@link String}, {@link Type} or {@link Handle}
+     *            value. This method is allowed to modify the content of the
+     *            array so a caller should expect that this array may change.
      */
-    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
+    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+            Object... bsmArgs) {
         if (mv != null) {
             mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
         }
@@ -392,13 +500,15 @@
      * Visits a jump instruction. A jump instruction is an instruction that may
      * jump to another instruction.
      *
-     * @param opcode the opcode of the type instruction to be visited. This
-     *        opcode is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
-     *        IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ,
-     *        IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
-     * @param label the operand of the instruction to be visited. This operand
-     *        is a label that designates the instruction to which the jump
-     *        instruction may jump.
+     * @param opcode
+     *            the opcode of the type instruction to be visited. This opcode
+     *            is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
+     *            IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
+     *            IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
+     * @param label
+     *            the operand of the instruction to be visited. This operand is
+     *            a label that designates the instruction to which the jump
+     *            instruction may jump.
      */
     public void visitJumpInsn(int opcode, Label label) {
         if (mv != null) {
@@ -410,7 +520,8 @@
      * Visits a label. A label designates the instruction that will be visited
      * just after it.
      *
-     * @param label a {@link Label Label} object.
+     * @param label
+     *            a {@link Label Label} object.
      */
     public void visitLabel(Label label) {
         if (mv != null) {
@@ -427,41 +538,44 @@
      * future versions of the Java Virtual Machine. To easily detect new
      * constant types, implementations of this method should check for
      * unexpected constant types, like this:
+     *
      * <pre>
      * if (cst instanceof Integer) {
-     *   // ...
+     *     // ...
      * } else if (cst instanceof Float) {
-     *   // ...
+     *     // ...
      * } else if (cst instanceof Long) {
-     *   // ...
+     *     // ...
      * } else if (cst instanceof Double) {
-     *   // ...
+     *     // ...
      * } else if (cst instanceof String) {
-     *   // ...
+     *     // ...
      * } else if (cst instanceof Type) {
-     *   int sort = ((Type) cst).getSort();
-     *   if (sort == Type.OBJECT) {
-     *     // ...
-     *   } else if (sort == Type.ARRAY) {
-     *     // ...
-     *   } else if (sort == Type.METHOD) {
-     *     // ...
-     *   } else {
-     *     // throw an exception
-     *   }
+     *     int sort = ((Type) cst).getSort();
+     *     if (sort == Type.OBJECT) {
+     *         // ...
+     *     } else if (sort == Type.ARRAY) {
+     *         // ...
+     *     } else if (sort == Type.METHOD) {
+     *         // ...
+     *     } else {
+     *         // throw an exception
+     *     }
      * } else if (cst instanceof Handle) {
-     *   // ...
+     *     // ...
      * } else {
-     *   // throw an exception
-     * }</pre>
+     *     // throw an exception
+     * }
+     * </pre>
      *
-     * @param cst the constant to be loaded on the stack. This parameter must be
-     *        a non null {@link Integer}, a {@link Float}, a {@link Long}, a
-     *        {@link Double}, a {@link String}, a {@link Type} of OBJECT or ARRAY
-     *        sort for <tt>.class</tt> constants, for classes whose version is
-     *        49.0, a {@link Type} of METHOD sort or a {@link Handle} for
-     *        MethodType and MethodHandle constants, for classes whose version
-     *        is 51.0.
+     * @param cst
+     *            the constant to be loaded on the stack. This parameter must be
+     *            a non null {@link Integer}, a {@link Float}, a {@link Long}, a
+     *            {@link Double}, a {@link String}, a {@link Type} of OBJECT or
+     *            ARRAY sort for <tt>.class</tt> constants, for classes whose
+     *            version is 49.0, a {@link Type} of METHOD sort or a
+     *            {@link Handle} for MethodType and MethodHandle constants, for
+     *            classes whose version is 51.0.
      */
     public void visitLdcInsn(Object cst) {
         if (mv != null) {
@@ -472,8 +586,10 @@
     /**
      * Visits an IINC instruction.
      *
-     * @param var index of the local variable to be incremented.
-     * @param increment amount to increment the local variable by.
+     * @param var
+     *            index of the local variable to be incremented.
+     * @param increment
+     *            amount to increment the local variable by.
      */
     public void visitIincInsn(int var, int increment) {
         if (mv != null) {
@@ -484,13 +600,18 @@
     /**
      * Visits a TABLESWITCH instruction.
      *
-     * @param min the minimum key value.
-     * @param max the maximum key value.
-     * @param dflt beginning of the default handler block.
-     * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is
-     *        the beginning of the handler block for the <tt>min + i</tt> key.
+     * @param min
+     *            the minimum key value.
+     * @param max
+     *            the maximum key value.
+     * @param dflt
+     *            beginning of the default handler block.
+     * @param labels
+     *            beginnings of the handler blocks. <tt>labels[i]</tt> is the
+     *            beginning of the handler block for the <tt>min + i</tt> key.
      */
-    public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
+    public void visitTableSwitchInsn(int min, int max, Label dflt,
+            Label... labels) {
         if (mv != null) {
             mv.visitTableSwitchInsn(min, max, dflt, labels);
         }
@@ -499,10 +620,13 @@
     /**
      * Visits a LOOKUPSWITCH instruction.
      *
-     * @param dflt beginning of the default handler block.
-     * @param keys the values of the keys.
-     * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is
-     *        the beginning of the handler block for the <tt>keys[i]</tt> key.
+     * @param dflt
+     *            beginning of the default handler block.
+     * @param keys
+     *            the values of the keys.
+     * @param labels
+     *            beginnings of the handler blocks. <tt>labels[i]</tt> is the
+     *            beginning of the handler block for the <tt>keys[i]</tt> key.
      */
     public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
         if (mv != null) {
@@ -513,8 +637,10 @@
     /**
      * Visits a MULTIANEWARRAY instruction.
      *
-     * @param desc an array type descriptor (see {@link Type Type}).
-     * @param dims number of dimensions of the array to allocate.
+     * @param desc
+     *            an array type descriptor (see {@link Type Type}).
+     * @param dims
+     *            number of dimensions of the array to allocate.
      */
     public void visitMultiANewArrayInsn(String desc, int dims) {
         if (mv != null) {
@@ -522,6 +648,48 @@
         }
     }
 
+    /**
+     * Visits an annotation on an instruction. This method must be called just
+     * <i>after</i> the annotated instruction. It can be called several times
+     * for the same instruction.
+     *
+     * @param typeRef
+     *            a reference to the annotated type. The sort of this type
+     *            reference must be {@link TypeReference#INSTANCEOF INSTANCEOF},
+     *            {@link TypeReference#NEW NEW},
+     *            {@link TypeReference#CONSTRUCTOR_REFERENCE
+     *            CONSTRUCTOR_REFERENCE}, {@link TypeReference#METHOD_REFERENCE
+     *            METHOD_REFERENCE}, {@link TypeReference#CAST CAST},
+     *            {@link TypeReference#CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+     *            CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
+     *            {@link TypeReference#METHOD_INVOCATION_TYPE_ARGUMENT
+     *            METHOD_INVOCATION_TYPE_ARGUMENT},
+     *            {@link TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+     *            CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
+     *            {@link TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT
+     *            METHOD_REFERENCE_TYPE_ARGUMENT}. See {@link TypeReference}.
+     * @param typePath
+     *            the path to the annotated type argument, wildcard bound, array
+     *            element type, or static inner type within 'typeRef'. May be
+     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
+     * @param desc
+     *            the class descriptor of the annotation class.
+     * @param visible
+     *            <tt>true</tt> if the annotation is visible at runtime.
+     * @return a visitor to visit the annotation values, or <tt>null</tt> if
+     *         this visitor is not interested in visiting this annotation.
+     */
+    public AnnotationVisitor visitInsnAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        if (api < Opcodes.ASM5) {
+            throw new RuntimeException();
+        }
+        if (mv != null) {
+            return mv.visitInsnAnnotation(typeRef, typePath, desc, visible);
+        }
+        return null;
+    }
+
     // -------------------------------------------------------------------------
     // Exceptions table entries, debug information, max stack and max locals
     // -------------------------------------------------------------------------
@@ -529,61 +697,142 @@
     /**
      * Visits a try catch block.
      *
-     * @param start beginning of the exception handler's scope (inclusive).
-     * @param end end of the exception handler's scope (exclusive).
-     * @param handler beginning of the exception handler's code.
-     * @param type internal name of the type of exceptions handled by the
-     *        handler, or <tt>null</tt> to catch any exceptions (for "finally"
-     *        blocks).
-     * @throws IllegalArgumentException if one of the labels has already been
-     *         visited by this visitor (by the {@link #visitLabel visitLabel}
-     *         method).
+     * @param start
+     *            beginning of the exception handler's scope (inclusive).
+     * @param end
+     *            end of the exception handler's scope (exclusive).
+     * @param handler
+     *            beginning of the exception handler's code.
+     * @param type
+     *            internal name of the type of exceptions handled by the
+     *            handler, or <tt>null</tt> to catch any exceptions (for
+     *            "finally" blocks).
+     * @throws IllegalArgumentException
+     *             if one of the labels has already been visited by this visitor
+     *             (by the {@link #visitLabel visitLabel} method).
      */
-    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
+    public void visitTryCatchBlock(Label start, Label end, Label handler,
+            String type) {
         if (mv != null) {
             mv.visitTryCatchBlock(start, end, handler, type);
         }
     }
 
     /**
+     * Visits an annotation on an exception handler type. This method must be
+     * called <i>after</i> the {@link #visitTryCatchBlock} for the annotated
+     * exception handler. It can be called several times for the same exception
+     * handler.
+     *
+     * @param typeRef
+     *            a reference to the annotated type. The sort of this type
+     *            reference must be {@link TypeReference#EXCEPTION_PARAMETER
+     *            EXCEPTION_PARAMETER}. See {@link TypeReference}.
+     * @param typePath
+     *            the path to the annotated type argument, wildcard bound, array
+     *            element type, or static inner type within 'typeRef'. May be
+     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
+     * @param desc
+     *            the class descriptor of the annotation class.
+     * @param visible
+     *            <tt>true</tt> if the annotation is visible at runtime.
+     * @return a visitor to visit the annotation values, or <tt>null</tt> if
+     *         this visitor is not interested in visiting this annotation.
+     */
+    public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        if (api < Opcodes.ASM5) {
+            throw new RuntimeException();
+        }
+        if (mv != null) {
+            return mv.visitTryCatchAnnotation(typeRef, typePath, desc, visible);
+        }
+        return null;
+    }
+
+    /**
      * Visits a local variable declaration.
      *
-     * @param name the name of a local variable.
-     * @param desc the type descriptor of this local variable.
-     * @param signature the type signature of this local variable. May be
-     *        <tt>null</tt> if the local variable type does not use generic
-     *        types.
-     * @param start the first instruction corresponding to the scope of this
-     *        local variable (inclusive).
-     * @param end the last instruction corresponding to the scope of this local
-     *        variable (exclusive).
-     * @param index the local variable's index.
-     * @throws IllegalArgumentException if one of the labels has not already
-     *         been visited by this visitor (by the
-     *         {@link #visitLabel visitLabel} method).
+     * @param name
+     *            the name of a local variable.
+     * @param desc
+     *            the type descriptor of this local variable.
+     * @param signature
+     *            the type signature of this local variable. May be
+     *            <tt>null</tt> if the local variable type does not use generic
+     *            types.
+     * @param start
+     *            the first instruction corresponding to the scope of this local
+     *            variable (inclusive).
+     * @param end
+     *            the last instruction corresponding to the scope of this local
+     *            variable (exclusive).
+     * @param index
+     *            the local variable's index.
+     * @throws IllegalArgumentException
+     *             if one of the labels has not already been visited by this
+     *             visitor (by the {@link #visitLabel visitLabel} method).
      */
-    public void visitLocalVariable(
-        String name,
-        String desc,
-        String signature,
-        Label start,
-        Label end,
-        int index)
-    {
+    public void visitLocalVariable(String name, String desc, String signature,
+            Label start, Label end, int index) {
         if (mv != null) {
             mv.visitLocalVariable(name, desc, signature, start, end, index);
         }
     }
 
     /**
+     * Visits an annotation on a local variable type.
+     *
+     * @param typeRef
+     *            a reference to the annotated type. The sort of this type
+     *            reference must be {@link TypeReference#LOCAL_VARIABLE
+     *            LOCAL_VARIABLE} or {@link TypeReference#RESOURCE_VARIABLE
+     *            RESOURCE_VARIABLE}. See {@link TypeReference}.
+     * @param typePath
+     *            the path to the annotated type argument, wildcard bound, array
+     *            element type, or static inner type within 'typeRef'. May be
+     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
+     * @param start
+     *            the fist instructions corresponding to the continuous ranges
+     *            that make the scope of this local variable (inclusive).
+     * @param end
+     *            the last instructions corresponding to the continuous ranges
+     *            that make the scope of this local variable (exclusive). This
+     *            array must have the same size as the 'start' array.
+     * @param index
+     *            the local variable's index in each range. This array must have
+     *            the same size as the 'start' array.
+     * @param desc
+     *            the class descriptor of the annotation class.
+     * @param visible
+     *            <tt>true</tt> if the annotation is visible at runtime.
+     * @return a visitor to visit the annotation values, or <tt>null</tt> if
+     *         this visitor is not interested in visiting this annotation.
+     */
+    public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
+            TypePath typePath, Label[] start, Label[] end, int[] index,
+            String desc, boolean visible) {
+        if (api < Opcodes.ASM5) {
+            throw new RuntimeException();
+        }
+        if (mv != null) {
+            return mv.visitLocalVariableAnnotation(typeRef, typePath, start,
+                    end, index, desc, visible);
+        }
+        return null;
+    }
+
+    /**
      * Visits a line number declaration.
      *
-     * @param line a line number. This number refers to the source file from
-     *        which the class was compiled.
-     * @param start the first instruction corresponding to this line number.
-     * @throws IllegalArgumentException if <tt>start</tt> has not already been
-     *         visited by this visitor (by the {@link #visitLabel visitLabel}
-     *         method).
+     * @param line
+     *            a line number. This number refers to the source file from
+     *            which the class was compiled.
+     * @param start
+     *            the first instruction corresponding to this line number.
+     * @throws IllegalArgumentException
+     *             if <tt>start</tt> has not already been visited by this
+     *             visitor (by the {@link #visitLabel visitLabel} method).
      */
     public void visitLineNumber(int line, Label start) {
         if (mv != null) {
@@ -595,8 +844,10 @@
      * Visits the maximum stack size and the maximum number of local variables
      * of the method.
      *
-     * @param maxStack maximum stack size of the method.
-     * @param maxLocals maximum number of local variables for the method.
+     * @param maxStack
+     *            maximum stack size of the method.
+     * @param maxLocals
+     *            maximum number of local variables for the method.
      */
     public void visitMaxs(int maxStack, int maxLocals) {
         if (mv != null) {
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java
index e43ecb1..f59abfa 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java
@@ -221,6 +221,18 @@
     private AnnotationWriter ianns;
 
     /**
+     * The runtime visible type annotations of this method. May be <tt>null</tt>
+     * .
+     */
+    private AnnotationWriter tanns;
+
+    /**
+     * The runtime invisible type annotations of this method. May be
+     * <tt>null</tt>.
+     */
+    private AnnotationWriter itanns;
+
+    /**
      * The runtime visible parameter annotations of this method. May be
      * <tt>null</tt>.
      */
@@ -258,7 +270,7 @@
     private int maxLocals;
 
     /**
-     *  Number of local variables in the current stack map frame.
+     * Number of local variables in the current stack map frame.
      */
     private int currentLocals;
 
@@ -317,6 +329,16 @@
     private Handler lastHandler;
 
     /**
+     * Number of entries in the MethodParameters attribute.
+     */
+    private int methodParametersCount;
+
+    /**
+     * The MethodParameters attribute.
+     */
+    private ByteVector methodParameters;
+
+    /**
      * Number of entries in the LocalVariableTable attribute.
      */
     private int localVarCount;
@@ -347,6 +369,21 @@
     private ByteVector lineNumber;
 
     /**
+     * The start offset of the last visited instruction.
+     */
+    private int lastCodeOffset;
+
+    /**
+     * The runtime visible type annotations of the code. May be <tt>null</tt>.
+     */
+    private AnnotationWriter ctanns;
+
+    /**
+     * The runtime invisible type annotations of the code. May be <tt>null</tt>.
+     */
+    private AnnotationWriter ictanns;
+
+    /**
      * The non standard attributes of the method's code.
      */
     private Attribute cattrs;
@@ -386,7 +423,8 @@
      * A list of labels. This list is the list of basic blocks in the method,
      * i.e. a list of Label objects linked to each other by their
      * {@link Label#successor} field, in the order they are visited by
-     * {@link MethodVisitor#visitLabel}, and starting with the first basic block.
+     * {@link MethodVisitor#visitLabel}, and starting with the first basic
+     * block.
      */
     private Label labels;
 
@@ -425,29 +463,31 @@
     /**
      * Constructs a new {@link MethodWriter}.
      *
-     * @param cw the class writer in which the method must be added.
-     * @param access the method's access flags (see {@link Opcodes}).
-     * @param name the method's name.
-     * @param desc the method's descriptor (see {@link Type}).
-     * @param signature the method's signature. May be <tt>null</tt>.
-     * @param exceptions the internal names of the method's exceptions. May be
-     *        <tt>null</tt>.
-     * @param computeMaxs <tt>true</tt> if the maximum stack size and number
-     *        of local variables must be automatically computed.
-     * @param computeFrames <tt>true</tt> if the stack map tables must be
-     *        recomputed from scratch.
+     * @param cw
+     *            the class writer in which the method must be added.
+     * @param access
+     *            the method's access flags (see {@link Opcodes}).
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor (see {@link Type}).
+     * @param signature
+     *            the method's signature. May be <tt>null</tt>.
+     * @param exceptions
+     *            the internal names of the method's exceptions. May be
+     *            <tt>null</tt>.
+     * @param computeMaxs
+     *            <tt>true</tt> if the maximum stack size and number of local
+     *            variables must be automatically computed.
+     * @param computeFrames
+     *            <tt>true</tt> if the stack map tables must be recomputed from
+     *            scratch.
      */
-    MethodWriter(
-        final ClassWriter cw,
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final String[] exceptions,
-        final boolean computeMaxs,
-        final boolean computeFrames)
-    {
-        super(Opcodes.ASM4);
+    MethodWriter(final ClassWriter cw, final int access, final String name,
+            final String desc, final String signature,
+            final String[] exceptions, final boolean computeMaxs,
+            final boolean computeFrames) {
+        super(Opcodes.ASM5);
         if (cw.firstMethod == null) {
             cw.firstMethod = this;
         } else {
@@ -493,6 +533,16 @@
     // ------------------------------------------------------------------------
 
     @Override
+    public void visitParameter(String name, int access) {
+        if (methodParameters == null) {
+            methodParameters = new ByteVector();
+        }
+        ++methodParametersCount;
+        methodParameters.putShort((name == null) ? 0 : cw.newUTF8(name))
+                .putShort(access);
+    }
+
+    @Override
     public AnnotationVisitor visitAnnotationDefault() {
         if (!ClassReader.ANNOTATIONS) {
             return null;
@@ -502,10 +552,8 @@
     }
 
     @Override
-    public AnnotationVisitor visitAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public AnnotationVisitor visitAnnotation(final String desc,
+            final boolean visible) {
         if (!ClassReader.ANNOTATIONS) {
             return null;
         }
@@ -524,11 +572,31 @@
     }
 
     @Override
-    public AnnotationVisitor visitParameterAnnotation(
-        final int parameter,
-        final String desc,
-        final boolean visible)
-    {
+    public AnnotationVisitor visitTypeAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        if (!ClassReader.ANNOTATIONS) {
+            return null;
+        }
+        ByteVector bv = new ByteVector();
+        // write target_type and target_info
+        AnnotationWriter.putTarget(typeRef, typePath, bv);
+        // write type, and reserve space for values count
+        bv.putShort(cw.newUTF8(desc)).putShort(0);
+        AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+                bv.length - 2);
+        if (visible) {
+            aw.next = tanns;
+            tanns = aw;
+        } else {
+            aw.next = itanns;
+            itanns = aw;
+        }
+        return aw;
+    }
+
+    @Override
+    public AnnotationVisitor visitParameterAnnotation(final int parameter,
+            final String desc, final boolean visible) {
         if (!ClassReader.ANNOTATIONS) {
             return null;
         }
@@ -574,13 +642,8 @@
     }
 
     @Override
-    public void visitFrame(
-        final int type,
-        final int nLocal,
-        final Object[] local,
-        final int nStack,
-        final Object[] stack)
-    {
+    public void visitFrame(final int type, final int nLocal,
+            final Object[] local, final int nStack, final Object[] stack) {
         if (!ClassReader.FRAMES || compute == FRAMES) {
             return;
         }
@@ -630,48 +693,44 @@
             }
 
             switch (type) {
-                case Opcodes.F_FULL:
-                    currentLocals = nLocal;
-                    stackMap.putByte(FULL_FRAME)
-                            .putShort(delta)
-                            .putShort(nLocal);
-                    for (int i = 0; i < nLocal; ++i) {
-                        writeFrameType(local[i]);
-                    }
-                    stackMap.putShort(nStack);
-                    for (int i = 0; i < nStack; ++i) {
-                        writeFrameType(stack[i]);
-                    }
-                    break;
-                case Opcodes.F_APPEND:
-                    currentLocals += nLocal;
-                    stackMap.putByte(SAME_FRAME_EXTENDED + nLocal)
+            case Opcodes.F_FULL:
+                currentLocals = nLocal;
+                stackMap.putByte(FULL_FRAME).putShort(delta).putShort(nLocal);
+                for (int i = 0; i < nLocal; ++i) {
+                    writeFrameType(local[i]);
+                }
+                stackMap.putShort(nStack);
+                for (int i = 0; i < nStack; ++i) {
+                    writeFrameType(stack[i]);
+                }
+                break;
+            case Opcodes.F_APPEND:
+                currentLocals += nLocal;
+                stackMap.putByte(SAME_FRAME_EXTENDED + nLocal).putShort(delta);
+                for (int i = 0; i < nLocal; ++i) {
+                    writeFrameType(local[i]);
+                }
+                break;
+            case Opcodes.F_CHOP:
+                currentLocals -= nLocal;
+                stackMap.putByte(SAME_FRAME_EXTENDED - nLocal).putShort(delta);
+                break;
+            case Opcodes.F_SAME:
+                if (delta < 64) {
+                    stackMap.putByte(delta);
+                } else {
+                    stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta);
+                }
+                break;
+            case Opcodes.F_SAME1:
+                if (delta < 64) {
+                    stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta);
+                } else {
+                    stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
                             .putShort(delta);
-                    for (int i = 0; i < nLocal; ++i) {
-                        writeFrameType(local[i]);
-                    }
-                    break;
-                case Opcodes.F_CHOP:
-                    currentLocals -= nLocal;
-                    stackMap.putByte(SAME_FRAME_EXTENDED - nLocal)
-                            .putShort(delta);
-                    break;
-                case Opcodes.F_SAME:
-                    if (delta < 64) {
-                        stackMap.putByte(delta);
-                    } else {
-                        stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta);
-                    }
-                    break;
-                case Opcodes.F_SAME1:
-                    if (delta < 64) {
-                        stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta);
-                    } else {
-                        stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
-                                .putShort(delta);
-                    }
-                    writeFrameType(stack[0]);
-                    break;
+                }
+                writeFrameType(stack[0]);
+                break;
             }
 
             previousFrameOffset = code.length;
@@ -684,6 +743,7 @@
 
     @Override
     public void visitInsn(final int opcode) {
+        lastCodeOffset = code.length;
         // adds the instruction to the bytecode of the method
         code.putByte(opcode);
         // update currentBlock
@@ -701,8 +761,7 @@
             }
             // if opcode == ATHROW or xRETURN, ends current block (no successor)
             if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN)
-                    || opcode == Opcodes.ATHROW)
-            {
+                    || opcode == Opcodes.ATHROW) {
                 noSuccessor();
             }
         }
@@ -710,6 +769,7 @@
 
     @Override
     public void visitIntInsn(final int opcode, final int operand) {
+        lastCodeOffset = code.length;
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
             if (compute == FRAMES) {
@@ -734,6 +794,7 @@
 
     @Override
     public void visitVarInsn(final int opcode, final int var) {
+        lastCodeOffset = code.length;
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
             if (compute == FRAMES) {
@@ -760,8 +821,7 @@
             // updates max locals
             int n;
             if (opcode == Opcodes.LLOAD || opcode == Opcodes.DLOAD
-                    || opcode == Opcodes.LSTORE || opcode == Opcodes.DSTORE)
-            {
+                    || opcode == Opcodes.LSTORE || opcode == Opcodes.DSTORE) {
                 n = var + 2;
             } else {
                 n = var + 1;
@@ -793,6 +853,7 @@
 
     @Override
     public void visitTypeInsn(final int opcode, final String type) {
+        lastCodeOffset = code.length;
         Item i = cw.newClassItem(type);
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
@@ -813,12 +874,9 @@
     }
 
     @Override
-    public void visitFieldInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitFieldInsn(final int opcode, final String owner,
+            final String name, final String desc) {
+        lastCodeOffset = code.length;
         Item i = cw.newFieldItem(owner, name, desc);
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
@@ -829,19 +887,19 @@
                 // computes the stack size variation
                 char c = desc.charAt(0);
                 switch (opcode) {
-                    case Opcodes.GETSTATIC:
-                        size = stackSize + (c == 'D' || c == 'J' ? 2 : 1);
-                        break;
-                    case Opcodes.PUTSTATIC:
-                        size = stackSize + (c == 'D' || c == 'J' ? -2 : -1);
-                        break;
-                    case Opcodes.GETFIELD:
-                        size = stackSize + (c == 'D' || c == 'J' ? 1 : 0);
-                        break;
-                    // case Constants.PUTFIELD:
-                    default:
-                        size = stackSize + (c == 'D' || c == 'J' ? -3 : -2);
-                        break;
+                case Opcodes.GETSTATIC:
+                    size = stackSize + (c == 'D' || c == 'J' ? 2 : 1);
+                    break;
+                case Opcodes.PUTSTATIC:
+                    size = stackSize + (c == 'D' || c == 'J' ? -2 : -1);
+                    break;
+                case Opcodes.GETFIELD:
+                    size = stackSize + (c == 'D' || c == 'J' ? 1 : 0);
+                    break;
+                // case Constants.PUTFIELD:
+                default:
+                    size = stackSize + (c == 'D' || c == 'J' ? -3 : -2);
+                    break;
                 }
                 // updates current and max stack sizes
                 if (size > maxStackSize) {
@@ -855,12 +913,9 @@
     }
 
     @Override
-    public void visitMethodInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitMethodInsn(final int opcode, final String owner,
+            final String name, final String desc) {
+        lastCodeOffset = code.length;
         boolean itf = opcode == Opcodes.INVOKEINTERFACE;
         Item i = cw.newMethodItem(owner, name, desc, itf);
         int argSize = i.intVal;
@@ -911,12 +966,9 @@
     }
 
     @Override
-    public void visitInvokeDynamicInsn(
-        final String name,
-        final String desc,
-        final Handle bsm,
-        final Object... bsmArgs)
-    {
+    public void visitInvokeDynamicInsn(final String name, final String desc,
+            final Handle bsm, final Object... bsmArgs) {
+        lastCodeOffset = code.length;
         Item i = cw.newInvokeDynamicItem(name, desc, bsm, bsmArgs);
         int argSize = i.intVal;
         // Label currentBlock = this.currentBlock;
@@ -956,6 +1008,7 @@
 
     @Override
     public void visitJumpInsn(final int opcode, final Label label) {
+        lastCodeOffset = code.length;
         Label nextInsn = null;
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
@@ -996,8 +1049,7 @@
         }
         // adds the instruction to the bytecode of the method
         if ((label.status & Label.RESOLVED) != 0
-                && label.position - code.length < Short.MIN_VALUE)
-        {
+                && label.position - code.length < Short.MIN_VALUE) {
             /*
              * case of a backward jump with an offset < -32768. In this case we
              * automatically replace GOTO with GOTO_W, JSR with JSR_W and IFxxx
@@ -1015,8 +1067,7 @@
                 if (nextInsn != null) {
                     nextInsn.status |= Label.TARGET;
                 }
-                code.putByte(opcode <= 166
-                        ? ((opcode + 1) ^ 1) - 1
+                code.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
                         : opcode ^ 1);
                 code.putShort(8); // jump offset
                 code.putByte(200); // GOTO_W
@@ -1103,6 +1154,7 @@
 
     @Override
     public void visitLdcInsn(final Object cst) {
+        lastCodeOffset = code.length;
         Item i = cw.newConstItem(cst);
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
@@ -1111,8 +1163,7 @@
             } else {
                 int size;
                 // computes the stack size variation
-                if (i.type == ClassWriter.LONG || i.type == ClassWriter.DOUBLE)
-                {
+                if (i.type == ClassWriter.LONG || i.type == ClassWriter.DOUBLE) {
                     size = stackSize + 2;
                 } else {
                     size = stackSize + 1;
@@ -1137,6 +1188,7 @@
 
     @Override
     public void visitIincInsn(final int var, final int increment) {
+        lastCodeOffset = code.length;
         if (currentBlock != null) {
             if (compute == FRAMES) {
                 currentBlock.frame.execute(Opcodes.IINC, var, null, null);
@@ -1151,8 +1203,7 @@
         }
         // adds the instruction to the bytecode of the method
         if ((var > 255) || (increment > 127) || (increment < -128)) {
-            code.putByte(196 /* WIDE */)
-                    .put12(Opcodes.IINC, var)
+            code.putByte(196 /* WIDE */).put12(Opcodes.IINC, var)
                     .putShort(increment);
         } else {
             code.putByte(Opcodes.IINC).put11(var, increment);
@@ -1160,12 +1211,9 @@
     }
 
     @Override
-    public void visitTableSwitchInsn(
-        final int min,
-        final int max,
-        final Label dflt,
-        final Label... labels)
-    {
+    public void visitTableSwitchInsn(final int min, final int max,
+            final Label dflt, final Label... labels) {
+        lastCodeOffset = code.length;
         // adds the instruction to the bytecode of the method
         int source = code.length;
         code.putByte(Opcodes.TABLESWITCH);
@@ -1180,11 +1228,9 @@
     }
 
     @Override
-    public void visitLookupSwitchInsn(
-        final Label dflt,
-        final int[] keys,
-        final Label[] labels)
-    {
+    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+            final Label[] labels) {
+        lastCodeOffset = code.length;
         // adds the instruction to the bytecode of the method
         int source = code.length;
         code.putByte(Opcodes.LOOKUPSWITCH);
@@ -1227,6 +1273,7 @@
 
     @Override
     public void visitMultiANewArrayInsn(final String desc, final int dims) {
+        lastCodeOffset = code.length;
         Item i = cw.newClassItem(desc);
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
@@ -1243,12 +1290,32 @@
     }
 
     @Override
-    public void visitTryCatchBlock(
-        final Label start,
-        final Label end,
-        final Label handler,
-        final String type)
-    {
+    public AnnotationVisitor visitInsnAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        if (!ClassReader.ANNOTATIONS) {
+            return null;
+        }
+        ByteVector bv = new ByteVector();
+        // write target_type and target_info
+        typeRef = (typeRef & 0xFF0000FF) | (lastCodeOffset << 8);
+        AnnotationWriter.putTarget(typeRef, typePath, bv);
+        // write type, and reserve space for values count
+        bv.putShort(cw.newUTF8(desc)).putShort(0);
+        AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+                bv.length - 2);
+        if (visible) {
+            aw.next = ctanns;
+            ctanns = aw;
+        } else {
+            aw.next = ictanns;
+            ictanns = aw;
+        }
+        return aw;
+    }
+
+    @Override
+    public void visitTryCatchBlock(final Label start, final Label end,
+            final Label handler, final String type) {
         ++handlerCount;
         Handler h = new Handler();
         h.start = start;
@@ -1265,14 +1332,32 @@
     }
 
     @Override
-    public void visitLocalVariable(
-        final String name,
-        final String desc,
-        final String signature,
-        final Label start,
-        final Label end,
-        final int index)
-    {
+    public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        if (!ClassReader.ANNOTATIONS) {
+            return null;
+        }
+        ByteVector bv = new ByteVector();
+        // write target_type and target_info
+        AnnotationWriter.putTarget(typeRef, typePath, bv);
+        // write type, and reserve space for values count
+        bv.putShort(cw.newUTF8(desc)).putShort(0);
+        AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+                bv.length - 2);
+        if (visible) {
+            aw.next = ctanns;
+            ctanns = aw;
+        } else {
+            aw.next = ictanns;
+            ictanns = aw;
+        }
+        return aw;
+    }
+
+    @Override
+    public void visitLocalVariable(final String name, final String desc,
+            final String signature, final Label start, final Label end,
+            final int index) {
         if (signature != null) {
             if (localVarType == null) {
                 localVarType = new ByteVector();
@@ -1280,8 +1365,7 @@
             ++localVarTypeCount;
             localVarType.putShort(start.position)
                     .putShort(end.position - start.position)
-                    .putShort(cw.newUTF8(name))
-                    .putShort(cw.newUTF8(signature))
+                    .putShort(cw.newUTF8(name)).putShort(cw.newUTF8(signature))
                     .putShort(index);
         }
         if (localVar == null) {
@@ -1290,8 +1374,7 @@
         ++localVarCount;
         localVar.putShort(start.position)
                 .putShort(end.position - start.position)
-                .putShort(cw.newUTF8(name))
-                .putShort(cw.newUTF8(desc))
+                .putShort(cw.newUTF8(name)).putShort(cw.newUTF8(desc))
                 .putShort(index);
         if (compute != NOTHING) {
             // updates max locals
@@ -1304,6 +1387,41 @@
     }
 
     @Override
+    public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
+            TypePath typePath, Label[] start, Label[] end, int[] index,
+            String desc, boolean visible) {
+        if (!ClassReader.ANNOTATIONS) {
+            return null;
+        }
+        ByteVector bv = new ByteVector();
+        // write target_type and target_info
+        bv.putByte(typeRef >>> 24).putShort(start.length);
+        for (int i = 0; i < start.length; ++i) {
+            bv.putShort(start[i].position)
+                    .putShort(end[i].position - start[i].position)
+                    .putShort(index[i]);
+        }
+        if (typePath == null) {
+            bv.putByte(0);
+        } else {
+            int length = typePath.b[typePath.offset] * 2 + 1;
+            bv.putByteArray(typePath.b, typePath.offset, length);
+        }
+        // write type, and reserve space for values count
+        bv.putShort(cw.newUTF8(desc)).putShort(0);
+        AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+                bv.length - 2);
+        if (visible) {
+            aw.next = ctanns;
+            ctanns = aw;
+        } else {
+            aw.next = ictanns;
+            ictanns = aw;
+        }
+        return aw;
+    }
+
+    @Override
     public void visitLineNumber(final int line, final Label start) {
         if (lineNumber == null) {
             lineNumber = new ByteVector();
@@ -1323,8 +1441,7 @@
                 Label h = handler.handler.getFirst();
                 Label e = handler.end.getFirst();
                 // computes the kind of the edges to 'h'
-                String t = handler.desc == null
-                        ? "java/lang/Throwable"
+                String t = handler.desc == null ? "java/lang/Throwable"
                         : handler.desc;
                 int kind = Frame.OBJECT | cw.addType(t);
                 // h is an exception handler
@@ -1415,7 +1532,8 @@
                         frame[frameIndex++] = Frame.OBJECT
                                 | cw.addType("java/lang/Throwable");
                         endFrame();
-                        // removes the start-end range from the exception handlers
+                        // removes the start-end range from the exception
+                        // handlers
                         firstHandler = Handler.remove(firstHandler, l, k);
                     }
                 }
@@ -1564,8 +1682,10 @@
     /**
      * Adds a successor to the {@link #currentBlock currentBlock} block.
      *
-     * @param info information about the control flow edge to be added.
-     * @param successor the successor block to be added to the current block.
+     * @param info
+     *            information about the control flow edge to be added.
+     * @param successor
+     *            the successor block to be added to the current block.
      */
     private void addSuccessor(final int info, final Label successor) {
         // creates and initializes an Edge object...
@@ -1602,7 +1722,8 @@
     /**
      * Visits a frame that has been computed from scratch.
      *
-     * @param f the frame that must be visited.
+     * @param f
+     *            the frame that must be visited.
      */
     private void visitFrame(final Frame f) {
         int i, t;
@@ -1656,13 +1777,14 @@
     /**
      * Starts the visit of a stack map frame.
      *
-     * @param offset the offset of the instruction to which the frame
-     *        corresponds.
-     * @param nLocal the number of local variables in the frame.
-     * @param nStack the number of stack elements in the frame.
+     * @param offset
+     *            the offset of the instruction to which the frame corresponds.
+     * @param nLocal
+     *            the number of local variables in the frame.
+     * @param nStack
+     *            the number of stack elements in the frame.
      */
-    private void startFrame(final int offset, final int nLocal, final int nStack)
-    {
+    private void startFrame(final int offset, final int nLocal, final int nStack) {
         int n = 3 + nLocal + nStack;
         if (frame == null || frame.length < n) {
             frame = new int[n];
@@ -1715,24 +1837,23 @@
         if (cstackSize == 0) {
             k = clocalsSize - localsSize;
             switch (k) {
-                case -3:
-                case -2:
-                case -1:
-                    type = CHOP_FRAME;
-                    localsSize = clocalsSize;
-                    break;
-                case 0:
-                    type = delta < 64 ? SAME_FRAME : SAME_FRAME_EXTENDED;
-                    break;
-                case 1:
-                case 2:
-                case 3:
-                    type = APPEND_FRAME;
-                    break;
+            case -3:
+            case -2:
+            case -1:
+                type = CHOP_FRAME;
+                localsSize = clocalsSize;
+                break;
+            case 0:
+                type = delta < 64 ? SAME_FRAME : SAME_FRAME_EXTENDED;
+                break;
+            case 1:
+            case 2:
+            case 3:
+                type = APPEND_FRAME;
+                break;
             }
         } else if (clocalsSize == localsSize && cstackSize == 1) {
-            type = delta < 63
-                    ? SAME_LOCALS_1_STACK_ITEM_FRAME
+            type = delta < 63 ? SAME_LOCALS_1_STACK_ITEM_FRAME
                     : SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED;
         }
         if (type != FULL_FRAME) {
@@ -1747,36 +1868,34 @@
             }
         }
         switch (type) {
-            case SAME_FRAME:
-                stackMap.putByte(delta);
-                break;
-            case SAME_LOCALS_1_STACK_ITEM_FRAME:
-                stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta);
-                writeFrameTypes(3 + clocalsSize, 4 + clocalsSize);
-                break;
-            case SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED:
-                stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
-                        .putShort(delta);
-                writeFrameTypes(3 + clocalsSize, 4 + clocalsSize);
-                break;
-            case SAME_FRAME_EXTENDED:
-                stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta);
-                break;
-            case CHOP_FRAME:
-                stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta);
-                break;
-            case APPEND_FRAME:
-                stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta);
-                writeFrameTypes(3 + localsSize, 3 + clocalsSize);
-                break;
-            // case FULL_FRAME:
-            default:
-                stackMap.putByte(FULL_FRAME)
-                        .putShort(delta)
-                        .putShort(clocalsSize);
-                writeFrameTypes(3, 3 + clocalsSize);
-                stackMap.putShort(cstackSize);
-                writeFrameTypes(3 + clocalsSize, 3 + clocalsSize + cstackSize);
+        case SAME_FRAME:
+            stackMap.putByte(delta);
+            break;
+        case SAME_LOCALS_1_STACK_ITEM_FRAME:
+            stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta);
+            writeFrameTypes(3 + clocalsSize, 4 + clocalsSize);
+            break;
+        case SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED:
+            stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED).putShort(
+                    delta);
+            writeFrameTypes(3 + clocalsSize, 4 + clocalsSize);
+            break;
+        case SAME_FRAME_EXTENDED:
+            stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta);
+            break;
+        case CHOP_FRAME:
+            stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta);
+            break;
+        case APPEND_FRAME:
+            stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta);
+            writeFrameTypes(3 + localsSize, 3 + clocalsSize);
+            break;
+        // case FULL_FRAME:
+        default:
+            stackMap.putByte(FULL_FRAME).putShort(delta).putShort(clocalsSize);
+            writeFrameTypes(3, 3 + clocalsSize);
+            stackMap.putShort(cstackSize);
+            writeFrameTypes(3 + clocalsSize, 3 + clocalsSize + cstackSize);
         }
     }
 
@@ -1786,8 +1905,10 @@
      * in {@link Label} to the format used in StackMapTable attributes. In
      * particular, it converts type table indexes to constant pool indexes.
      *
-     * @param start index of the first type in {@link #frame} to write.
-     * @param end index of last type in {@link #frame} to write (exclusive).
+     * @param start
+     *            index of the first type in {@link #frame} to write.
+     * @param end
+     *            index of last type in {@link #frame} to write (exclusive).
      */
     private void writeFrameTypes(final int start, final int end) {
         for (int i = start; i < end; ++i) {
@@ -1796,15 +1917,15 @@
             if (d == 0) {
                 int v = t & Frame.BASE_VALUE;
                 switch (t & Frame.BASE_KIND) {
-                    case Frame.OBJECT:
-                        stackMap.putByte(7)
-                                .putShort(cw.newClass(cw.typeTable[v].strVal1));
-                        break;
-                    case Frame.UNINITIALIZED:
-                        stackMap.putByte(8).putShort(cw.typeTable[v].intVal);
-                        break;
-                    default:
-                        stackMap.putByte(v);
+                case Frame.OBJECT:
+                    stackMap.putByte(7).putShort(
+                            cw.newClass(cw.typeTable[v].strVal1));
+                    break;
+                case Frame.UNINITIALIZED:
+                    stackMap.putByte(8).putShort(cw.typeTable[v].intVal);
+                    break;
+                default:
+                    stackMap.putByte(v);
                 }
             } else {
                 StringBuffer buf = new StringBuffer();
@@ -1818,29 +1939,29 @@
                     buf.append(';');
                 } else {
                     switch (t & 0xF) {
-                        case 1:
-                            buf.append('I');
-                            break;
-                        case 2:
-                            buf.append('F');
-                            break;
-                        case 3:
-                            buf.append('D');
-                            break;
-                        case 9:
-                            buf.append('Z');
-                            break;
-                        case 10:
-                            buf.append('B');
-                            break;
-                        case 11:
-                            buf.append('C');
-                            break;
-                        case 12:
-                            buf.append('S');
-                            break;
-                        default:
-                            buf.append('J');
+                    case 1:
+                        buf.append('I');
+                        break;
+                    case 2:
+                        buf.append('F');
+                        break;
+                    case 3:
+                        buf.append('D');
+                        break;
+                    case 9:
+                        buf.append('Z');
+                        break;
+                    case 10:
+                        buf.append('B');
+                        break;
+                    case 11:
+                        buf.append('C');
+                        break;
+                    case 12:
+                        buf.append('S');
+                        break;
+                    default:
+                        buf.append('J');
                     }
                 }
                 stackMap.putByte(7).putShort(cw.newClass(buf.toString()));
@@ -1903,11 +2024,16 @@
                 cw.newUTF8(zip ? "StackMapTable" : "StackMap");
                 size += 8 + stackMap.length;
             }
+            if (ClassReader.ANNOTATIONS && ctanns != null) {
+                cw.newUTF8("RuntimeVisibleTypeAnnotations");
+                size += 8 + ctanns.getSize();
+            }
+            if (ClassReader.ANNOTATIONS && ictanns != null) {
+                cw.newUTF8("RuntimeInvisibleTypeAnnotations");
+                size += 8 + ictanns.getSize();
+            }
             if (cattrs != null) {
-                size += cattrs.getSize(cw,
-                        code.data,
-                        code.length,
-                        maxStack,
+                size += cattrs.getSize(cw, code.data, code.length, maxStack,
                         maxLocals);
             }
         }
@@ -1915,11 +2041,12 @@
             cw.newUTF8("Exceptions");
             size += 8 + 2 * exceptionCount;
         }
-        if ((access & Opcodes.ACC_SYNTHETIC) != 0
-                && ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0))
-        {
-            cw.newUTF8("Synthetic");
-            size += 6;
+        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+            if ((cw.version & 0xFFFF) < Opcodes.V1_5
+                    || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+                cw.newUTF8("Synthetic");
+                size += 6;
+            }
         }
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             cw.newUTF8("Deprecated");
@@ -1930,6 +2057,10 @@
             cw.newUTF8(signature);
             size += 8;
         }
+        if (methodParameters != null) {
+            cw.newUTF8("MethodParameters");
+            size += 7 + methodParameters.length;
+        }
         if (ClassReader.ANNOTATIONS && annd != null) {
             cw.newUTF8("AnnotationDefault");
             size += 6 + annd.length;
@@ -1942,6 +2073,14 @@
             cw.newUTF8("RuntimeInvisibleAnnotations");
             size += 8 + ianns.getSize();
         }
+        if (ClassReader.ANNOTATIONS && tanns != null) {
+            cw.newUTF8("RuntimeVisibleTypeAnnotations");
+            size += 8 + tanns.getSize();
+        }
+        if (ClassReader.ANNOTATIONS && itanns != null) {
+            cw.newUTF8("RuntimeInvisibleTypeAnnotations");
+            size += 8 + itanns.getSize();
+        }
         if (ClassReader.ANNOTATIONS && panns != null) {
             cw.newUTF8("RuntimeVisibleParameterAnnotations");
             size += 7 + 2 * (panns.length - synthetics);
@@ -1965,13 +2104,14 @@
     /**
      * Puts the bytecode of this method in the given byte vector.
      *
-     * @param out the byte vector into which the bytecode of this method must be
-     *        copied.
+     * @param out
+     *            the byte vector into which the bytecode of this method must be
+     *            copied.
      */
     final void put(final ByteVector out) {
-        int mask = Opcodes.ACC_DEPRECATED
-                | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
-                | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / (ClassWriter.ACC_SYNTHETIC_ATTRIBUTE / Opcodes.ACC_SYNTHETIC));
+        final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC;
+        int mask = Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
+                | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR);
         out.putShort(access & ~mask).putShort(name).putShort(desc);
         if (classReaderOffset != 0) {
             out.putByteArray(cw.cr.b, classReaderOffset, classReaderLength);
@@ -1984,10 +2124,11 @@
         if (exceptionCount > 0) {
             ++attributeCount;
         }
-        if ((access & Opcodes.ACC_SYNTHETIC) != 0
-                && ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0))
-        {
-            ++attributeCount;
+        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+            if ((cw.version & 0xFFFF) < Opcodes.V1_5
+                    || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+                ++attributeCount;
+            }
         }
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             ++attributeCount;
@@ -1995,6 +2136,9 @@
         if (ClassReader.SIGNATURES && signature != null) {
             ++attributeCount;
         }
+        if (methodParameters != null) {
+            ++attributeCount;
+        }
         if (ClassReader.ANNOTATIONS && annd != null) {
             ++attributeCount;
         }
@@ -2004,6 +2148,12 @@
         if (ClassReader.ANNOTATIONS && ianns != null) {
             ++attributeCount;
         }
+        if (ClassReader.ANNOTATIONS && tanns != null) {
+            ++attributeCount;
+        }
+        if (ClassReader.ANNOTATIONS && itanns != null) {
+            ++attributeCount;
+        }
         if (ClassReader.ANNOTATIONS && panns != null) {
             ++attributeCount;
         }
@@ -2028,11 +2178,14 @@
             if (stackMap != null) {
                 size += 8 + stackMap.length;
             }
+            if (ClassReader.ANNOTATIONS && ctanns != null) {
+                size += 8 + ctanns.getSize();
+            }
+            if (ClassReader.ANNOTATIONS && ictanns != null) {
+                size += 8 + ictanns.getSize();
+            }
             if (cattrs != null) {
-                size += cattrs.getSize(cw,
-                        code.data,
-                        code.length,
-                        maxStack,
+                size += cattrs.getSize(cw, code.data, code.length, maxStack,
                         maxLocals);
             }
             out.putShort(cw.newUTF8("Code")).putInt(size);
@@ -2042,10 +2195,8 @@
             if (handlerCount > 0) {
                 Handler h = firstHandler;
                 while (h != null) {
-                    out.putShort(h.start.position)
-                            .putShort(h.end.position)
-                            .putShort(h.handler.position)
-                            .putShort(h.type);
+                    out.putShort(h.start.position).putShort(h.end.position)
+                            .putShort(h.handler.position).putShort(h.type);
                     h = h.next;
                 }
             }
@@ -2062,6 +2213,12 @@
             if (stackMap != null) {
                 ++attributeCount;
             }
+            if (ClassReader.ANNOTATIONS && ctanns != null) {
+                ++attributeCount;
+            }
+            if (ClassReader.ANNOTATIONS && ictanns != null) {
+                ++attributeCount;
+            }
             if (cattrs != null) {
                 attributeCount += cattrs.getCount();
             }
@@ -2087,31 +2244,45 @@
                 out.putInt(stackMap.length + 2).putShort(frameCount);
                 out.putByteArray(stackMap.data, 0, stackMap.length);
             }
+            if (ClassReader.ANNOTATIONS && ctanns != null) {
+                out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
+                ctanns.put(out);
+            }
+            if (ClassReader.ANNOTATIONS && ictanns != null) {
+                out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
+                ictanns.put(out);
+            }
             if (cattrs != null) {
                 cattrs.put(cw, code.data, code.length, maxLocals, maxStack, out);
             }
         }
         if (exceptionCount > 0) {
-            out.putShort(cw.newUTF8("Exceptions"))
-                    .putInt(2 * exceptionCount + 2);
+            out.putShort(cw.newUTF8("Exceptions")).putInt(
+                    2 * exceptionCount + 2);
             out.putShort(exceptionCount);
             for (int i = 0; i < exceptionCount; ++i) {
                 out.putShort(exceptions[i]);
             }
         }
-        if ((access & Opcodes.ACC_SYNTHETIC) != 0
-                && ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0))
-        {
-            out.putShort(cw.newUTF8("Synthetic")).putInt(0);
+        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+            if ((cw.version & 0xFFFF) < Opcodes.V1_5
+                    || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+                out.putShort(cw.newUTF8("Synthetic")).putInt(0);
+            }
         }
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             out.putShort(cw.newUTF8("Deprecated")).putInt(0);
         }
         if (ClassReader.SIGNATURES && signature != null) {
-            out.putShort(cw.newUTF8("Signature"))
-                    .putInt(2)
+            out.putShort(cw.newUTF8("Signature")).putInt(2)
                     .putShort(cw.newUTF8(signature));
         }
+        if (methodParameters != null) {
+            out.putShort(cw.newUTF8("MethodParameters"));
+            out.putInt(methodParameters.length + 1).putByte(
+                    methodParametersCount);
+            out.putByteArray(methodParameters.data, 0, methodParameters.length);
+        }
         if (ClassReader.ANNOTATIONS && annd != null) {
             out.putShort(cw.newUTF8("AnnotationDefault"));
             out.putInt(annd.length);
@@ -2125,6 +2296,14 @@
             out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
             ianns.put(out);
         }
+        if (ClassReader.ANNOTATIONS && tanns != null) {
+            out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
+            tanns.put(out);
+        }
+        if (ClassReader.ANNOTATIONS && itanns != null) {
+            out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
+            itanns.put(out);
+        }
         if (ClassReader.ANNOTATIONS && panns != null) {
             out.putShort(cw.newUTF8("RuntimeVisibleParameterAnnotations"));
             AnnotationWriter.put(panns, synthetics, out);
@@ -2152,10 +2331,12 @@
      * 32768, in which case IFEQ 32766 must be replaced with IFNEQ 8 GOTO_W
      * 32765. This, in turn, may require to increase the size of another jump
      * instruction, and so on... All these operations are handled automatically
-     * by this method. <p> <i>This method must be called after all the method
-     * that is being built has been visited</i>. In particular, the
-     * {@link Label Label} objects used to construct the method are no longer
-     * valid after this method has been called.
+     * by this method.
+     * <p>
+     * <i>This method must be called after all the method that is being built
+     * has been visited</i>. In particular, the {@link Label Label} objects used
+     * to construct the method are no longer valid after this method has been
+     * called.
      */
     private void resizeInstructions() {
         byte[] b = code.data; // bytecode of the method
@@ -2205,123 +2386,117 @@
                 int insert = 0; // bytes to be added after this instruction
 
                 switch (ClassWriter.TYPE[opcode]) {
-                    case ClassWriter.NOARG_INSN:
-                    case ClassWriter.IMPLVAR_INSN:
-                        u += 1;
-                        break;
-                    case ClassWriter.LABEL_INSN:
-                        if (opcode > 201) {
-                            // converts temporary opcodes 202 to 217, 218 and
-                            // 219 to IFEQ ... JSR (inclusive), IFNULL and
-                            // IFNONNULL
-                            opcode = opcode < 218 ? opcode - 49 : opcode - 20;
-                            label = u + readUnsignedShort(b, u + 1);
-                        } else {
-                            label = u + readShort(b, u + 1);
-                        }
-                        newOffset = getNewOffset(allIndexes, allSizes, u, label);
-                        if (newOffset < Short.MIN_VALUE
-                                || newOffset > Short.MAX_VALUE)
-                        {
-                            if (!resize[u]) {
-                                if (opcode == Opcodes.GOTO
-                                        || opcode == Opcodes.JSR)
-                                {
-                                    // two additional bytes will be required to
-                                    // replace this GOTO or JSR instruction with
-                                    // a GOTO_W or a JSR_W
-                                    insert = 2;
-                                } else {
-                                    // five additional bytes will be required to
-                                    // replace this IFxxx <l> instruction with
-                                    // IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx
-                                    // is the "opposite" opcode of IFxxx (i.e.,
-                                    // IFNE for IFEQ) and where <l'> designates
-                                    // the instruction just after the GOTO_W.
-                                    insert = 5;
-                                }
-                                resize[u] = true;
+                case ClassWriter.NOARG_INSN:
+                case ClassWriter.IMPLVAR_INSN:
+                    u += 1;
+                    break;
+                case ClassWriter.LABEL_INSN:
+                    if (opcode > 201) {
+                        // converts temporary opcodes 202 to 217, 218 and
+                        // 219 to IFEQ ... JSR (inclusive), IFNULL and
+                        // IFNONNULL
+                        opcode = opcode < 218 ? opcode - 49 : opcode - 20;
+                        label = u + readUnsignedShort(b, u + 1);
+                    } else {
+                        label = u + readShort(b, u + 1);
+                    }
+                    newOffset = getNewOffset(allIndexes, allSizes, u, label);
+                    if (newOffset < Short.MIN_VALUE
+                            || newOffset > Short.MAX_VALUE) {
+                        if (!resize[u]) {
+                            if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
+                                // two additional bytes will be required to
+                                // replace this GOTO or JSR instruction with
+                                // a GOTO_W or a JSR_W
+                                insert = 2;
+                            } else {
+                                // five additional bytes will be required to
+                                // replace this IFxxx <l> instruction with
+                                // IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx
+                                // is the "opposite" opcode of IFxxx (i.e.,
+                                // IFNE for IFEQ) and where <l'> designates
+                                // the instruction just after the GOTO_W.
+                                insert = 5;
                             }
-                        }
-                        u += 3;
-                        break;
-                    case ClassWriter.LABELW_INSN:
-                        u += 5;
-                        break;
-                    case ClassWriter.TABL_INSN:
-                        if (state == 1) {
-                            // true number of bytes to be added (or removed)
-                            // from this instruction = (future number of padding
-                            // bytes - current number of padding byte) -
-                            // previously over estimated variation =
-                            // = ((3 - newOffset%4) - (3 - u%4)) - u%4
-                            // = (-newOffset%4 + u%4) - u%4
-                            // = -(newOffset & 3)
-                            newOffset = getNewOffset(allIndexes, allSizes, 0, u);
-                            insert = -(newOffset & 3);
-                        } else if (!resize[u]) {
-                            // over estimation of the number of bytes to be
-                            // added to this instruction = 3 - current number
-                            // of padding bytes = 3 - (3 - u%4) = u%4 = u & 3
-                            insert = u & 3;
                             resize[u] = true;
                         }
-                        // skips instruction
-                        u = u + 4 - (u & 3);
-                        u += 4 * (readInt(b, u + 8) - readInt(b, u + 4) + 1) + 12;
-                        break;
-                    case ClassWriter.LOOK_INSN:
-                        if (state == 1) {
-                            // like TABL_INSN
-                            newOffset = getNewOffset(allIndexes, allSizes, 0, u);
-                            insert = -(newOffset & 3);
-                        } else if (!resize[u]) {
-                            // like TABL_INSN
-                            insert = u & 3;
-                            resize[u] = true;
-                        }
-                        // skips instruction
-                        u = u + 4 - (u & 3);
-                        u += 8 * readInt(b, u + 4) + 8;
-                        break;
-                    case ClassWriter.WIDE_INSN:
-                        opcode = b[u + 1] & 0xFF;
-                        if (opcode == Opcodes.IINC) {
-                            u += 6;
-                        } else {
-                            u += 4;
-                        }
-                        break;
-                    case ClassWriter.VAR_INSN:
-                    case ClassWriter.SBYTE_INSN:
-                    case ClassWriter.LDC_INSN:
-                        u += 2;
-                        break;
-                    case ClassWriter.SHORT_INSN:
-                    case ClassWriter.LDCW_INSN:
-                    case ClassWriter.FIELDORMETH_INSN:
-                    case ClassWriter.TYPE_INSN:
-                    case ClassWriter.IINC_INSN:
-                        u += 3;
-                        break;
-                    case ClassWriter.ITFMETH_INSN:
-                    case ClassWriter.INDYMETH_INSN:
-                        u += 5;
-                        break;
-                    // case ClassWriter.MANA_INSN:
-                    default:
+                    }
+                    u += 3;
+                    break;
+                case ClassWriter.LABELW_INSN:
+                    u += 5;
+                    break;
+                case ClassWriter.TABL_INSN:
+                    if (state == 1) {
+                        // true number of bytes to be added (or removed)
+                        // from this instruction = (future number of padding
+                        // bytes - current number of padding byte) -
+                        // previously over estimated variation =
+                        // = ((3 - newOffset%4) - (3 - u%4)) - u%4
+                        // = (-newOffset%4 + u%4) - u%4
+                        // = -(newOffset & 3)
+                        newOffset = getNewOffset(allIndexes, allSizes, 0, u);
+                        insert = -(newOffset & 3);
+                    } else if (!resize[u]) {
+                        // over estimation of the number of bytes to be
+                        // added to this instruction = 3 - current number
+                        // of padding bytes = 3 - (3 - u%4) = u%4 = u & 3
+                        insert = u & 3;
+                        resize[u] = true;
+                    }
+                    // skips instruction
+                    u = u + 4 - (u & 3);
+                    u += 4 * (readInt(b, u + 8) - readInt(b, u + 4) + 1) + 12;
+                    break;
+                case ClassWriter.LOOK_INSN:
+                    if (state == 1) {
+                        // like TABL_INSN
+                        newOffset = getNewOffset(allIndexes, allSizes, 0, u);
+                        insert = -(newOffset & 3);
+                    } else if (!resize[u]) {
+                        // like TABL_INSN
+                        insert = u & 3;
+                        resize[u] = true;
+                    }
+                    // skips instruction
+                    u = u + 4 - (u & 3);
+                    u += 8 * readInt(b, u + 4) + 8;
+                    break;
+                case ClassWriter.WIDE_INSN:
+                    opcode = b[u + 1] & 0xFF;
+                    if (opcode == Opcodes.IINC) {
+                        u += 6;
+                    } else {
                         u += 4;
-                        break;
+                    }
+                    break;
+                case ClassWriter.VAR_INSN:
+                case ClassWriter.SBYTE_INSN:
+                case ClassWriter.LDC_INSN:
+                    u += 2;
+                    break;
+                case ClassWriter.SHORT_INSN:
+                case ClassWriter.LDCW_INSN:
+                case ClassWriter.FIELDORMETH_INSN:
+                case ClassWriter.TYPE_INSN:
+                case ClassWriter.IINC_INSN:
+                    u += 3;
+                    break;
+                case ClassWriter.ITFMETH_INSN:
+                case ClassWriter.INDYMETH_INSN:
+                    u += 5;
+                    break;
+                // case ClassWriter.MANA_INSN:
+                default:
+                    u += 4;
+                    break;
                 }
                 if (insert != 0) {
                     // adds a new (u, insert) entry in the allIndexes and
                     // allSizes arrays
                     int[] newIndexes = new int[allIndexes.length + 1];
                     int[] newSizes = new int[allSizes.length + 1];
-                    System.arraycopy(allIndexes,
-                            0,
-                            newIndexes,
-                            0,
+                    System.arraycopy(allIndexes, 0, newIndexes, 0,
                             allIndexes.length);
                     System.arraycopy(allSizes, 0, newSizes, 0, allSizes.length);
                     newIndexes[allIndexes.length] = u;
@@ -2348,136 +2523,135 @@
         while (u < code.length) {
             int opcode = b[u] & 0xFF;
             switch (ClassWriter.TYPE[opcode]) {
-                case ClassWriter.NOARG_INSN:
-                case ClassWriter.IMPLVAR_INSN:
-                    newCode.putByte(opcode);
-                    u += 1;
-                    break;
-                case ClassWriter.LABEL_INSN:
-                    if (opcode > 201) {
-                        // changes temporary opcodes 202 to 217 (inclusive), 218
-                        // and 219 to IFEQ ... JSR (inclusive), IFNULL and
-                        // IFNONNULL
-                        opcode = opcode < 218 ? opcode - 49 : opcode - 20;
-                        label = u + readUnsignedShort(b, u + 1);
+            case ClassWriter.NOARG_INSN:
+            case ClassWriter.IMPLVAR_INSN:
+                newCode.putByte(opcode);
+                u += 1;
+                break;
+            case ClassWriter.LABEL_INSN:
+                if (opcode > 201) {
+                    // changes temporary opcodes 202 to 217 (inclusive), 218
+                    // and 219 to IFEQ ... JSR (inclusive), IFNULL and
+                    // IFNONNULL
+                    opcode = opcode < 218 ? opcode - 49 : opcode - 20;
+                    label = u + readUnsignedShort(b, u + 1);
+                } else {
+                    label = u + readShort(b, u + 1);
+                }
+                newOffset = getNewOffset(allIndexes, allSizes, u, label);
+                if (resize[u]) {
+                    // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
+                    // <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is
+                    // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
+                    // and where <l'> designates the instruction just after
+                    // the GOTO_W.
+                    if (opcode == Opcodes.GOTO) {
+                        newCode.putByte(200); // GOTO_W
+                    } else if (opcode == Opcodes.JSR) {
+                        newCode.putByte(201); // JSR_W
                     } else {
-                        label = u + readShort(b, u + 1);
+                        newCode.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
+                                : opcode ^ 1);
+                        newCode.putShort(8); // jump offset
+                        newCode.putByte(200); // GOTO_W
+                        // newOffset now computed from start of GOTO_W
+                        newOffset -= 3;
                     }
-                    newOffset = getNewOffset(allIndexes, allSizes, u, label);
-                    if (resize[u]) {
-                        // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
-                        // <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is
-                        // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
-                        // and where <l'> designates the instruction just after
-                        // the GOTO_W.
-                        if (opcode == Opcodes.GOTO) {
-                            newCode.putByte(200); // GOTO_W
-                        } else if (opcode == Opcodes.JSR) {
-                            newCode.putByte(201); // JSR_W
-                        } else {
-                            newCode.putByte(opcode <= 166
-                                    ? ((opcode + 1) ^ 1) - 1
-                                    : opcode ^ 1);
-                            newCode.putShort(8); // jump offset
-                            newCode.putByte(200); // GOTO_W
-                            // newOffset now computed from start of GOTO_W
-                            newOffset -= 3;
-                        }
-                        newCode.putInt(newOffset);
-                    } else {
-                        newCode.putByte(opcode);
-                        newCode.putShort(newOffset);
-                    }
-                    u += 3;
-                    break;
-                case ClassWriter.LABELW_INSN:
-                    label = u + readInt(b, u + 1);
-                    newOffset = getNewOffset(allIndexes, allSizes, u, label);
-                    newCode.putByte(opcode);
                     newCode.putInt(newOffset);
-                    u += 5;
-                    break;
-                case ClassWriter.TABL_INSN:
-                    // skips 0 to 3 padding bytes
-                    v = u;
-                    u = u + 4 - (v & 3);
-                    // reads and copies instruction
-                    newCode.putByte(Opcodes.TABLESWITCH);
-                    newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
+                } else {
+                    newCode.putByte(opcode);
+                    newCode.putShort(newOffset);
+                }
+                u += 3;
+                break;
+            case ClassWriter.LABELW_INSN:
+                label = u + readInt(b, u + 1);
+                newOffset = getNewOffset(allIndexes, allSizes, u, label);
+                newCode.putByte(opcode);
+                newCode.putInt(newOffset);
+                u += 5;
+                break;
+            case ClassWriter.TABL_INSN:
+                // skips 0 to 3 padding bytes
+                v = u;
+                u = u + 4 - (v & 3);
+                // reads and copies instruction
+                newCode.putByte(Opcodes.TABLESWITCH);
+                newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
+                label = v + readInt(b, u);
+                u += 4;
+                newOffset = getNewOffset(allIndexes, allSizes, v, label);
+                newCode.putInt(newOffset);
+                j = readInt(b, u);
+                u += 4;
+                newCode.putInt(j);
+                j = readInt(b, u) - j + 1;
+                u += 4;
+                newCode.putInt(readInt(b, u - 4));
+                for (; j > 0; --j) {
                     label = v + readInt(b, u);
                     u += 4;
                     newOffset = getNewOffset(allIndexes, allSizes, v, label);
                     newCode.putInt(newOffset);
-                    j = readInt(b, u);
+                }
+                break;
+            case ClassWriter.LOOK_INSN:
+                // skips 0 to 3 padding bytes
+                v = u;
+                u = u + 4 - (v & 3);
+                // reads and copies instruction
+                newCode.putByte(Opcodes.LOOKUPSWITCH);
+                newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
+                label = v + readInt(b, u);
+                u += 4;
+                newOffset = getNewOffset(allIndexes, allSizes, v, label);
+                newCode.putInt(newOffset);
+                j = readInt(b, u);
+                u += 4;
+                newCode.putInt(j);
+                for (; j > 0; --j) {
+                    newCode.putInt(readInt(b, u));
                     u += 4;
-                    newCode.putInt(j);
-                    j = readInt(b, u) - j + 1;
-                    u += 4;
-                    newCode.putInt(readInt(b, u - 4));
-                    for (; j > 0; --j) {
-                        label = v + readInt(b, u);
-                        u += 4;
-                        newOffset = getNewOffset(allIndexes, allSizes, v, label);
-                        newCode.putInt(newOffset);
-                    }
-                    break;
-                case ClassWriter.LOOK_INSN:
-                    // skips 0 to 3 padding bytes
-                    v = u;
-                    u = u + 4 - (v & 3);
-                    // reads and copies instruction
-                    newCode.putByte(Opcodes.LOOKUPSWITCH);
-                    newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
                     label = v + readInt(b, u);
                     u += 4;
                     newOffset = getNewOffset(allIndexes, allSizes, v, label);
                     newCode.putInt(newOffset);
-                    j = readInt(b, u);
-                    u += 4;
-                    newCode.putInt(j);
-                    for (; j > 0; --j) {
-                        newCode.putInt(readInt(b, u));
-                        u += 4;
-                        label = v + readInt(b, u);
-                        u += 4;
-                        newOffset = getNewOffset(allIndexes, allSizes, v, label);
-                        newCode.putInt(newOffset);
-                    }
-                    break;
-                case ClassWriter.WIDE_INSN:
-                    opcode = b[u + 1] & 0xFF;
-                    if (opcode == Opcodes.IINC) {
-                        newCode.putByteArray(b, u, 6);
-                        u += 6;
-                    } else {
-                        newCode.putByteArray(b, u, 4);
-                        u += 4;
-                    }
-                    break;
-                case ClassWriter.VAR_INSN:
-                case ClassWriter.SBYTE_INSN:
-                case ClassWriter.LDC_INSN:
-                    newCode.putByteArray(b, u, 2);
-                    u += 2;
-                    break;
-                case ClassWriter.SHORT_INSN:
-                case ClassWriter.LDCW_INSN:
-                case ClassWriter.FIELDORMETH_INSN:
-                case ClassWriter.TYPE_INSN:
-                case ClassWriter.IINC_INSN:
-                    newCode.putByteArray(b, u, 3);
-                    u += 3;
-                    break;
-                case ClassWriter.ITFMETH_INSN:
-                case ClassWriter.INDYMETH_INSN:
-                    newCode.putByteArray(b, u, 5);
-                    u += 5;
-                    break;
-                // case MANA_INSN:
-                default:
+                }
+                break;
+            case ClassWriter.WIDE_INSN:
+                opcode = b[u + 1] & 0xFF;
+                if (opcode == Opcodes.IINC) {
+                    newCode.putByteArray(b, u, 6);
+                    u += 6;
+                } else {
                     newCode.putByteArray(b, u, 4);
                     u += 4;
-                    break;
+                }
+                break;
+            case ClassWriter.VAR_INSN:
+            case ClassWriter.SBYTE_INSN:
+            case ClassWriter.LDC_INSN:
+                newCode.putByteArray(b, u, 2);
+                u += 2;
+                break;
+            case ClassWriter.SHORT_INSN:
+            case ClassWriter.LDCW_INSN:
+            case ClassWriter.FIELDORMETH_INSN:
+            case ClassWriter.TYPE_INSN:
+            case ClassWriter.IINC_INSN:
+                newCode.putByteArray(b, u, 3);
+                u += 3;
+                break;
+            case ClassWriter.ITFMETH_INSN:
+            case ClassWriter.INDYMETH_INSN:
+                newCode.putByteArray(b, u, 5);
+                u += 5;
+                break;
+            // case MANA_INSN:
+            default:
+                newCode.putByteArray(b, u, 4);
+                u += 4;
+                break;
             }
         }
 
@@ -2500,8 +2674,7 @@
                      * must therefore never have been called for this label.
                      */
                     u = l.position - 3;
-                    if ((l.status & Label.STORE) != 0 || (u >= 0 && resize[u]))
-                    {
+                    if ((l.status & Label.STORE) != 0 || (u >= 0 && resize[u])) {
                         getNewOffset(allIndexes, allSizes, l);
                         // TODO update offsets in UNINITIALIZED values
                         visitFrame(l.frame);
@@ -2557,10 +2730,11 @@
             b = lineNumber.data;
             u = 0;
             while (u < lineNumber.length) {
-                writeShort(b, u, getNewOffset(allIndexes,
-                        allSizes,
-                        0,
-                        readUnsignedShort(b, u)));
+                writeShort(
+                        b,
+                        u,
+                        getNewOffset(allIndexes, allSizes, 0,
+                                readUnsignedShort(b, u)));
                 u += 4;
             }
         }
@@ -2583,8 +2757,10 @@
     /**
      * Reads an unsigned short value in the given byte array.
      *
-     * @param b a byte array.
-     * @param index the start index of the value to be read.
+     * @param b
+     *            a byte array.
+     * @param index
+     *            the start index of the value to be read.
      * @return the read value.
      */
     static int readUnsignedShort(final byte[] b, final int index) {
@@ -2594,8 +2770,10 @@
     /**
      * Reads a signed short value in the given byte array.
      *
-     * @param b a byte array.
-     * @param index the start index of the value to be read.
+     * @param b
+     *            a byte array.
+     * @param index
+     *            the start index of the value to be read.
      * @return the read value.
      */
     static short readShort(final byte[] b, final int index) {
@@ -2605,8 +2783,10 @@
     /**
      * Reads a signed int value in the given byte array.
      *
-     * @param b a byte array.
-     * @param index the start index of the value to be read.
+     * @param b
+     *            a byte array.
+     * @param index
+     *            the start index of the value to be read.
      * @return the read value.
      */
     static int readInt(final byte[] b, final int index) {
@@ -2617,9 +2797,12 @@
     /**
      * Writes a short value in the given byte array.
      *
-     * @param b a byte array.
-     * @param index where the first byte of the short value must be written.
-     * @param s the value to be written in the given byte array.
+     * @param b
+     *            a byte array.
+     * @param index
+     *            where the first byte of the short value must be written.
+     * @param s
+     *            the value to be written in the given byte array.
      */
     static void writeShort(final byte[] b, final int index, final int s) {
         b[index] = (byte) (s >>> 8);
@@ -2627,32 +2810,34 @@
     }
 
     /**
-     * Computes the future value of a bytecode offset. <p> Note: it is possible
-     * to have several entries for the same instruction in the <tt>indexes</tt>
-     * and <tt>sizes</tt>: two entries (index=a,size=b) and (index=a,size=b')
-     * are equivalent to a single entry (index=a,size=b+b').
+     * Computes the future value of a bytecode offset.
+     * <p>
+     * Note: it is possible to have several entries for the same instruction in
+     * the <tt>indexes</tt> and <tt>sizes</tt>: two entries (index=a,size=b) and
+     * (index=a,size=b') are equivalent to a single entry (index=a,size=b+b').
      *
-     * @param indexes current positions of the instructions to be resized. Each
-     *        instruction must be designated by the index of its <i>last</i>
-     *        byte, plus one (or, in other words, by the index of the <i>first</i>
-     *        byte of the <i>next</i> instruction).
-     * @param sizes the number of bytes to be <i>added</i> to the above
-     *        instructions. More precisely, for each i < <tt>len</tt>,
-     *        <tt>sizes</tt>[i] bytes will be added at the end of the
-     *        instruction designated by <tt>indexes</tt>[i] or, if
-     *        <tt>sizes</tt>[i] is negative, the <i>last</i> |<tt>sizes[i]</tt>|
-     *        bytes of the instruction will be removed (the instruction size
-     *        <i>must not</i> become negative or null).
-     * @param begin index of the first byte of the source instruction.
-     * @param end index of the first byte of the target instruction.
+     * @param indexes
+     *            current positions of the instructions to be resized. Each
+     *            instruction must be designated by the index of its <i>last</i>
+     *            byte, plus one (or, in other words, by the index of the
+     *            <i>first</i> byte of the <i>next</i> instruction).
+     * @param sizes
+     *            the number of bytes to be <i>added</i> to the above
+     *            instructions. More precisely, for each i < <tt>len</tt>,
+     *            <tt>sizes</tt>[i] bytes will be added at the end of the
+     *            instruction designated by <tt>indexes</tt>[i] or, if
+     *            <tt>sizes</tt>[i] is negative, the <i>last</i> |
+     *            <tt>sizes[i]</tt>| bytes of the instruction will be removed
+     *            (the instruction size <i>must not</i> become negative or
+     *            null).
+     * @param begin
+     *            index of the first byte of the source instruction.
+     * @param end
+     *            index of the first byte of the target instruction.
      * @return the future value of the given bytecode offset.
      */
-    static int getNewOffset(
-        final int[] indexes,
-        final int[] sizes,
-        final int begin,
-        final int end)
-    {
+    static int getNewOffset(final int[] indexes, final int[] sizes,
+            final int begin, final int end) {
         int offset = end - begin;
         for (int i = 0; i < indexes.length; ++i) {
             if (begin < indexes[i] && indexes[i] <= end) {
@@ -2669,24 +2854,25 @@
     /**
      * Updates the offset of the given label.
      *
-     * @param indexes current positions of the instructions to be resized. Each
-     *        instruction must be designated by the index of its <i>last</i>
-     *        byte, plus one (or, in other words, by the index of the <i>first</i>
-     *        byte of the <i>next</i> instruction).
-     * @param sizes the number of bytes to be <i>added</i> to the above
-     *        instructions. More precisely, for each i < <tt>len</tt>,
-     *        <tt>sizes</tt>[i] bytes will be added at the end of the
-     *        instruction designated by <tt>indexes</tt>[i] or, if
-     *        <tt>sizes</tt>[i] is negative, the <i>last</i> |<tt>sizes[i]</tt>|
-     *        bytes of the instruction will be removed (the instruction size
-     *        <i>must not</i> become negative or null).
-     * @param label the label whose offset must be updated.
+     * @param indexes
+     *            current positions of the instructions to be resized. Each
+     *            instruction must be designated by the index of its <i>last</i>
+     *            byte, plus one (or, in other words, by the index of the
+     *            <i>first</i> byte of the <i>next</i> instruction).
+     * @param sizes
+     *            the number of bytes to be <i>added</i> to the above
+     *            instructions. More precisely, for each i < <tt>len</tt>,
+     *            <tt>sizes</tt>[i] bytes will be added at the end of the
+     *            instruction designated by <tt>indexes</tt>[i] or, if
+     *            <tt>sizes</tt>[i] is negative, the <i>last</i> |
+     *            <tt>sizes[i]</tt>| bytes of the instruction will be removed
+     *            (the instruction size <i>must not</i> become negative or
+     *            null).
+     * @param label
+     *            the label whose offset must be updated.
      */
-    static void getNewOffset(
-        final int[] indexes,
-        final int[] sizes,
-        final Label label)
-    {
+    static void getNewOffset(final int[] indexes, final int[] sizes,
+            final Label label) {
         if ((label.status & Label.RESIZED) == 0) {
             label.position = getNewOffset(indexes, sizes, 0, label.position);
             label.status |= Label.RESIZED;
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java
index df3dcbc..2868533 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java
@@ -75,6 +75,7 @@
     // ASM API versions
 
     int ASM4 = 4 << 16 | 0 << 8 | 0;
+    int ASM5 = 5 << 16 | 0 << 8 | 0;
 
     // versions
 
@@ -85,6 +86,7 @@
     int V1_5 = 0 << 16 | 49;
     int V1_6 = 0 << 16 | 50;
     int V1_7 = 0 << 16 | 51;
+    int V1_8 = 0 << 16 | 52;
 
     // access flags
 
@@ -92,7 +94,7 @@
     int ACC_PRIVATE = 0x0002; // class, field, method
     int ACC_PROTECTED = 0x0004; // class, field, method
     int ACC_STATIC = 0x0008; // field, method
-    int ACC_FINAL = 0x0010; // class, field, method
+    int ACC_FINAL = 0x0010; // class, field, method, parameter
     int ACC_SUPER = 0x0020; // class
     int ACC_SYNCHRONIZED = 0x0020; // method
     int ACC_VOLATILE = 0x0040; // field
@@ -103,9 +105,10 @@
     int ACC_INTERFACE = 0x0200; // class
     int ACC_ABSTRACT = 0x0400; // class, method
     int ACC_STRICT = 0x0800; // method
-    int ACC_SYNTHETIC = 0x1000; // class, field, method
+    int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter
     int ACC_ANNOTATION = 0x2000; // class
     int ACC_ENUM = 0x4000; // class(?) field inner
+    int ACC_MANDATED = 0x8000; // parameter
 
     // ASM specific pseudo access flags
 
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Type.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Type.java
index b7c7a7c..e385f9f 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Type.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Type.java
@@ -219,13 +219,16 @@
     /**
      * Constructs a reference type.
      *
-     * @param sort the sort of the reference type to be constructed.
-     * @param buf a buffer containing the descriptor of the previous type.
-     * @param off the offset of this descriptor in the previous buffer.
-     * @param len the length of this descriptor.
+     * @param sort
+     *            the sort of the reference type to be constructed.
+     * @param buf
+     *            a buffer containing the descriptor of the previous type.
+     * @param off
+     *            the offset of this descriptor in the previous buffer.
+     * @param len
+     *            the length of this descriptor.
      */
-    private Type(final int sort, final char[] buf, final int off, final int len)
-    {
+    private Type(final int sort, final char[] buf, final int off, final int len) {
         this.sort = sort;
         this.buf = buf;
         this.off = off;
@@ -235,7 +238,8 @@
     /**
      * Returns the Java type corresponding to the given type descriptor.
      *
-     * @param typeDescriptor a field or method type descriptor.
+     * @param typeDescriptor
+     *            a field or method type descriptor.
      * @return the Java type corresponding to the given type descriptor.
      */
     public static Type getType(final String typeDescriptor) {
@@ -245,7 +249,8 @@
     /**
      * Returns the Java type corresponding to the given internal name.
      *
-     * @param internalName an internal name.
+     * @param internalName
+     *            an internal name.
      * @return the Java type corresponding to the given internal name.
      */
     public static Type getObjectType(final String internalName) {
@@ -257,7 +262,8 @@
      * Returns the Java type corresponding to the given method descriptor.
      * Equivalent to <code>Type.getType(methodDescriptor)</code>.
      *
-     * @param methodDescriptor a method descriptor.
+     * @param methodDescriptor
+     *            a method descriptor.
      * @return the Java type corresponding to the given method descriptor.
      */
     public static Type getMethodType(final String methodDescriptor) {
@@ -268,18 +274,23 @@
      * Returns the Java method type corresponding to the given argument and
      * return types.
      *
-     * @param returnType the return type of the method.
-     * @param argumentTypes the argument types of the method.
-     * @return the Java type corresponding to the given argument and return types.
+     * @param returnType
+     *            the return type of the method.
+     * @param argumentTypes
+     *            the argument types of the method.
+     * @return the Java type corresponding to the given argument and return
+     *         types.
      */
-    public static Type getMethodType(final Type returnType, final Type... argumentTypes) {
+    public static Type getMethodType(final Type returnType,
+            final Type... argumentTypes) {
         return getType(getMethodDescriptor(returnType, argumentTypes));
     }
 
     /**
      * Returns the Java type corresponding to the given class.
      *
-     * @param c a class.
+     * @param c
+     *            a class.
      * @return the Java type corresponding to the given class.
      */
     public static Type getType(final Class<?> c) {
@@ -311,7 +322,8 @@
     /**
      * Returns the Java method type corresponding to the given constructor.
      *
-     * @param c a {@link Constructor Constructor} object.
+     * @param c
+     *            a {@link Constructor Constructor} object.
      * @return the Java method type corresponding to the given constructor.
      */
     public static Type getType(final Constructor<?> c) {
@@ -321,7 +333,8 @@
     /**
      * Returns the Java method type corresponding to the given method.
      *
-     * @param m a {@link Method Method} object.
+     * @param m
+     *            a {@link Method Method} object.
      * @return the Java method type corresponding to the given method.
      */
     public static Type getType(final Method m) {
@@ -332,7 +345,8 @@
      * Returns the Java types corresponding to the argument types of the given
      * method descriptor.
      *
-     * @param methodDescriptor a method descriptor.
+     * @param methodDescriptor
+     *            a method descriptor.
      * @return the Java types corresponding to the argument types of the given
      *         method descriptor.
      */
@@ -367,7 +381,8 @@
      * Returns the Java types corresponding to the argument types of the given
      * method.
      *
-     * @param method a method.
+     * @param method
+     *            a method.
      * @return the Java types corresponding to the argument types of the given
      *         method.
      */
@@ -384,7 +399,8 @@
      * Returns the Java type corresponding to the return type of the given
      * method descriptor.
      *
-     * @param methodDescriptor a method descriptor.
+     * @param methodDescriptor
+     *            a method descriptor.
      * @return the Java type corresponding to the return type of the given
      *         method descriptor.
      */
@@ -397,7 +413,8 @@
      * Returns the Java type corresponding to the return type of the given
      * method.
      *
-     * @param method a method.
+     * @param method
+     *            a method.
      * @return the Java type corresponding to the return type of the given
      *         method.
      */
@@ -408,12 +425,13 @@
     /**
      * Computes the size of the arguments and of the return value of a method.
      *
-     * @param desc the descriptor of a method.
+     * @param desc
+     *            the descriptor of a method.
      * @return the size of the arguments of the method (plus one for the
      *         implicit this argument), argSize, and the size of its return
      *         value, retSize, packed into a single int i =
-     *         <tt>(argSize << 2) | retSize</tt> (argSize is therefore equal
-     *         to <tt>i >> 2</tt>, and retSize to <tt>i & 0x03</tt>).
+     *         <tt>(argSize &lt;&lt; 2) | retSize</tt> (argSize is therefore equal to
+     *         <tt>i &gt;&gt; 2</tt>, and retSize to <tt>i &amp; 0x03</tt>).
      */
     public static int getArgumentsAndReturnSizes(final String desc) {
         int n = 1;
@@ -448,52 +466,54 @@
      * method descriptors, buf is supposed to contain nothing more than the
      * descriptor itself.
      *
-     * @param buf a buffer containing a type descriptor.
-     * @param off the offset of this descriptor in the previous buffer.
+     * @param buf
+     *            a buffer containing a type descriptor.
+     * @param off
+     *            the offset of this descriptor in the previous buffer.
      * @return the Java type corresponding to the given type descriptor.
      */
     private static Type getType(final char[] buf, final int off) {
         int len;
         switch (buf[off]) {
-            case 'V':
-                return VOID_TYPE;
-            case 'Z':
-                return BOOLEAN_TYPE;
-            case 'C':
-                return CHAR_TYPE;
-            case 'B':
-                return BYTE_TYPE;
-            case 'S':
-                return SHORT_TYPE;
-            case 'I':
-                return INT_TYPE;
-            case 'F':
-                return FLOAT_TYPE;
-            case 'J':
-                return LONG_TYPE;
-            case 'D':
-                return DOUBLE_TYPE;
-            case '[':
-                len = 1;
-                while (buf[off + len] == '[') {
-                    ++len;
-                }
-                if (buf[off + len] == 'L') {
-                    ++len;
-                    while (buf[off + len] != ';') {
-                        ++len;
-                    }
-                }
-                return new Type(ARRAY, buf, off, len + 1);
-            case 'L':
-                len = 1;
+        case 'V':
+            return VOID_TYPE;
+        case 'Z':
+            return BOOLEAN_TYPE;
+        case 'C':
+            return CHAR_TYPE;
+        case 'B':
+            return BYTE_TYPE;
+        case 'S':
+            return SHORT_TYPE;
+        case 'I':
+            return INT_TYPE;
+        case 'F':
+            return FLOAT_TYPE;
+        case 'J':
+            return LONG_TYPE;
+        case 'D':
+            return DOUBLE_TYPE;
+        case '[':
+            len = 1;
+            while (buf[off + len] == '[') {
+                ++len;
+            }
+            if (buf[off + len] == 'L') {
+                ++len;
                 while (buf[off + len] != ';') {
                     ++len;
                 }
-                return new Type(OBJECT, buf, off + 1, len - 1);
+            }
+            return new Type(ARRAY, buf, off, len + 1);
+        case 'L':
+            len = 1;
+            while (buf[off + len] != ';') {
+                ++len;
+            }
+            return new Type(OBJECT, buf, off + 1, len - 1);
             // case '(':
-            default:
-                return new Type(METHOD, buf, 0, buf.length);
+        default:
+            return new Type(METHOD, buf, off, buf.length - off);
         }
     }
 
@@ -504,11 +524,11 @@
     /**
      * Returns the sort of this Java type.
      *
-     * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN},
-     *         {@link #CHAR CHAR}, {@link #BYTE BYTE}, {@link #SHORT SHORT},
-     *         {@link #INT INT}, {@link #FLOAT FLOAT}, {@link #LONG LONG},
-     *         {@link #DOUBLE DOUBLE}, {@link #ARRAY ARRAY},
-     *         {@link #OBJECT OBJECT} or {@link #METHOD METHOD}.
+     * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR},
+     *         {@link #BYTE BYTE}, {@link #SHORT SHORT}, {@link #INT INT},
+     *         {@link #FLOAT FLOAT}, {@link #LONG LONG}, {@link #DOUBLE DOUBLE},
+     *         {@link #ARRAY ARRAY}, {@link #OBJECT OBJECT} or {@link #METHOD
+     *         METHOD}.
      */
     public int getSort() {
         return sort;
@@ -546,34 +566,34 @@
      */
     public String getClassName() {
         switch (sort) {
-            case VOID:
-                return "void";
-            case BOOLEAN:
-                return "boolean";
-            case CHAR:
-                return "char";
-            case BYTE:
-                return "byte";
-            case SHORT:
-                return "short";
-            case INT:
-                return "int";
-            case FLOAT:
-                return "float";
-            case LONG:
-                return "long";
-            case DOUBLE:
-                return "double";
-            case ARRAY:
-                StringBuffer b = new StringBuffer(getElementType().getClassName());
-                for (int i = getDimensions(); i > 0; --i) {
-                    b.append("[]");
-                }
-                return b.toString();
-            case OBJECT:
-                return new String(buf, off, len).replace('/', '.');
-            default:
-                return null;
+        case VOID:
+            return "void";
+        case BOOLEAN:
+            return "boolean";
+        case CHAR:
+            return "char";
+        case BYTE:
+            return "byte";
+        case SHORT:
+            return "short";
+        case INT:
+            return "int";
+        case FLOAT:
+            return "float";
+        case LONG:
+            return "long";
+        case DOUBLE:
+            return "double";
+        case ARRAY:
+            StringBuffer b = new StringBuffer(getElementType().getClassName());
+            for (int i = getDimensions(); i > 0; --i) {
+                b.append("[]");
+            }
+            return b.toString();
+        case OBJECT:
+            return new String(buf, off, len).replace('/', '.');
+        default:
+            return null;
         }
     }
 
@@ -615,9 +635,10 @@
      *
      * @return the size of the arguments (plus one for the implicit this
      *         argument), argSize, and the size of the return value, retSize,
-     *         packed into a single int i = <tt>(argSize << 2) | retSize</tt>
-     *         (argSize is therefore equal to <tt>i >> 2</tt>, and retSize to
-     *         <tt>i & 0x03</tt>).
+     *         packed into a single
+     *         int i = <tt>(argSize &lt;&lt; 2) | retSize</tt>
+     *         (argSize is therefore equal to <tt>i &gt;&gt; 2</tt>,
+     *         and retSize to <tt>i &amp; 0x03</tt>).
      */
     public int getArgumentsAndReturnSizes() {
         return getArgumentsAndReturnSizes(getDescriptor());
@@ -642,15 +663,15 @@
      * Returns the descriptor corresponding to the given argument and return
      * types.
      *
-     * @param returnType the return type of the method.
-     * @param argumentTypes the argument types of the method.
+     * @param returnType
+     *            the return type of the method.
+     * @param argumentTypes
+     *            the argument types of the method.
      * @return the descriptor corresponding to the given argument and return
      *         types.
      */
-    public static String getMethodDescriptor(
-        final Type returnType,
-        final Type... argumentTypes)
-    {
+    public static String getMethodDescriptor(final Type returnType,
+            final Type... argumentTypes) {
         StringBuffer buf = new StringBuffer();
         buf.append('(');
         for (int i = 0; i < argumentTypes.length; ++i) {
@@ -665,11 +686,13 @@
      * Appends the descriptor corresponding to this Java type to the given
      * string buffer.
      *
-     * @param buf the string buffer to which the descriptor must be appended.
+     * @param buf
+     *            the string buffer to which the descriptor must be appended.
      */
     private void getDescriptor(final StringBuffer buf) {
         if (this.buf == null) {
-            // descriptor is in byte 3 of 'off' for primitive types (buf == null)
+            // descriptor is in byte 3 of 'off' for primitive types (buf ==
+            // null)
             buf.append((char) ((off & 0xFF000000) >>> 24));
         } else if (sort == OBJECT) {
             buf.append('L');
@@ -690,7 +713,8 @@
      * class is its fully qualified name, as returned by Class.getName(), where
      * '.' are replaced by '/'.
      *
-     * @param c an object or array class.
+     * @param c
+     *            an object or array class.
      * @return the internal name of the given class.
      */
     public static String getInternalName(final Class<?> c) {
@@ -700,7 +724,8 @@
     /**
      * Returns the descriptor corresponding to the given Java type.
      *
-     * @param c an object class, a primitive class or an array class.
+     * @param c
+     *            an object class, a primitive class or an array class.
      * @return the descriptor corresponding to the given class.
      */
     public static String getDescriptor(final Class<?> c) {
@@ -712,7 +737,8 @@
     /**
      * Returns the descriptor corresponding to the given constructor.
      *
-     * @param c a {@link Constructor Constructor} object.
+     * @param c
+     *            a {@link Constructor Constructor} object.
      * @return the descriptor of the given constructor.
      */
     public static String getConstructorDescriptor(final Constructor<?> c) {
@@ -728,7 +754,8 @@
     /**
      * Returns the descriptor corresponding to the given method.
      *
-     * @param m a {@link Method Method} object.
+     * @param m
+     *            a {@link Method Method} object.
      * @return the descriptor of the given method.
      */
     public static String getMethodDescriptor(final Method m) {
@@ -746,8 +773,10 @@
     /**
      * Appends the descriptor of the given class to the given string buffer.
      *
-     * @param buf the string buffer to which the descriptor must be appended.
-     * @param c the class whose descriptor must be computed.
+     * @param buf
+     *            the string buffer to which the descriptor must be appended.
+     * @param c
+     *            the class whose descriptor must be computed.
      */
     private static void getDescriptor(final StringBuffer buf, final Class<?> c) {
         Class<?> d = c;
@@ -812,9 +841,10 @@
      * Returns a JVM instruction opcode adapted to this Java type. This method
      * must not be used for method types.
      *
-     * @param opcode a JVM instruction opcode. This opcode must be one of ILOAD,
-     *        ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, ISHL,
-     *        ISHR, IUSHR, IAND, IOR, IXOR and IRETURN.
+     * @param opcode
+     *            a JVM instruction opcode. This opcode must be one of ILOAD,
+     *            ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG,
+     *            ISHL, ISHR, IUSHR, IAND, IOR, IXOR and IRETURN.
      * @return an opcode that is similar to the given opcode, but adapted to
      *         this Java type. For example, if this type is <tt>float</tt> and
      *         <tt>opcode</tt> is IRETURN, this method returns FRETURN.
@@ -838,7 +868,8 @@
     /**
      * Tests if the given object is equal to this type.
      *
-     * @param o the object to be compared to this type.
+     * @param o
+     *            the object to be compared to this type.
      * @return <tt>true</tt> if the given object is equal to this type.
      */
     @Override
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/TypePath.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/TypePath.java
new file mode 100644
index 0000000..b43a11d
--- /dev/null
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/TypePath.java
@@ -0,0 +1,222 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2013 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm;
+
+/**
+ * The path to a type argument, wildcard bound, array element type, or static
+ * inner type within an enclosing type.
+ *
+ * @author Eric Bruneton
+ */
+public class TypePath {
+
+    /**
+     * A type path step that steps into the element type of an array type. See
+     * {@link #getStep getStep}.
+     */
+    public final static int ARRAY_ELEMENT = 0;
+
+    /**
+     * A type path step that steps into the nested type of a class type. See
+     * {@link #getStep getStep}.
+     */
+    public final static int INNER_TYPE = 1;
+
+    /**
+     * A type path step that steps into the bound of a wildcard type. See
+     * {@link #getStep getStep}.
+     */
+    public final static int WILDCARD_BOUND = 2;
+
+    /**
+     * A type path step that steps into a type argument of a generic type. See
+     * {@link #getStep getStep}.
+     */
+    public final static int TYPE_ARGUMENT = 3;
+
+    /**
+     * The byte array where the path is stored, in Java class file format.
+     */
+    byte[] b;
+
+    /**
+     * The offset of the first byte of the type path in 'b'.
+     */
+    int offset;
+
+    /**
+     * Creates a new type path.
+     *
+     * @param b
+     *            the byte array containing the type path in Java class file
+     *            format.
+     * @param offset
+     *            the offset of the first byte of the type path in 'b'.
+     */
+    TypePath(byte[] b, int offset) {
+        this.b = b;
+        this.offset = offset;
+    }
+
+    /**
+     * Returns the length of this path.
+     *
+     * @return the length of this path.
+     */
+    public int getLength() {
+        return b[offset];
+    }
+
+    /**
+     * Returns the value of the given step of this path.
+     *
+     * @param index
+     *            an index between 0 and {@link #getLength()}, exclusive.
+     * @return {@link #ARRAY_ELEMENT ARRAY_ELEMENT}, {@link #INNER_TYPE
+     *         INNER_TYPE}, {@link #WILDCARD_BOUND WILDCARD_BOUND}, or
+     *         {@link #TYPE_ARGUMENT TYPE_ARGUMENT}.
+     */
+    public int getStep(int index) {
+        return b[offset + 2 * index + 1];
+    }
+
+    /**
+     * Returns the index of the type argument that the given step is stepping
+     * into. This method should only be used for steps whose value is
+     * {@link #TYPE_ARGUMENT TYPE_ARGUMENT}.
+     *
+     * @param index
+     *            an index between 0 and {@link #getLength()}, exclusive.
+     * @return the index of the type argument that the given step is stepping
+     *         into.
+     */
+    public int getStepArgument(int index) {
+        return b[offset + 2 * index + 2];
+    }
+
+    /**
+     * Converts a type path in string form, in the format used by
+     * {@link #toString()}, into a TypePath object.
+     *
+     * @param typePath
+     *            a type path in string form, in the format used by
+     *            {@link #toString()}. May be null or empty.
+     * @return the corresponding TypePath object, or null if the path is empty.
+     */
+    public static TypePath fromString(final String typePath) {
+        if (typePath == null || typePath.length() == 0) {
+            return null;
+        }
+        int n = typePath.length();
+        ByteVector out = new ByteVector(n);
+        out.putByte(0);
+        for (int i = 0; i < n;) {
+            char c = typePath.charAt(i++);
+            if (c == '[') {
+                out.put11(ARRAY_ELEMENT, 0);
+            } else if (c == '.') {
+                out.put11(INNER_TYPE, 0);
+            } else if (c == '*') {
+                out.put11(WILDCARD_BOUND, 0);
+            } else if (c >= '0' && c <= '9') {
+                int typeArg = c - '0';
+                while (i < n && (c = typePath.charAt(i)) >= '0' && c <= '9') {
+                    typeArg = typeArg * 10 + c - '0';
+                    i += 1;
+                }
+                out.put11(TYPE_ARGUMENT, typeArg);
+            }
+        }
+        out.data[0] = (byte) (out.length / 2);
+        return new TypePath(out.data, 0);
+    }
+
+    /**
+     * Returns a string representation of this type path. {@link #ARRAY_ELEMENT
+     * ARRAY_ELEMENT} steps are represented with '[', {@link #INNER_TYPE
+     * INNER_TYPE} steps with '.', {@link #WILDCARD_BOUND WILDCARD_BOUND} steps
+     * with '*' and {@link #TYPE_ARGUMENT TYPE_ARGUMENT} steps with their type
+     * argument index in decimal form.
+     */
+    @Override
+    public String toString() {
+        int length = getLength();
+        StringBuilder result = new StringBuilder(length * 2);
+        for (int i = 0; i < length; ++i) {
+            switch (getStep(i)) {
+            case ARRAY_ELEMENT:
+                result.append('[');
+                break;
+            case INNER_TYPE:
+                result.append('.');
+                break;
+            case WILDCARD_BOUND:
+                result.append('*');
+                break;
+            case TYPE_ARGUMENT:
+                result.append(getStepArgument(i));
+                break;
+            default:
+                result.append('_');
+            }
+        }
+        return result.toString();
+    }
+}
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/TypeReference.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/TypeReference.java
new file mode 100644
index 0000000..4caf8f1
--- /dev/null
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/TypeReference.java
@@ -0,0 +1,481 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2013 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm;
+
+/**
+ * A reference to a type appearing in a class, field or method declaration, or
+ * on an instruction. Such a reference designates the part of the class where
+ * the referenced type is appearing (e.g. an 'extends', 'implements' or 'throws'
+ * clause, a 'new' instruction, a 'catch' clause, a type cast, a local variable
+ * declaration, etc).
+ *
+ * @author Eric Bruneton
+ */
+public class TypeReference {
+
+    /**
+     * The sort of type references that target a type parameter of a generic
+     * class. See {@link #getSort getSort}.
+     */
+    public final static int CLASS_TYPE_PARAMETER = 0x00;
+
+    /**
+     * The sort of type references that target a type parameter of a generic
+     * method. See {@link #getSort getSort}.
+     */
+    public final static int METHOD_TYPE_PARAMETER = 0x01;
+
+    /**
+     * The sort of type references that target the super class of a class or one
+     * of the interfaces it implements. See {@link #getSort getSort}.
+     */
+    public final static int CLASS_EXTENDS = 0x10;
+
+    /**
+     * The sort of type references that target a bound of a type parameter of a
+     * generic class. See {@link #getSort getSort}.
+     */
+    public final static int CLASS_TYPE_PARAMETER_BOUND = 0x11;
+
+    /**
+     * The sort of type references that target a bound of a type parameter of a
+     * generic method. See {@link #getSort getSort}.
+     */
+    public final static int METHOD_TYPE_PARAMETER_BOUND = 0x12;
+
+    /**
+     * The sort of type references that target the type of a field. See
+     * {@link #getSort getSort}.
+     */
+    public final static int FIELD = 0x13;
+
+    /**
+     * The sort of type references that target the return type of a method. See
+     * {@link #getSort getSort}.
+     */
+    public final static int METHOD_RETURN = 0x14;
+
+    /**
+     * The sort of type references that target the receiver type of a method.
+     * See {@link #getSort getSort}.
+     */
+    public final static int METHOD_RECEIVER = 0x15;
+
+    /**
+     * The sort of type references that target the type of a formal parameter of
+     * a method. See {@link #getSort getSort}.
+     */
+    public final static int METHOD_FORMAL_PARAMETER = 0x16;
+
+    /**
+     * The sort of type references that target the type of an exception declared
+     * in the throws clause of a method. See {@link #getSort getSort}.
+     */
+    public final static int THROWS = 0x17;
+
+    /**
+     * The sort of type references that target the type of a local variable in a
+     * method. See {@link #getSort getSort}.
+     */
+    public final static int LOCAL_VARIABLE = 0x40;
+
+    /**
+     * The sort of type references that target the type of a resource variable
+     * in a method. See {@link #getSort getSort}.
+     */
+    public final static int RESOURCE_VARIABLE = 0x41;
+
+    /**
+     * The sort of type references that target the type of the exception of a
+     * 'catch' clause in a method. See {@link #getSort getSort}.
+     */
+    public final static int EXCEPTION_PARAMETER = 0x42;
+
+    /**
+     * The sort of type references that target the type declared in an
+     * 'instanceof' instruction. See {@link #getSort getSort}.
+     */
+    public final static int INSTANCEOF = 0x43;
+
+    /**
+     * The sort of type references that target the type of the object created by
+     * a 'new' instruction. See {@link #getSort getSort}.
+     */
+    public final static int NEW = 0x44;
+
+    /**
+     * The sort of type references that target the receiver type of a
+     * constructor reference. See {@link #getSort getSort}.
+     */
+    public final static int CONSTRUCTOR_REFERENCE = 0x45;
+
+    /**
+     * The sort of type references that target the receiver type of a method
+     * reference. See {@link #getSort getSort}.
+     */
+    public final static int METHOD_REFERENCE = 0x46;
+
+    /**
+     * The sort of type references that target the type declared in an explicit
+     * or implicit cast instruction. See {@link #getSort getSort}.
+     */
+    public final static int CAST = 0x47;
+
+    /**
+     * The sort of type references that target a type parameter of a generic
+     * constructor in a constructor call. See {@link #getSort getSort}.
+     */
+    public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
+
+    /**
+     * The sort of type references that target a type parameter of a generic
+     * method in a method call. See {@link #getSort getSort}.
+     */
+    public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49;
+
+    /**
+     * The sort of type references that target a type parameter of a generic
+     * constructor in a constructor reference. See {@link #getSort getSort}.
+     */
+    public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A;
+
+    /**
+     * The sort of type references that target a type parameter of a generic
+     * method in a method reference. See {@link #getSort getSort}.
+     */
+    public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
+
+    /**
+     * The type reference value in Java class file format.
+     */
+    private int value;
+
+    /**
+     * Creates a new TypeReference.
+     *
+     * @param typeRef
+     *            the int encoded value of the type reference, as received in a
+     *            visit method related to type annotations, like
+     *            visitTypeAnnotation.
+     */
+    public TypeReference(int typeRef) {
+        this.value = typeRef;
+    }
+
+    /**
+     * Returns a type reference of the given sort.
+     *
+     * @param sort
+     *            {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN},
+     *            {@link #METHOD_RECEIVER METHOD_RECEIVER},
+     *            {@link #LOCAL_VARIABLE LOCAL_VARIABLE},
+     *            {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE},
+     *            {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW},
+     *            {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, or
+     *            {@link #METHOD_REFERENCE METHOD_REFERENCE}.
+     * @return a type reference of the given sort.
+     */
+    public static TypeReference newTypeReference(int sort) {
+        return new TypeReference(sort << 24);
+    }
+
+    /**
+     * Returns a reference to a type parameter of a generic class or method.
+     *
+     * @param sort
+     *            {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or
+     *            {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}.
+     * @param paramIndex
+     *            the type parameter index.
+     * @return a reference to the given generic class or method type parameter.
+     */
+    public static TypeReference newTypeParameterReference(int sort,
+            int paramIndex) {
+        return new TypeReference((sort << 24) | (paramIndex << 16));
+    }
+
+    /**
+     * Returns a reference to a type parameter bound of a generic class or
+     * method.
+     *
+     * @param sort
+     *            {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or
+     *            {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}.
+     * @param paramIndex
+     *            the type parameter index.
+     * @param boundIndex
+     *            the type bound index within the above type parameters.
+     * @return a reference to the given generic class or method type parameter
+     *         bound.
+     */
+    public static TypeReference newTypeParameterBoundReference(int sort,
+            int paramIndex, int boundIndex) {
+        return new TypeReference((sort << 24) | (paramIndex << 16)
+                | (boundIndex << 8));
+    }
+
+    /**
+     * Returns a reference to the super class or to an interface of the
+     * 'implements' clause of a class.
+     *
+     * @param itfIndex
+     *            the index of an interface in the 'implements' clause of a
+     *            class, or -1 to reference the super class of the class.
+     * @return a reference to the given super type of a class.
+     */
+    public static TypeReference newSuperTypeReference(int itfIndex) {
+        itfIndex &= 0xFFFF;
+        return new TypeReference((CLASS_EXTENDS << 24) | (itfIndex << 8));
+    }
+
+    /**
+     * Returns a reference to the type of a formal parameter of a method.
+     *
+     * @param paramIndex
+     *            the formal parameter index.
+     *
+     * @return a reference to the type of the given method formal parameter.
+     */
+    public static TypeReference newFormalParameterReference(int paramIndex) {
+        return new TypeReference((METHOD_FORMAL_PARAMETER << 24)
+                | (paramIndex << 16));
+    }
+
+    /**
+     * Returns a reference to the type of an exception, in a 'throws' clause of
+     * a method.
+     *
+     * @param exceptionIndex
+     *            the index of an exception in a 'throws' clause of a method.
+     *
+     * @return a reference to the type of the given exception.
+     */
+    public static TypeReference newExceptionReference(int exceptionIndex) {
+        return new TypeReference((THROWS << 24) | (exceptionIndex << 8));
+    }
+
+    /**
+     * Returns a reference to the type of the exception declared in a 'catch'
+     * clause of a method.
+     *
+     * @param tryCatchBlockIndex
+     *            the index of a try catch block (using the order in which they
+     *            are visited with visitTryCatchBlock).
+     *
+     * @return a reference to the type of the given exception.
+     */
+    public static TypeReference newTryCatchReference(int tryCatchBlockIndex) {
+        return new TypeReference((EXCEPTION_PARAMETER << 24)
+                | (tryCatchBlockIndex << 8));
+    }
+
+    /**
+     * Returns a reference to the type of a type argument in a constructor or
+     * method call or reference.
+     *
+     * @param sort
+     *            {@link #CAST CAST},
+     *            {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+     *            CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
+     *            {@link #METHOD_INVOCATION_TYPE_ARGUMENT
+     *            METHOD_INVOCATION_TYPE_ARGUMENT},
+     *            {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+     *            CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
+     *            {@link #METHOD_REFERENCE_TYPE_ARGUMENT
+     *            METHOD_REFERENCE_TYPE_ARGUMENT}.
+     * @param argIndex
+     *            the type argument index.
+     *
+     * @return a reference to the type of the given type argument.
+     */
+    public static TypeReference newTypeArgumentReference(int sort, int argIndex) {
+        return new TypeReference((sort << 24) | argIndex);
+    }
+
+    /**
+     * Returns the sort of this type reference.
+     *
+     * @return {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER},
+     *         {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER},
+     *         {@link #CLASS_EXTENDS CLASS_EXTENDS},
+     *         {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND},
+     *         {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND},
+     *         {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN},
+     *         {@link #METHOD_RECEIVER METHOD_RECEIVER},
+     *         {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER},
+     *         {@link #THROWS THROWS}, {@link #LOCAL_VARIABLE LOCAL_VARIABLE},
+     *         {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE},
+     *         {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER},
+     *         {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW},
+     *         {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE},
+     *         {@link #METHOD_REFERENCE METHOD_REFERENCE}, {@link #CAST CAST},
+     *         {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+     *         CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
+     *         {@link #METHOD_INVOCATION_TYPE_ARGUMENT
+     *         METHOD_INVOCATION_TYPE_ARGUMENT},
+     *         {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+     *         CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
+     *         {@link #METHOD_REFERENCE_TYPE_ARGUMENT
+     *         METHOD_REFERENCE_TYPE_ARGUMENT}.
+     */
+    public int getSort() {
+        return value >>> 24;
+    }
+
+    /**
+     * Returns the index of the type parameter referenced by this type
+     * reference. This method must only be used for type references whose sort
+     * is {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER},
+     * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER},
+     * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or
+     * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}.
+     *
+     * @return a type parameter index.
+     */
+    public int getTypeParameterIndex() {
+        return (value & 0x00FF0000) >> 16;
+    }
+
+    /**
+     * Returns the index of the type parameter bound, within the type parameter
+     * {@link #getTypeParameterIndex}, referenced by this type reference. This
+     * method must only be used for type references whose sort is
+     * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or
+     * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}.
+     *
+     * @return a type parameter bound index.
+     */
+    public int getTypeParameterBoundIndex() {
+        return (value & 0x0000FF00) >> 8;
+    }
+
+    /**
+     * Returns the index of the "super type" of a class that is referenced by
+     * this type reference. This method must only be used for type references
+     * whose sort is {@link #CLASS_EXTENDS CLASS_EXTENDS}.
+     *
+     * @return the index of an interface in the 'implements' clause of a class,
+     *         or -1 if this type reference references the type of the super
+     *         class.
+     */
+    public int getSuperTypeIndex() {
+        return (short) ((value & 0x00FFFF00) >> 8);
+    }
+
+    /**
+     * Returns the index of the formal parameter whose type is referenced by
+     * this type reference. This method must only be used for type references
+     * whose sort is {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER}.
+     *
+     * @return a formal parameter index.
+     */
+    public int getFormalParameterIndex() {
+        return (value & 0x00FF0000) >> 16;
+    }
+
+    /**
+     * Returns the index of the exception, in a 'throws' clause of a method,
+     * whose type is referenced by this type reference. This method must only be
+     * used for type references whose sort is {@link #THROWS THROWS}.
+     *
+     * @return the index of an exception in the 'throws' clause of a method.
+     */
+    public int getExceptionIndex() {
+        return (value & 0x00FFFF00) >> 8;
+    }
+
+    /**
+     * Returns the index of the try catch block (using the order in which they
+     * are visited with visitTryCatchBlock), whose 'catch' type is referenced by
+     * this type reference. This method must only be used for type references
+     * whose sort is {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER} .
+     *
+     * @return the index of an exception in the 'throws' clause of a method.
+     */
+    public int getTryCatchBlockIndex() {
+        return (value & 0x00FFFF00) >> 8;
+    }
+
+    /**
+     * Returns the index of the type argument referenced by this type reference.
+     * This method must only be used for type references whose sort is
+     * {@link #CAST CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+     * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
+     * {@link #METHOD_INVOCATION_TYPE_ARGUMENT METHOD_INVOCATION_TYPE_ARGUMENT},
+     * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+     * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
+     * {@link #METHOD_REFERENCE_TYPE_ARGUMENT METHOD_REFERENCE_TYPE_ARGUMENT}.
+     *
+     * @return a type parameter index.
+     */
+    public int getTypeArgumentIndex() {
+        return value & 0xFF;
+    }
+
+    /**
+     * Returns the int encoded value of this type reference, suitable for use in
+     * visit methods related to type annotations, like visitTypeAnnotation.
+     *
+     * @return the int encoded value of this type reference.
+     */
+    public int getValue() {
+        return value;
+    }
+}
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/AdviceAdapter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/AdviceAdapter.java
index dd6f260..c7d51d4 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/AdviceAdapter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/AdviceAdapter.java
@@ -30,7 +30,6 @@
  *
  * ASM: a very small and fast Java bytecode manipulation framework
  * Copyright (c) 2000-2011 INRIA, France Telecom
- * Copyright (c) 2011 Google
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -72,14 +71,16 @@
 
 /**
  * A {@link jdk.internal.org.objectweb.asm.MethodVisitor} to insert before, after and around
- * advices in methods and constructors. <p> The behavior for constructors is
- * like this: <ol>
+ * advices in methods and constructors.
+ * <p>
+ * The behavior for constructors is like this:
+ * <ol>
  *
  * <li>as long as the INVOKESPECIAL for the object initialization has not been
  * reached, every bytecode instruction is dispatched in the ctor code visitor</li>
  *
- * <li>when this one is reached, it is only added in the ctor code visitor and
- * a JP invoke is added</li>
+ * <li>when this one is reached, it is only added in the ctor code visitor and a
+ * JP invoke is added</li>
  *
  * <li>after that, only the other code visitor receives the instructions</li>
  *
@@ -88,8 +89,7 @@
  * @author Eugene Kuleshov
  * @author Eric Bruneton
  */
-public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
-{
+public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes {
 
     private static final Object THIS = new Object();
 
@@ -110,20 +110,20 @@
     /**
      * Creates a new {@link AdviceAdapter}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
-     * @param mv the method visitor to which this adapter delegates calls.
-     * @param access the method's access flags (see {@link Opcodes}).
-     * @param name the method's name.
-     * @param desc the method's descriptor (see {@link Type Type}).
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param mv
+     *            the method visitor to which this adapter delegates calls.
+     * @param access
+     *            the method's access flags (see {@link Opcodes}).
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor (see {@link Type Type}).
      */
-    protected AdviceAdapter(
-        final int api,
-        final MethodVisitor mv,
-        final int access,
-        final String name,
-        final String desc)
-    {
+    protected AdviceAdapter(final int api, final MethodVisitor mv,
+            final int access, final String name, final String desc) {
         super(api, mv, access, name, desc);
         methodAccess = access;
         methodDesc = desc;
@@ -159,194 +159,178 @@
         if (constructor) {
             int s;
             switch (opcode) {
-                case RETURN: // empty stack
-                    onMethodExit(opcode);
-                    break;
-
-                case IRETURN: // 1 before n/a after
-                case FRETURN: // 1 before n/a after
-                case ARETURN: // 1 before n/a after
-                case ATHROW: // 1 before n/a after
-                    popValue();
-                    onMethodExit(opcode);
-                    break;
-
-                case LRETURN: // 2 before n/a after
-                case DRETURN: // 2 before n/a after
-                    popValue();
-                    popValue();
-                    onMethodExit(opcode);
-                    break;
-
-                case NOP:
-                case LALOAD: // remove 2 add 2
-                case DALOAD: // remove 2 add 2
-                case LNEG:
-                case DNEG:
-                case FNEG:
-                case INEG:
-                case L2D:
-                case D2L:
-                case F2I:
-                case I2B:
-                case I2C:
-                case I2S:
-                case I2F:
-                case ARRAYLENGTH:
-                    break;
-
-                case ACONST_NULL:
-                case ICONST_M1:
-                case ICONST_0:
-                case ICONST_1:
-                case ICONST_2:
-                case ICONST_3:
-                case ICONST_4:
-                case ICONST_5:
-                case FCONST_0:
-                case FCONST_1:
-                case FCONST_2:
-                case F2L: // 1 before 2 after
-                case F2D:
-                case I2L:
-                case I2D:
-                    pushValue(OTHER);
-                    break;
-
-                case LCONST_0:
-                case LCONST_1:
-                case DCONST_0:
-                case DCONST_1:
-                    pushValue(OTHER);
-                    pushValue(OTHER);
-                    break;
-
-                case IALOAD: // remove 2 add 1
-                case FALOAD: // remove 2 add 1
-                case AALOAD: // remove 2 add 1
-                case BALOAD: // remove 2 add 1
-                case CALOAD: // remove 2 add 1
-                case SALOAD: // remove 2 add 1
-                case POP:
-                case IADD:
-                case FADD:
-                case ISUB:
-                case LSHL: // 3 before 2 after
-                case LSHR: // 3 before 2 after
-                case LUSHR: // 3 before 2 after
-                case L2I: // 2 before 1 after
-                case L2F: // 2 before 1 after
-                case D2I: // 2 before 1 after
-                case D2F: // 2 before 1 after
-                case FSUB:
-                case FMUL:
-                case FDIV:
-                case FREM:
-                case FCMPL: // 2 before 1 after
-                case FCMPG: // 2 before 1 after
-                case IMUL:
-                case IDIV:
-                case IREM:
-                case ISHL:
-                case ISHR:
-                case IUSHR:
-                case IAND:
-                case IOR:
-                case IXOR:
-                case MONITORENTER:
-                case MONITOREXIT:
-                    popValue();
-                    break;
-
-                case POP2:
-                case LSUB:
-                case LMUL:
-                case LDIV:
-                case LREM:
-                case LADD:
-                case LAND:
-                case LOR:
-                case LXOR:
-                case DADD:
-                case DMUL:
-                case DSUB:
-                case DDIV:
-                case DREM:
-                    popValue();
-                    popValue();
-                    break;
-
-                case IASTORE:
-                case FASTORE:
-                case AASTORE:
-                case BASTORE:
-                case CASTORE:
-                case SASTORE:
-                case LCMP: // 4 before 1 after
-                case DCMPL:
-                case DCMPG:
-                    popValue();
-                    popValue();
-                    popValue();
-                    break;
-
-                case LASTORE:
-                case DASTORE:
-                    popValue();
-                    popValue();
-                    popValue();
-                    popValue();
-                    break;
-
-                case DUP:
-                    pushValue(peekValue());
-                    break;
-
-                case DUP_X1:
-                    s = stackFrame.size();
-                    stackFrame.add(s - 2, stackFrame.get(s - 1));
-                    break;
-
-                case DUP_X2:
-                    s = stackFrame.size();
-                    stackFrame.add(s - 3, stackFrame.get(s - 1));
-                    break;
-
-                case DUP2:
-                    s = stackFrame.size();
-                    stackFrame.add(s - 2, stackFrame.get(s - 1));
-                    stackFrame.add(s - 2, stackFrame.get(s - 1));
-                    break;
-
-                case DUP2_X1:
-                    s = stackFrame.size();
-                    stackFrame.add(s - 3, stackFrame.get(s - 1));
-                    stackFrame.add(s - 3, stackFrame.get(s - 1));
-                    break;
-
-                case DUP2_X2:
-                    s = stackFrame.size();
-                    stackFrame.add(s - 4, stackFrame.get(s - 1));
-                    stackFrame.add(s - 4, stackFrame.get(s - 1));
-                    break;
-
-                case SWAP:
-                    s = stackFrame.size();
-                    stackFrame.add(s - 2, stackFrame.get(s - 1));
-                    stackFrame.remove(s);
-                    break;
+            case RETURN: // empty stack
+                onMethodExit(opcode);
+                break;
+            case IRETURN: // 1 before n/a after
+            case FRETURN: // 1 before n/a after
+            case ARETURN: // 1 before n/a after
+            case ATHROW: // 1 before n/a after
+                popValue();
+                onMethodExit(opcode);
+                break;
+            case LRETURN: // 2 before n/a after
+            case DRETURN: // 2 before n/a after
+                popValue();
+                popValue();
+                onMethodExit(opcode);
+                break;
+            case NOP:
+            case LALOAD: // remove 2 add 2
+            case DALOAD: // remove 2 add 2
+            case LNEG:
+            case DNEG:
+            case FNEG:
+            case INEG:
+            case L2D:
+            case D2L:
+            case F2I:
+            case I2B:
+            case I2C:
+            case I2S:
+            case I2F:
+            case ARRAYLENGTH:
+                break;
+            case ACONST_NULL:
+            case ICONST_M1:
+            case ICONST_0:
+            case ICONST_1:
+            case ICONST_2:
+            case ICONST_3:
+            case ICONST_4:
+            case ICONST_5:
+            case FCONST_0:
+            case FCONST_1:
+            case FCONST_2:
+            case F2L: // 1 before 2 after
+            case F2D:
+            case I2L:
+            case I2D:
+                pushValue(OTHER);
+                break;
+            case LCONST_0:
+            case LCONST_1:
+            case DCONST_0:
+            case DCONST_1:
+                pushValue(OTHER);
+                pushValue(OTHER);
+                break;
+            case IALOAD: // remove 2 add 1
+            case FALOAD: // remove 2 add 1
+            case AALOAD: // remove 2 add 1
+            case BALOAD: // remove 2 add 1
+            case CALOAD: // remove 2 add 1
+            case SALOAD: // remove 2 add 1
+            case POP:
+            case IADD:
+            case FADD:
+            case ISUB:
+            case LSHL: // 3 before 2 after
+            case LSHR: // 3 before 2 after
+            case LUSHR: // 3 before 2 after
+            case L2I: // 2 before 1 after
+            case L2F: // 2 before 1 after
+            case D2I: // 2 before 1 after
+            case D2F: // 2 before 1 after
+            case FSUB:
+            case FMUL:
+            case FDIV:
+            case FREM:
+            case FCMPL: // 2 before 1 after
+            case FCMPG: // 2 before 1 after
+            case IMUL:
+            case IDIV:
+            case IREM:
+            case ISHL:
+            case ISHR:
+            case IUSHR:
+            case IAND:
+            case IOR:
+            case IXOR:
+            case MONITORENTER:
+            case MONITOREXIT:
+                popValue();
+                break;
+            case POP2:
+            case LSUB:
+            case LMUL:
+            case LDIV:
+            case LREM:
+            case LADD:
+            case LAND:
+            case LOR:
+            case LXOR:
+            case DADD:
+            case DMUL:
+            case DSUB:
+            case DDIV:
+            case DREM:
+                popValue();
+                popValue();
+                break;
+            case IASTORE:
+            case FASTORE:
+            case AASTORE:
+            case BASTORE:
+            case CASTORE:
+            case SASTORE:
+            case LCMP: // 4 before 1 after
+            case DCMPL:
+            case DCMPG:
+                popValue();
+                popValue();
+                popValue();
+                break;
+            case LASTORE:
+            case DASTORE:
+                popValue();
+                popValue();
+                popValue();
+                popValue();
+                break;
+            case DUP:
+                pushValue(peekValue());
+                break;
+            case DUP_X1:
+                s = stackFrame.size();
+                stackFrame.add(s - 2, stackFrame.get(s - 1));
+                break;
+            case DUP_X2:
+                s = stackFrame.size();
+                stackFrame.add(s - 3, stackFrame.get(s - 1));
+                break;
+            case DUP2:
+                s = stackFrame.size();
+                stackFrame.add(s - 2, stackFrame.get(s - 1));
+                stackFrame.add(s - 2, stackFrame.get(s - 1));
+                break;
+            case DUP2_X1:
+                s = stackFrame.size();
+                stackFrame.add(s - 3, stackFrame.get(s - 1));
+                stackFrame.add(s - 3, stackFrame.get(s - 1));
+                break;
+            case DUP2_X2:
+                s = stackFrame.size();
+                stackFrame.add(s - 4, stackFrame.get(s - 1));
+                stackFrame.add(s - 4, stackFrame.get(s - 1));
+                break;
+            case SWAP:
+                s = stackFrame.size();
+                stackFrame.add(s - 2, stackFrame.get(s - 1));
+                stackFrame.remove(s);
+                break;
             }
         } else {
             switch (opcode) {
-                case RETURN:
-                case IRETURN:
-                case FRETURN:
-                case ARETURN:
-                case LRETURN:
-                case DRETURN:
-                case ATHROW:
-                    onMethodExit(opcode);
-                    break;
+            case RETURN:
+            case IRETURN:
+            case FRETURN:
+            case ARETURN:
+            case LRETURN:
+            case DRETURN:
+            case ATHROW:
+                onMethodExit(opcode);
+                break;
             }
         }
         mv.visitInsn(opcode);
@@ -357,68 +341,64 @@
         super.visitVarInsn(opcode, var);
         if (constructor) {
             switch (opcode) {
-                case ILOAD:
-                case FLOAD:
-                    pushValue(OTHER);
-                    break;
-                case LLOAD:
-                case DLOAD:
-                    pushValue(OTHER);
-                    pushValue(OTHER);
-                    break;
-                case ALOAD:
-                    pushValue(var == 0 ? THIS : OTHER);
-                    break;
-                case ASTORE:
-                case ISTORE:
-                case FSTORE:
-                    popValue();
-                    break;
-                case LSTORE:
-                case DSTORE:
-                    popValue();
-                    popValue();
-                    break;
+            case ILOAD:
+            case FLOAD:
+                pushValue(OTHER);
+                break;
+            case LLOAD:
+            case DLOAD:
+                pushValue(OTHER);
+                pushValue(OTHER);
+                break;
+            case ALOAD:
+                pushValue(var == 0 ? THIS : OTHER);
+                break;
+            case ASTORE:
+            case ISTORE:
+            case FSTORE:
+                popValue();
+                break;
+            case LSTORE:
+            case DSTORE:
+                popValue();
+                popValue();
+                break;
             }
         }
     }
 
     @Override
-    public void visitFieldInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitFieldInsn(final int opcode, final String owner,
+            final String name, final String desc) {
         mv.visitFieldInsn(opcode, owner, name, desc);
         if (constructor) {
             char c = desc.charAt(0);
             boolean longOrDouble = c == 'J' || c == 'D';
             switch (opcode) {
-                case GETSTATIC:
+            case GETSTATIC:
+                pushValue(OTHER);
+                if (longOrDouble) {
                     pushValue(OTHER);
-                    if (longOrDouble) {
-                        pushValue(OTHER);
-                    }
-                    break;
-                case PUTSTATIC:
+                }
+                break;
+            case PUTSTATIC:
+                popValue();
+                if (longOrDouble) {
                     popValue();
-                    if (longOrDouble) {
-                        popValue();
-                    }
-                    break;
-                case PUTFIELD:
+                }
+                break;
+            case PUTFIELD:
+                popValue();
+                if (longOrDouble) {
                     popValue();
-                    if (longOrDouble) {
-                        popValue();
-                        popValue();
-                    }
-                    break;
-                // case GETFIELD:
-                default:
-                    if (longOrDouble) {
-                        pushValue(OTHER);
-                    }
+                    popValue();
+                }
+                break;
+            // case GETFIELD:
+            default:
+                if (longOrDouble) {
+                    pushValue(OTHER);
+                }
             }
         }
     }
@@ -463,12 +443,8 @@
     }
 
     @Override
-    public void visitMethodInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitMethodInsn(final int opcode, final String owner,
+            final String name, final String desc) {
         mv.visitMethodInsn(opcode, owner, name, desc);
         if (constructor) {
             Type[] types = Type.getArgumentTypes(desc);
@@ -479,24 +455,22 @@
                 }
             }
             switch (opcode) {
-                // case INVOKESTATIC:
-                // break;
-
-                case INVOKEINTERFACE:
-                case INVOKEVIRTUAL:
-                    popValue(); // objectref
-                    break;
-
-                case INVOKESPECIAL:
-                    Object type = popValue(); // objectref
-                    if (type == THIS && !superInitialized) {
-                        onMethodEnter();
-                        superInitialized = true;
-                        // once super has been initialized it is no longer
-                        // necessary to keep track of stack state
-                        constructor = false;
-                    }
-                    break;
+            // case INVOKESTATIC:
+            // break;
+            case INVOKEINTERFACE:
+            case INVOKEVIRTUAL:
+                popValue(); // objectref
+                break;
+            case INVOKESPECIAL:
+                Object type = popValue(); // objectref
+                if (type == THIS && !superInitialized) {
+                    onMethodEnter();
+                    superInitialized = true;
+                    // once super has been initialized it is no longer
+                    // necessary to keep track of stack state
+                    constructor = false;
+                }
+                break;
             }
 
             Type returnType = Type.getReturnType(desc);
@@ -510,12 +484,8 @@
     }
 
     @Override
-    public void visitInvokeDynamicInsn(
-        String name,
-        String desc,
-        Handle bsm,
-        Object... bsmArgs)
-    {
+    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+            Object... bsmArgs) {
         mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
         if (constructor) {
             Type[] types = Type.getArgumentTypes(desc);
@@ -541,43 +511,38 @@
         mv.visitJumpInsn(opcode, label);
         if (constructor) {
             switch (opcode) {
-                case IFEQ:
-                case IFNE:
-                case IFLT:
-                case IFGE:
-                case IFGT:
-                case IFLE:
-                case IFNULL:
-                case IFNONNULL:
-                    popValue();
-                    break;
-
-                case IF_ICMPEQ:
-                case IF_ICMPNE:
-                case IF_ICMPLT:
-                case IF_ICMPGE:
-                case IF_ICMPGT:
-                case IF_ICMPLE:
-                case IF_ACMPEQ:
-                case IF_ACMPNE:
-                    popValue();
-                    popValue();
-                    break;
-
-                case JSR:
-                    pushValue(OTHER);
-                    break;
+            case IFEQ:
+            case IFNE:
+            case IFLT:
+            case IFGE:
+            case IFGT:
+            case IFLE:
+            case IFNULL:
+            case IFNONNULL:
+                popValue();
+                break;
+            case IF_ICMPEQ:
+            case IF_ICMPNE:
+            case IF_ICMPLT:
+            case IF_ICMPGE:
+            case IF_ICMPGT:
+            case IF_ICMPLE:
+            case IF_ACMPEQ:
+            case IF_ACMPNE:
+                popValue();
+                popValue();
+                break;
+            case JSR:
+                pushValue(OTHER);
+                break;
             }
             addBranch(label);
         }
     }
 
     @Override
-    public void visitLookupSwitchInsn(
-        final Label dflt,
-        final int[] keys,
-        final Label[] labels)
-    {
+    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+            final Label[] labels) {
         mv.visitLookupSwitchInsn(dflt, keys, labels);
         if (constructor) {
             popValue();
@@ -586,12 +551,8 @@
     }
 
     @Override
-    public void visitTableSwitchInsn(
-        final int min,
-        final int max,
-        final Label dflt,
-        final Label... labels)
-    {
+    public void visitTableSwitchInsn(final int min, final int max,
+            final Label dflt, final Label... labels) {
         mv.visitTableSwitchInsn(min, max, dflt, labels);
         if (constructor) {
             popValue();
@@ -600,12 +561,8 @@
     }
 
     @Override
-    public void visitTryCatchBlock(
-        Label start,
-        Label end,
-        Label handler,
-        String type)
-    {
+    public void visitTryCatchBlock(Label start, Label end, Label handler,
+            String type) {
         super.visitTryCatchBlock(start, end, handler, type);
         if (constructor && !branches.containsKey(handler)) {
             List<Object> stackFrame = new ArrayList<Object>();
@@ -642,7 +599,8 @@
 
     /**
      * Called at the beginning of the method or after super class class call in
-     * the constructor. <br><br>
+     * the constructor. <br>
+     * <br>
      *
      * <i>Custom code can use or change all the local variables, but should not
      * change state of the stack.</i>
@@ -678,13 +636,15 @@
      *     ...
      * </pre>
      *
-     * <br><br>
+     * <br>
+     * <br>
      *
      * <i>Custom code can use or change all the local variables, but should not
      * change state of the stack.</i>
      *
-     * @param opcode one of the RETURN, IRETURN, FRETURN, ARETURN, LRETURN,
-     *        DRETURN or ATHROW
+     * @param opcode
+     *            one of the RETURN, IRETURN, FRETURN, ARETURN, LRETURN, DRETURN
+     *            or ATHROW
      *
      */
     protected void onMethodExit(int opcode) {
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java
index c686141..1371250 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java
@@ -73,13 +73,13 @@
  * A {@link MethodVisitor} that keeps track of stack map frame changes between
  * {@link #visitFrame(int, int, Object[], int, Object[]) visitFrame} calls. This
  * adapter must be used with the
- * {@link jdk.internal.org.objectweb.asm.ClassReader#EXPAND_FRAMES} option. Each visit<i>X</i>
- * instruction delegates to the next visitor in the chain, if any, and then
- * simulates the effect of this instruction on the stack map frame, represented
- * by {@link #locals} and {@link #stack}. The next visitor in the chain can get
- * the state of the stack map frame <i>before</i> each instruction by reading
- * the value of these fields in its visit<i>X</i> methods (this requires a
- * reference to the AnalyzerAdapter that is before it in the chain).
+ * {@link jdk.internal.org.objectweb.asm.ClassReader#EXPAND_FRAMES} option. Each
+ * visit<i>X</i> instruction delegates to the next visitor in the chain, if any,
+ * and then simulates the effect of this instruction on the stack map frame,
+ * represented by {@link #locals} and {@link #stack}. The next visitor in the
+ * chain can get the state of the stack map frame <i>before</i> each instruction
+ * by reading the value of these fields in its visit<i>X</i> methods (this
+ * requires a reference to the AnalyzerAdapter that is before it in the chain).
  * If this adapter is used with a class that does not contain stack map table
  * attributes (i.e., pre Java 6 classes) then this adapter may not be able to
  * compute the stack map frame for each instruction. In this case no exception
@@ -95,25 +95,25 @@
      * frame. Primitive types are represented by {@link Opcodes#TOP},
      * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
      * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
-     * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a
+     * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by
      * two elements, the second one being TOP). Reference types are represented
      * by String objects (representing internal names), and uninitialized types
      * by Label objects (this label designates the NEW instruction that created
-     * this uninitialized value). This field is <tt>null</tt> for unreacheable
+     * this uninitialized value). This field is <tt>null</tt> for unreachable
      * instructions.
      */
     public List<Object> locals;
 
     /**
-     * <code>List</code> of the operand stack slots for current execution
-     * frame. Primitive types are represented by {@link Opcodes#TOP},
+     * <code>List</code> of the operand stack slots for current execution frame.
+     * Primitive types are represented by {@link Opcodes#TOP},
      * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
      * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
-     * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a
+     * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by
      * two elements, the second one being TOP). Reference types are represented
      * by String objects (representing internal names), and uninitialized types
      * by Label objects (this label designates the NEW instruction that created
-     * this uninitialized value). This field is <tt>null</tt> for unreacheable
+     * this uninitialized value). This field is <tt>null</tt> for unreachable
      * instructions.
      */
     public List<Object> stack;
@@ -131,7 +131,7 @@
      * types, and the associated internal name represents the NEW operand, i.e.
      * the final, initialized type value.
      */
-    public Map<Object,Object> uninitializedTypes;
+    public Map<Object, Object> uninitializedTypes;
 
     /**
      * The maximum stack size of this method.
@@ -154,43 +154,44 @@
      * {@link #AnalyzerAdapter(int, String, int, String, String, MethodVisitor)}
      * version.
      *
-     * @param owner the owner's class name.
-     * @param access the method's access flags (see {@link Opcodes}).
-     * @param name the method's name.
-     * @param desc the method's descriptor (see {@link Type Type}).
-     * @param mv the method visitor to which this adapter delegates calls. May
-     *        be <tt>null</tt>.
+     * @param owner
+     *            the owner's class name.
+     * @param access
+     *            the method's access flags (see {@link Opcodes}).
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor (see {@link Type Type}).
+     * @param mv
+     *            the method visitor to which this adapter delegates calls. May
+     *            be <tt>null</tt>.
      */
-    public AnalyzerAdapter(
-        final String owner,
-        final int access,
-        final String name,
-        final String desc,
-        final MethodVisitor mv)
-    {
-        this(Opcodes.ASM4, owner, access, name, desc, mv);
+    public AnalyzerAdapter(final String owner, final int access,
+            final String name, final String desc, final MethodVisitor mv) {
+        this(Opcodes.ASM5, owner, access, name, desc, mv);
     }
 
     /**
      * Creates a new {@link AnalyzerAdapter}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
-     * @param owner the owner's class name.
-     * @param access the method's access flags (see {@link Opcodes}).
-     * @param name the method's name.
-     * @param desc the method's descriptor (see {@link Type Type}).
-     * @param mv the method visitor to which this adapter delegates calls. May
-     *        be <tt>null</tt>.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param owner
+     *            the owner's class name.
+     * @param access
+     *            the method's access flags (see {@link Opcodes}).
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor (see {@link Type Type}).
+     * @param mv
+     *            the method visitor to which this adapter delegates calls. May
+     *            be <tt>null</tt>.
      */
-    protected AnalyzerAdapter(
-        final int api,
-        final String owner,
-        final int access,
-        final String name,
-        final String desc,
-        final MethodVisitor mv)
-    {
+    protected AnalyzerAdapter(final int api, final String owner,
+            final int access, final String name, final String desc,
+            final MethodVisitor mv) {
         super(api, mv);
         this.owner = owner;
         locals = new ArrayList<Object>();
@@ -208,44 +209,40 @@
         for (int i = 0; i < types.length; ++i) {
             Type type = types[i];
             switch (type.getSort()) {
-                case Type.BOOLEAN:
-                case Type.CHAR:
-                case Type.BYTE:
-                case Type.SHORT:
-                case Type.INT:
-                    locals.add(Opcodes.INTEGER);
-                    break;
-                case Type.FLOAT:
-                    locals.add(Opcodes.FLOAT);
-                    break;
-                case Type.LONG:
-                    locals.add(Opcodes.LONG);
-                    locals.add(Opcodes.TOP);
-                    break;
-                case Type.DOUBLE:
-                    locals.add(Opcodes.DOUBLE);
-                    locals.add(Opcodes.TOP);
-                    break;
-                case Type.ARRAY:
-                    locals.add(types[i].getDescriptor());
-                    break;
-                // case Type.OBJECT:
-                default:
-                    locals.add(types[i].getInternalName());
+            case Type.BOOLEAN:
+            case Type.CHAR:
+            case Type.BYTE:
+            case Type.SHORT:
+            case Type.INT:
+                locals.add(Opcodes.INTEGER);
+                break;
+            case Type.FLOAT:
+                locals.add(Opcodes.FLOAT);
+                break;
+            case Type.LONG:
+                locals.add(Opcodes.LONG);
+                locals.add(Opcodes.TOP);
+                break;
+            case Type.DOUBLE:
+                locals.add(Opcodes.DOUBLE);
+                locals.add(Opcodes.TOP);
+                break;
+            case Type.ARRAY:
+                locals.add(types[i].getDescriptor());
+                break;
+            // case Type.OBJECT:
+            default:
+                locals.add(types[i].getInternalName());
             }
         }
     }
 
     @Override
-    public void visitFrame(
-        final int type,
-        final int nLocal,
-        final Object[] local,
-        final int nStack,
-        final Object[] stack)
-    {
+    public void visitFrame(final int type, final int nLocal,
+            final Object[] local, final int nStack, final Object[] stack) {
         if (type != Opcodes.F_NEW) { // uncompressed frame
-            throw new IllegalStateException("ClassReader.accept() should be called with EXPAND_FRAMES flag");
+            throw new IllegalStateException(
+                    "ClassReader.accept() should be called with EXPAND_FRAMES flag");
         }
 
         if (mv != null) {
@@ -264,11 +261,8 @@
         maxStack = Math.max(maxStack, this.stack.size());
     }
 
-    private static void visitFrameTypes(
-        final int n,
-        final Object[] types,
-        final List<Object> result)
-    {
+    private static void visitFrameTypes(final int n, final Object[] types,
+            final List<Object> result) {
         for (int i = 0; i < n; ++i) {
             Object type = types[i];
             result.add(type);
@@ -285,8 +279,7 @@
         }
         execute(opcode, 0, null);
         if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN)
-                || opcode == Opcodes.ATHROW)
-        {
+                || opcode == Opcodes.ATHROW) {
             this.locals = null;
             this.stack = null;
         }
@@ -330,12 +323,8 @@
     }
 
     @Override
-    public void visitFieldInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitFieldInsn(final int opcode, final String owner,
+            final String name, final String desc) {
         if (mv != null) {
             mv.visitFieldInsn(opcode, owner, name, desc);
         }
@@ -343,12 +332,8 @@
     }
 
     @Override
-    public void visitMethodInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitMethodInsn(final int opcode, final String owner,
+            final String name, final String desc) {
         if (mv != null) {
             mv.visitMethodInsn(opcode, owner, name, desc);
         }
@@ -383,12 +368,8 @@
     }
 
     @Override
-    public void visitInvokeDynamicInsn(
-        String name,
-        String desc,
-        Handle bsm,
-        Object... bsmArgs)
-    {
+    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+            Object... bsmArgs) {
         if (mv != null) {
             mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
         }
@@ -471,12 +452,8 @@
     }
 
     @Override
-    public void visitTableSwitchInsn(
-        final int min,
-        final int max,
-        final Label dflt,
-        final Label... labels)
-    {
+    public void visitTableSwitchInsn(final int min, final int max,
+            final Label dflt, final Label... labels) {
         if (mv != null) {
             mv.visitTableSwitchInsn(min, max, dflt, labels);
         }
@@ -486,11 +463,8 @@
     }
 
     @Override
-    public void visitLookupSwitchInsn(
-        final Label dflt,
-        final int[] keys,
-        final Label[] labels)
-    {
+    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+            final Label[] labels) {
         if (mv != null) {
             mv.visitLookupSwitchInsn(dflt, keys, labels);
         }
@@ -539,40 +513,40 @@
     private void pushDesc(final String desc) {
         int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
         switch (desc.charAt(index)) {
-            case 'V':
-                return;
-            case 'Z':
-            case 'C':
-            case 'B':
-            case 'S':
-            case 'I':
-                push(Opcodes.INTEGER);
-                return;
-            case 'F':
-                push(Opcodes.FLOAT);
-                return;
-            case 'J':
-                push(Opcodes.LONG);
-                push(Opcodes.TOP);
-                return;
-            case 'D':
-                push(Opcodes.DOUBLE);
-                push(Opcodes.TOP);
-                return;
-            case '[':
-                if (index == 0) {
-                    push(desc);
-                } else {
-                    push(desc.substring(index, desc.length()));
-                }
-                break;
-            // case 'L':
-            default:
-                if (index == 0) {
-                    push(desc.substring(1, desc.length() - 1));
-                } else {
-                    push(desc.substring(index + 1, desc.length() - 1));
-                }
+        case 'V':
+            return;
+        case 'Z':
+        case 'C':
+        case 'B':
+        case 'S':
+        case 'I':
+            push(Opcodes.INTEGER);
+            return;
+        case 'F':
+            push(Opcodes.FLOAT);
+            return;
+        case 'J':
+            push(Opcodes.LONG);
+            push(Opcodes.TOP);
+            return;
+        case 'D':
+            push(Opcodes.DOUBLE);
+            push(Opcodes.TOP);
+            return;
+        case '[':
+            if (index == 0) {
+                push(desc);
+            } else {
+                push(desc.substring(index, desc.length()));
+            }
+            break;
+        // case 'L':
+        default:
+            if (index == 0) {
+                push(desc.substring(1, desc.length() - 1));
+            } else {
+                push(desc.substring(index + 1, desc.length() - 1));
+            }
         }
     }
 
@@ -611,364 +585,364 @@
         }
         Object t1, t2, t3, t4;
         switch (opcode) {
-            case Opcodes.NOP:
-            case Opcodes.INEG:
-            case Opcodes.LNEG:
-            case Opcodes.FNEG:
-            case Opcodes.DNEG:
-            case Opcodes.I2B:
-            case Opcodes.I2C:
-            case Opcodes.I2S:
-            case Opcodes.GOTO:
-            case Opcodes.RETURN:
-                break;
-            case Opcodes.ACONST_NULL:
-                push(Opcodes.NULL);
-                break;
-            case Opcodes.ICONST_M1:
-            case Opcodes.ICONST_0:
-            case Opcodes.ICONST_1:
-            case Opcodes.ICONST_2:
-            case Opcodes.ICONST_3:
-            case Opcodes.ICONST_4:
-            case Opcodes.ICONST_5:
-            case Opcodes.BIPUSH:
-            case Opcodes.SIPUSH:
-                push(Opcodes.INTEGER);
-                break;
-            case Opcodes.LCONST_0:
-            case Opcodes.LCONST_1:
-                push(Opcodes.LONG);
-                push(Opcodes.TOP);
-                break;
-            case Opcodes.FCONST_0:
-            case Opcodes.FCONST_1:
-            case Opcodes.FCONST_2:
-                push(Opcodes.FLOAT);
-                break;
-            case Opcodes.DCONST_0:
-            case Opcodes.DCONST_1:
-                push(Opcodes.DOUBLE);
-                push(Opcodes.TOP);
-                break;
-            case Opcodes.ILOAD:
-            case Opcodes.FLOAD:
-            case Opcodes.ALOAD:
-                push(get(iarg));
-                break;
-            case Opcodes.LLOAD:
-            case Opcodes.DLOAD:
-                push(get(iarg));
-                push(Opcodes.TOP);
-                break;
-            case Opcodes.IALOAD:
-            case Opcodes.BALOAD:
-            case Opcodes.CALOAD:
-            case Opcodes.SALOAD:
-                pop(2);
-                push(Opcodes.INTEGER);
-                break;
-            case Opcodes.LALOAD:
-            case Opcodes.D2L:
-                pop(2);
-                push(Opcodes.LONG);
-                push(Opcodes.TOP);
-                break;
-            case Opcodes.FALOAD:
-                pop(2);
-                push(Opcodes.FLOAT);
-                break;
-            case Opcodes.DALOAD:
-            case Opcodes.L2D:
-                pop(2);
-                push(Opcodes.DOUBLE);
-                push(Opcodes.TOP);
-                break;
-            case Opcodes.AALOAD:
-                pop(1);
-                t1 = pop();
-                if (t1 instanceof String) {
-                    pushDesc(((String) t1).substring(1));
-                } else {
-                    push("java/lang/Object");
+        case Opcodes.NOP:
+        case Opcodes.INEG:
+        case Opcodes.LNEG:
+        case Opcodes.FNEG:
+        case Opcodes.DNEG:
+        case Opcodes.I2B:
+        case Opcodes.I2C:
+        case Opcodes.I2S:
+        case Opcodes.GOTO:
+        case Opcodes.RETURN:
+            break;
+        case Opcodes.ACONST_NULL:
+            push(Opcodes.NULL);
+            break;
+        case Opcodes.ICONST_M1:
+        case Opcodes.ICONST_0:
+        case Opcodes.ICONST_1:
+        case Opcodes.ICONST_2:
+        case Opcodes.ICONST_3:
+        case Opcodes.ICONST_4:
+        case Opcodes.ICONST_5:
+        case Opcodes.BIPUSH:
+        case Opcodes.SIPUSH:
+            push(Opcodes.INTEGER);
+            break;
+        case Opcodes.LCONST_0:
+        case Opcodes.LCONST_1:
+            push(Opcodes.LONG);
+            push(Opcodes.TOP);
+            break;
+        case Opcodes.FCONST_0:
+        case Opcodes.FCONST_1:
+        case Opcodes.FCONST_2:
+            push(Opcodes.FLOAT);
+            break;
+        case Opcodes.DCONST_0:
+        case Opcodes.DCONST_1:
+            push(Opcodes.DOUBLE);
+            push(Opcodes.TOP);
+            break;
+        case Opcodes.ILOAD:
+        case Opcodes.FLOAD:
+        case Opcodes.ALOAD:
+            push(get(iarg));
+            break;
+        case Opcodes.LLOAD:
+        case Opcodes.DLOAD:
+            push(get(iarg));
+            push(Opcodes.TOP);
+            break;
+        case Opcodes.IALOAD:
+        case Opcodes.BALOAD:
+        case Opcodes.CALOAD:
+        case Opcodes.SALOAD:
+            pop(2);
+            push(Opcodes.INTEGER);
+            break;
+        case Opcodes.LALOAD:
+        case Opcodes.D2L:
+            pop(2);
+            push(Opcodes.LONG);
+            push(Opcodes.TOP);
+            break;
+        case Opcodes.FALOAD:
+            pop(2);
+            push(Opcodes.FLOAT);
+            break;
+        case Opcodes.DALOAD:
+        case Opcodes.L2D:
+            pop(2);
+            push(Opcodes.DOUBLE);
+            push(Opcodes.TOP);
+            break;
+        case Opcodes.AALOAD:
+            pop(1);
+            t1 = pop();
+            if (t1 instanceof String) {
+                pushDesc(((String) t1).substring(1));
+            } else {
+                push("java/lang/Object");
+            }
+            break;
+        case Opcodes.ISTORE:
+        case Opcodes.FSTORE:
+        case Opcodes.ASTORE:
+            t1 = pop();
+            set(iarg, t1);
+            if (iarg > 0) {
+                t2 = get(iarg - 1);
+                if (t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE) {
+                    set(iarg - 1, Opcodes.TOP);
                 }
-                break;
-            case Opcodes.ISTORE:
-            case Opcodes.FSTORE:
-            case Opcodes.ASTORE:
-                t1 = pop();
-                set(iarg, t1);
-                if (iarg > 0) {
-                    t2 = get(iarg - 1);
-                    if (t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE) {
-                        set(iarg - 1, Opcodes.TOP);
-                    }
+            }
+            break;
+        case Opcodes.LSTORE:
+        case Opcodes.DSTORE:
+            pop(1);
+            t1 = pop();
+            set(iarg, t1);
+            set(iarg + 1, Opcodes.TOP);
+            if (iarg > 0) {
+                t2 = get(iarg - 1);
+                if (t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE) {
+                    set(iarg - 1, Opcodes.TOP);
                 }
+            }
+            break;
+        case Opcodes.IASTORE:
+        case Opcodes.BASTORE:
+        case Opcodes.CASTORE:
+        case Opcodes.SASTORE:
+        case Opcodes.FASTORE:
+        case Opcodes.AASTORE:
+            pop(3);
+            break;
+        case Opcodes.LASTORE:
+        case Opcodes.DASTORE:
+            pop(4);
+            break;
+        case Opcodes.POP:
+        case Opcodes.IFEQ:
+        case Opcodes.IFNE:
+        case Opcodes.IFLT:
+        case Opcodes.IFGE:
+        case Opcodes.IFGT:
+        case Opcodes.IFLE:
+        case Opcodes.IRETURN:
+        case Opcodes.FRETURN:
+        case Opcodes.ARETURN:
+        case Opcodes.TABLESWITCH:
+        case Opcodes.LOOKUPSWITCH:
+        case Opcodes.ATHROW:
+        case Opcodes.MONITORENTER:
+        case Opcodes.MONITOREXIT:
+        case Opcodes.IFNULL:
+        case Opcodes.IFNONNULL:
+            pop(1);
+            break;
+        case Opcodes.POP2:
+        case Opcodes.IF_ICMPEQ:
+        case Opcodes.IF_ICMPNE:
+        case Opcodes.IF_ICMPLT:
+        case Opcodes.IF_ICMPGE:
+        case Opcodes.IF_ICMPGT:
+        case Opcodes.IF_ICMPLE:
+        case Opcodes.IF_ACMPEQ:
+        case Opcodes.IF_ACMPNE:
+        case Opcodes.LRETURN:
+        case Opcodes.DRETURN:
+            pop(2);
+            break;
+        case Opcodes.DUP:
+            t1 = pop();
+            push(t1);
+            push(t1);
+            break;
+        case Opcodes.DUP_X1:
+            t1 = pop();
+            t2 = pop();
+            push(t1);
+            push(t2);
+            push(t1);
+            break;
+        case Opcodes.DUP_X2:
+            t1 = pop();
+            t2 = pop();
+            t3 = pop();
+            push(t1);
+            push(t3);
+            push(t2);
+            push(t1);
+            break;
+        case Opcodes.DUP2:
+            t1 = pop();
+            t2 = pop();
+            push(t2);
+            push(t1);
+            push(t2);
+            push(t1);
+            break;
+        case Opcodes.DUP2_X1:
+            t1 = pop();
+            t2 = pop();
+            t3 = pop();
+            push(t2);
+            push(t1);
+            push(t3);
+            push(t2);
+            push(t1);
+            break;
+        case Opcodes.DUP2_X2:
+            t1 = pop();
+            t2 = pop();
+            t3 = pop();
+            t4 = pop();
+            push(t2);
+            push(t1);
+            push(t4);
+            push(t3);
+            push(t2);
+            push(t1);
+            break;
+        case Opcodes.SWAP:
+            t1 = pop();
+            t2 = pop();
+            push(t1);
+            push(t2);
+            break;
+        case Opcodes.IADD:
+        case Opcodes.ISUB:
+        case Opcodes.IMUL:
+        case Opcodes.IDIV:
+        case Opcodes.IREM:
+        case Opcodes.IAND:
+        case Opcodes.IOR:
+        case Opcodes.IXOR:
+        case Opcodes.ISHL:
+        case Opcodes.ISHR:
+        case Opcodes.IUSHR:
+        case Opcodes.L2I:
+        case Opcodes.D2I:
+        case Opcodes.FCMPL:
+        case Opcodes.FCMPG:
+            pop(2);
+            push(Opcodes.INTEGER);
+            break;
+        case Opcodes.LADD:
+        case Opcodes.LSUB:
+        case Opcodes.LMUL:
+        case Opcodes.LDIV:
+        case Opcodes.LREM:
+        case Opcodes.LAND:
+        case Opcodes.LOR:
+        case Opcodes.LXOR:
+            pop(4);
+            push(Opcodes.LONG);
+            push(Opcodes.TOP);
+            break;
+        case Opcodes.FADD:
+        case Opcodes.FSUB:
+        case Opcodes.FMUL:
+        case Opcodes.FDIV:
+        case Opcodes.FREM:
+        case Opcodes.L2F:
+        case Opcodes.D2F:
+            pop(2);
+            push(Opcodes.FLOAT);
+            break;
+        case Opcodes.DADD:
+        case Opcodes.DSUB:
+        case Opcodes.DMUL:
+        case Opcodes.DDIV:
+        case Opcodes.DREM:
+            pop(4);
+            push(Opcodes.DOUBLE);
+            push(Opcodes.TOP);
+            break;
+        case Opcodes.LSHL:
+        case Opcodes.LSHR:
+        case Opcodes.LUSHR:
+            pop(3);
+            push(Opcodes.LONG);
+            push(Opcodes.TOP);
+            break;
+        case Opcodes.IINC:
+            set(iarg, Opcodes.INTEGER);
+            break;
+        case Opcodes.I2L:
+        case Opcodes.F2L:
+            pop(1);
+            push(Opcodes.LONG);
+            push(Opcodes.TOP);
+            break;
+        case Opcodes.I2F:
+            pop(1);
+            push(Opcodes.FLOAT);
+            break;
+        case Opcodes.I2D:
+        case Opcodes.F2D:
+            pop(1);
+            push(Opcodes.DOUBLE);
+            push(Opcodes.TOP);
+            break;
+        case Opcodes.F2I:
+        case Opcodes.ARRAYLENGTH:
+        case Opcodes.INSTANCEOF:
+            pop(1);
+            push(Opcodes.INTEGER);
+            break;
+        case Opcodes.LCMP:
+        case Opcodes.DCMPL:
+        case Opcodes.DCMPG:
+            pop(4);
+            push(Opcodes.INTEGER);
+            break;
+        case Opcodes.JSR:
+        case Opcodes.RET:
+            throw new RuntimeException("JSR/RET are not supported");
+        case Opcodes.GETSTATIC:
+            pushDesc(sarg);
+            break;
+        case Opcodes.PUTSTATIC:
+            pop(sarg);
+            break;
+        case Opcodes.GETFIELD:
+            pop(1);
+            pushDesc(sarg);
+            break;
+        case Opcodes.PUTFIELD:
+            pop(sarg);
+            pop();
+            break;
+        case Opcodes.NEW:
+            push(labels.get(0));
+            break;
+        case Opcodes.NEWARRAY:
+            pop();
+            switch (iarg) {
+            case Opcodes.T_BOOLEAN:
+                pushDesc("[Z");
                 break;
-            case Opcodes.LSTORE:
-            case Opcodes.DSTORE:
-                pop(1);
-                t1 = pop();
-                set(iarg, t1);
-                set(iarg + 1, Opcodes.TOP);
-                if (iarg > 0) {
-                    t2 = get(iarg - 1);
-                    if (t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE) {
-                        set(iarg - 1, Opcodes.TOP);
-                    }
-                }
+            case Opcodes.T_CHAR:
+                pushDesc("[C");
                 break;
-            case Opcodes.IASTORE:
-            case Opcodes.BASTORE:
-            case Opcodes.CASTORE:
-            case Opcodes.SASTORE:
-            case Opcodes.FASTORE:
-            case Opcodes.AASTORE:
-                pop(3);
+            case Opcodes.T_BYTE:
+                pushDesc("[B");
                 break;
-            case Opcodes.LASTORE:
-            case Opcodes.DASTORE:
-                pop(4);
+            case Opcodes.T_SHORT:
+                pushDesc("[S");
                 break;
-            case Opcodes.POP:
-            case Opcodes.IFEQ:
-            case Opcodes.IFNE:
-            case Opcodes.IFLT:
-            case Opcodes.IFGE:
-            case Opcodes.IFGT:
-            case Opcodes.IFLE:
-            case Opcodes.IRETURN:
-            case Opcodes.FRETURN:
-            case Opcodes.ARETURN:
-            case Opcodes.TABLESWITCH:
-            case Opcodes.LOOKUPSWITCH:
-            case Opcodes.ATHROW:
-            case Opcodes.MONITORENTER:
-            case Opcodes.MONITOREXIT:
-            case Opcodes.IFNULL:
-            case Opcodes.IFNONNULL:
-                pop(1);
+            case Opcodes.T_INT:
+                pushDesc("[I");
                 break;
-            case Opcodes.POP2:
-            case Opcodes.IF_ICMPEQ:
-            case Opcodes.IF_ICMPNE:
-            case Opcodes.IF_ICMPLT:
-            case Opcodes.IF_ICMPGE:
-            case Opcodes.IF_ICMPGT:
-            case Opcodes.IF_ICMPLE:
-            case Opcodes.IF_ACMPEQ:
-            case Opcodes.IF_ACMPNE:
-            case Opcodes.LRETURN:
-            case Opcodes.DRETURN:
-                pop(2);
+            case Opcodes.T_FLOAT:
+                pushDesc("[F");
                 break;
-            case Opcodes.DUP:
-                t1 = pop();
-                push(t1);
-                push(t1);
+            case Opcodes.T_DOUBLE:
+                pushDesc("[D");
                 break;
-            case Opcodes.DUP_X1:
-                t1 = pop();
-                t2 = pop();
-                push(t1);
-                push(t2);
-                push(t1);
-                break;
-            case Opcodes.DUP_X2:
-                t1 = pop();
-                t2 = pop();
-                t3 = pop();
-                push(t1);
-                push(t3);
-                push(t2);
-                push(t1);
-                break;
-            case Opcodes.DUP2:
-                t1 = pop();
-                t2 = pop();
-                push(t2);
-                push(t1);
-                push(t2);
-                push(t1);
-                break;
-            case Opcodes.DUP2_X1:
-                t1 = pop();
-                t2 = pop();
-                t3 = pop();
-                push(t2);
-                push(t1);
-                push(t3);
-                push(t2);
-                push(t1);
-                break;
-            case Opcodes.DUP2_X2:
-                t1 = pop();
-                t2 = pop();
-                t3 = pop();
-                t4 = pop();
-                push(t2);
-                push(t1);
-                push(t4);
-                push(t3);
-                push(t2);
-                push(t1);
-                break;
-            case Opcodes.SWAP:
-                t1 = pop();
-                t2 = pop();
-                push(t1);
-                push(t2);
-                break;
-            case Opcodes.IADD:
-            case Opcodes.ISUB:
-            case Opcodes.IMUL:
-            case Opcodes.IDIV:
-            case Opcodes.IREM:
-            case Opcodes.IAND:
-            case Opcodes.IOR:
-            case Opcodes.IXOR:
-            case Opcodes.ISHL:
-            case Opcodes.ISHR:
-            case Opcodes.IUSHR:
-            case Opcodes.L2I:
-            case Opcodes.D2I:
-            case Opcodes.FCMPL:
-            case Opcodes.FCMPG:
-                pop(2);
-                push(Opcodes.INTEGER);
-                break;
-            case Opcodes.LADD:
-            case Opcodes.LSUB:
-            case Opcodes.LMUL:
-            case Opcodes.LDIV:
-            case Opcodes.LREM:
-            case Opcodes.LAND:
-            case Opcodes.LOR:
-            case Opcodes.LXOR:
-                pop(4);
-                push(Opcodes.LONG);
-                push(Opcodes.TOP);
-                break;
-            case Opcodes.FADD:
-            case Opcodes.FSUB:
-            case Opcodes.FMUL:
-            case Opcodes.FDIV:
-            case Opcodes.FREM:
-            case Opcodes.L2F:
-            case Opcodes.D2F:
-                pop(2);
-                push(Opcodes.FLOAT);
-                break;
-            case Opcodes.DADD:
-            case Opcodes.DSUB:
-            case Opcodes.DMUL:
-            case Opcodes.DDIV:
-            case Opcodes.DREM:
-                pop(4);
-                push(Opcodes.DOUBLE);
-                push(Opcodes.TOP);
-                break;
-            case Opcodes.LSHL:
-            case Opcodes.LSHR:
-            case Opcodes.LUSHR:
-                pop(3);
-                push(Opcodes.LONG);
-                push(Opcodes.TOP);
-                break;
-            case Opcodes.IINC:
-                set(iarg, Opcodes.INTEGER);
-                break;
-            case Opcodes.I2L:
-            case Opcodes.F2L:
-                pop(1);
-                push(Opcodes.LONG);
-                push(Opcodes.TOP);
-                break;
-            case Opcodes.I2F:
-                pop(1);
-                push(Opcodes.FLOAT);
-                break;
-            case Opcodes.I2D:
-            case Opcodes.F2D:
-                pop(1);
-                push(Opcodes.DOUBLE);
-                push(Opcodes.TOP);
-                break;
-            case Opcodes.F2I:
-            case Opcodes.ARRAYLENGTH:
-            case Opcodes.INSTANCEOF:
-                pop(1);
-                push(Opcodes.INTEGER);
-                break;
-            case Opcodes.LCMP:
-            case Opcodes.DCMPL:
-            case Opcodes.DCMPG:
-                pop(4);
-                push(Opcodes.INTEGER);
-                break;
-            case Opcodes.JSR:
-            case Opcodes.RET:
-                throw new RuntimeException("JSR/RET are not supported");
-            case Opcodes.GETSTATIC:
-                pushDesc(sarg);
-                break;
-            case Opcodes.PUTSTATIC:
-                pop(sarg);
-                break;
-            case Opcodes.GETFIELD:
-                pop(1);
-                pushDesc(sarg);
-                break;
-            case Opcodes.PUTFIELD:
-                pop(sarg);
-                pop();
-                break;
-            case Opcodes.NEW:
-                push(labels.get(0));
-                break;
-            case Opcodes.NEWARRAY:
-                pop();
-                switch (iarg) {
-                    case Opcodes.T_BOOLEAN:
-                        pushDesc("[Z");
-                        break;
-                    case Opcodes.T_CHAR:
-                        pushDesc("[C");
-                        break;
-                    case Opcodes.T_BYTE:
-                        pushDesc("[B");
-                        break;
-                    case Opcodes.T_SHORT:
-                        pushDesc("[S");
-                        break;
-                    case Opcodes.T_INT:
-                        pushDesc("[I");
-                        break;
-                    case Opcodes.T_FLOAT:
-                        pushDesc("[F");
-                        break;
-                    case Opcodes.T_DOUBLE:
-                        pushDesc("[D");
-                        break;
-                    // case Opcodes.T_LONG:
-                    default:
-                        pushDesc("[J");
-                        break;
-                }
-                break;
-            case Opcodes.ANEWARRAY:
-                pop();
-                pushDesc("[" + Type.getObjectType(sarg));
-                break;
-            case Opcodes.CHECKCAST:
-                pop();
-                pushDesc(Type.getObjectType(sarg).getDescriptor());
-                break;
-            // case Opcodes.MULTIANEWARRAY:
+            // case Opcodes.T_LONG:
             default:
-                pop(iarg);
-                pushDesc(sarg);
+                pushDesc("[J");
                 break;
+            }
+            break;
+        case Opcodes.ANEWARRAY:
+            pop();
+            pushDesc("[" + Type.getObjectType(sarg));
+            break;
+        case Opcodes.CHECKCAST:
+            pop();
+            pushDesc(Type.getObjectType(sarg).getDescriptor());
+            break;
+        // case Opcodes.MULTIANEWARRAY:
+        default:
+            pop(iarg);
+            pushDesc(sarg);
+            break;
         }
         labels = null;
     }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java
index 23776dd..a04a643 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java
@@ -75,7 +75,7 @@
     private int maxSize;
 
     public CodeSizeEvaluator(final MethodVisitor mv) {
-        this(Opcodes.ASM4, mv);
+        this(Opcodes.ASM5, mv);
     }
 
     protected CodeSizeEvaluator(final int api, final MethodVisitor mv) {
@@ -140,12 +140,8 @@
     }
 
     @Override
-    public void visitFieldInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitFieldInsn(final int opcode, final String owner,
+            final String name, final String desc) {
         minSize += 3;
         maxSize += 3;
         if (mv != null) {
@@ -154,12 +150,8 @@
     }
 
     @Override
-    public void visitMethodInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitMethodInsn(final int opcode, final String owner,
+            final String name, final String desc) {
         if (opcode == INVOKEINTERFACE) {
             minSize += 5;
             maxSize += 5;
@@ -173,12 +165,8 @@
     }
 
     @Override
-    public void visitInvokeDynamicInsn(
-        String name,
-        String desc,
-        Handle bsm,
-        Object... bsmArgs)
-    {
+    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+            Object... bsmArgs) {
         minSize += 5;
         maxSize += 5;
         if (mv != null) {
@@ -228,12 +216,8 @@
     }
 
     @Override
-    public void visitTableSwitchInsn(
-        final int min,
-        final int max,
-        final Label dflt,
-        final Label... labels)
-    {
+    public void visitTableSwitchInsn(final int min, final int max,
+            final Label dflt, final Label... labels) {
         minSize += 13 + labels.length * 4;
         maxSize += 16 + labels.length * 4;
         if (mv != null) {
@@ -242,11 +226,8 @@
     }
 
     @Override
-    public void visitLookupSwitchInsn(
-        final Label dflt,
-        final int[] keys,
-        final Label[] labels)
-    {
+    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+            final Label[] labels) {
         minSize += 9 + keys.length * 8;
         maxSize += 12 + keys.length * 8;
         if (mv != null) {
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java
index d86c198..7e30acb 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java
@@ -30,7 +30,6 @@
  *
  * ASM: a very small and fast Java bytecode manipulation framework
  * Copyright (c) 2000-2011 INRIA, France Telecom
- * Copyright (c) 2011 Google
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -99,7 +98,8 @@
  * mg = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC, m, null, null, cw);
  * mg.getStatic(Type.getType(System.class), &quot;out&quot;, Type.getType(PrintStream.class));
  * mg.push(&quot;Hello world!&quot;);
- * mg.invokeVirtual(Type.getType(PrintStream.class), Method.getMethod(&quot;void println (String)&quot;));
+ * mg.invokeVirtual(Type.getType(PrintStream.class),
+ *         Method.getMethod(&quot;void println (String)&quot;));
  * mg.returnValue();
  * mg.endMethod();
  *
@@ -117,35 +117,48 @@
 
     private static final Type BYTE_TYPE = Type.getObjectType("java/lang/Byte");
 
-    private static final Type BOOLEAN_TYPE = Type.getObjectType("java/lang/Boolean");
+    private static final Type BOOLEAN_TYPE = Type
+            .getObjectType("java/lang/Boolean");
 
-    private static final Type SHORT_TYPE = Type.getObjectType("java/lang/Short");
+    private static final Type SHORT_TYPE = Type
+            .getObjectType("java/lang/Short");
 
-    private static final Type CHARACTER_TYPE = Type.getObjectType("java/lang/Character");
+    private static final Type CHARACTER_TYPE = Type
+            .getObjectType("java/lang/Character");
 
-    private static final Type INTEGER_TYPE = Type.getObjectType("java/lang/Integer");
+    private static final Type INTEGER_TYPE = Type
+            .getObjectType("java/lang/Integer");
 
-    private static final Type FLOAT_TYPE = Type.getObjectType("java/lang/Float");
+    private static final Type FLOAT_TYPE = Type
+            .getObjectType("java/lang/Float");
 
     private static final Type LONG_TYPE = Type.getObjectType("java/lang/Long");
 
-    private static final Type DOUBLE_TYPE = Type.getObjectType("java/lang/Double");
+    private static final Type DOUBLE_TYPE = Type
+            .getObjectType("java/lang/Double");
 
-    private static final Type NUMBER_TYPE = Type.getObjectType("java/lang/Number");
+    private static final Type NUMBER_TYPE = Type
+            .getObjectType("java/lang/Number");
 
-    private static final Type OBJECT_TYPE = Type.getObjectType("java/lang/Object");
+    private static final Type OBJECT_TYPE = Type
+            .getObjectType("java/lang/Object");
 
-    private static final Method BOOLEAN_VALUE = Method.getMethod("boolean booleanValue()");
+    private static final Method BOOLEAN_VALUE = Method
+            .getMethod("boolean booleanValue()");
 
-    private static final Method CHAR_VALUE = Method.getMethod("char charValue()");
+    private static final Method CHAR_VALUE = Method
+            .getMethod("char charValue()");
 
     private static final Method INT_VALUE = Method.getMethod("int intValue()");
 
-    private static final Method FLOAT_VALUE = Method.getMethod("float floatValue()");
+    private static final Method FLOAT_VALUE = Method
+            .getMethod("float floatValue()");
 
-    private static final Method LONG_VALUE = Method.getMethod("long longValue()");
+    private static final Method LONG_VALUE = Method
+            .getMethod("long longValue()");
 
-    private static final Method DOUBLE_VALUE = Method.getMethod("double doubleValue()");
+    private static final Method DOUBLE_VALUE = Method
+            .getMethod("double doubleValue()");
 
     /**
      * Constant for the {@link #math math} method.
@@ -263,37 +276,37 @@
      * {@link #GeneratorAdapter(int, MethodVisitor, int, String, String)}
      * version.
      *
-     * @param mv the method visitor to which this adapter delegates calls.
-     * @param access the method's access flags (see {@link Opcodes}).
-     * @param name the method's name.
-     * @param desc the method's descriptor (see {@link Type Type}).
+     * @param mv
+     *            the method visitor to which this adapter delegates calls.
+     * @param access
+     *            the method's access flags (see {@link Opcodes}).
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor (see {@link Type Type}).
      */
-    public GeneratorAdapter(
-        final MethodVisitor mv,
-        final int access,
-        final String name,
-        final String desc)
-    {
-        this(Opcodes.ASM4, mv, access, name, desc);
+    public GeneratorAdapter(final MethodVisitor mv, final int access,
+            final String name, final String desc) {
+        this(Opcodes.ASM5, mv, access, name, desc);
     }
 
     /**
      * Creates a new {@link GeneratorAdapter}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
-     * @param mv the method visitor to which this adapter delegates calls.
-     * @param access the method's access flags (see {@link Opcodes}).
-     * @param name the method's name.
-     * @param desc the method's descriptor (see {@link Type Type}).
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param mv
+     *            the method visitor to which this adapter delegates calls.
+     * @param access
+     *            the method's access flags (see {@link Opcodes}).
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor (see {@link Type Type}).
      */
-    protected GeneratorAdapter(
-        final int api,
-        final MethodVisitor mv,
-        final int access,
-        final String name,
-        final String desc)
-    {
+    protected GeneratorAdapter(final int api, final MethodVisitor mv,
+            final int access, final String name, final String desc) {
         super(api, access, desc, mv);
         this.access = access;
         this.returnType = Type.getReturnType(desc);
@@ -306,15 +319,15 @@
      * {@link #GeneratorAdapter(int, MethodVisitor, int, String, String)}
      * version.
      *
-     * @param access access flags of the adapted method.
-     * @param method the adapted method.
-     * @param mv the method visitor to which this adapter delegates calls.
+     * @param access
+     *            access flags of the adapted method.
+     * @param method
+     *            the adapted method.
+     * @param mv
+     *            the method visitor to which this adapter delegates calls.
      */
-    public GeneratorAdapter(
-        final int access,
-        final Method method,
-        final MethodVisitor mv)
-    {
+    public GeneratorAdapter(final int access, final Method method,
+            final MethodVisitor mv) {
         this(mv, access, null, method.getDescriptor());
     }
 
@@ -324,32 +337,31 @@
      * {@link #GeneratorAdapter(int, MethodVisitor, int, String, String)}
      * version.
      *
-     * @param access access flags of the adapted method.
-     * @param method the adapted method.
-     * @param signature the signature of the adapted method (may be
-     *        <tt>null</tt>).
-     * @param exceptions the exceptions thrown by the adapted method (may be
-     *        <tt>null</tt>).
-     * @param cv the class visitor to which this adapter delegates calls.
+     * @param access
+     *            access flags of the adapted method.
+     * @param method
+     *            the adapted method.
+     * @param signature
+     *            the signature of the adapted method (may be <tt>null</tt>).
+     * @param exceptions
+     *            the exceptions thrown by the adapted method (may be
+     *            <tt>null</tt>).
+     * @param cv
+     *            the class visitor to which this adapter delegates calls.
      */
-    public GeneratorAdapter(
-        final int access,
-        final Method method,
-        final String signature,
-        final Type[] exceptions,
-        final ClassVisitor cv)
-    {
-        this(access, method, cv.visitMethod(access,
-                method.getName(),
-                method.getDescriptor(),
-                signature,
-                getInternalNames(exceptions)));
+    public GeneratorAdapter(final int access, final Method method,
+            final String signature, final Type[] exceptions,
+            final ClassVisitor cv) {
+        this(access, method, cv
+                .visitMethod(access, method.getName(), method.getDescriptor(),
+                        signature, getInternalNames(exceptions)));
     }
 
     /**
      * Returns the internal names of the given types.
      *
-     * @param types a set of types.
+     * @param types
+     *            a set of types.
      * @return the internal names of the given types.
      */
     private static String[] getInternalNames(final Type[] types) {
@@ -370,7 +382,8 @@
     /**
      * Generates the instruction to push the given value on the stack.
      *
-     * @param value the value to be pushed on the stack.
+     * @param value
+     *            the value to be pushed on the stack.
      */
     public void push(final boolean value) {
         push(value ? 1 : 0);
@@ -379,7 +392,8 @@
     /**
      * Generates the instruction to push the given value on the stack.
      *
-     * @param value the value to be pushed on the stack.
+     * @param value
+     *            the value to be pushed on the stack.
      */
     public void push(final int value) {
         if (value >= -1 && value <= 5) {
@@ -396,7 +410,8 @@
     /**
      * Generates the instruction to push the given value on the stack.
      *
-     * @param value the value to be pushed on the stack.
+     * @param value
+     *            the value to be pushed on the stack.
      */
     public void push(final long value) {
         if (value == 0L || value == 1L) {
@@ -409,7 +424,8 @@
     /**
      * Generates the instruction to push the given value on the stack.
      *
-     * @param value the value to be pushed on the stack.
+     * @param value
+     *            the value to be pushed on the stack.
      */
     public void push(final float value) {
         int bits = Float.floatToIntBits(value);
@@ -423,7 +439,8 @@
     /**
      * Generates the instruction to push the given value on the stack.
      *
-     * @param value the value to be pushed on the stack.
+     * @param value
+     *            the value to be pushed on the stack.
      */
     public void push(final double value) {
         long bits = Double.doubleToLongBits(value);
@@ -437,7 +454,8 @@
     /**
      * Generates the instruction to push the given value on the stack.
      *
-     * @param value the value to be pushed on the stack. May be <tt>null</tt>.
+     * @param value
+     *            the value to be pushed on the stack. May be <tt>null</tt>.
      */
     public void push(final String value) {
         if (value == null) {
@@ -450,63 +468,48 @@
     /**
      * Generates the instruction to push the given value on the stack.
      *
-     * @param value the value to be pushed on the stack.
+     * @param value
+     *            the value to be pushed on the stack.
      */
     public void push(final Type value) {
         if (value == null) {
             mv.visitInsn(Opcodes.ACONST_NULL);
         } else {
             switch (value.getSort()) {
-                case Type.BOOLEAN:
-                    mv.visitFieldInsn(Opcodes.GETSTATIC,
-                            "java/lang/Boolean",
-                            "TYPE",
-                            CLDESC);
-                    break;
-                case Type.CHAR:
-                    mv.visitFieldInsn(Opcodes.GETSTATIC,
-                            "java/lang/Character",
-                            "TYPE",
-                            CLDESC);
-                    break;
-                case Type.BYTE:
-                    mv.visitFieldInsn(Opcodes.GETSTATIC,
-                            "java/lang/Byte",
-                            "TYPE",
-                            CLDESC);
-                    break;
-                case Type.SHORT:
-                    mv.visitFieldInsn(Opcodes.GETSTATIC,
-                            "java/lang/Short",
-                            "TYPE",
-                            CLDESC);
-                    break;
-                case Type.INT:
-                    mv.visitFieldInsn(Opcodes.GETSTATIC,
-                            "java/lang/Integer",
-                            "TYPE",
-                            CLDESC);
-                    break;
-                case Type.FLOAT:
-                    mv.visitFieldInsn(Opcodes.GETSTATIC,
-                            "java/lang/Float",
-                            "TYPE",
-                            CLDESC);
-                    break;
-                case Type.LONG:
-                    mv.visitFieldInsn(Opcodes.GETSTATIC,
-                            "java/lang/Long",
-                            "TYPE",
-                            CLDESC);
-                    break;
-                case Type.DOUBLE:
-                    mv.visitFieldInsn(Opcodes.GETSTATIC,
-                            "java/lang/Double",
-                            "TYPE",
-                            CLDESC);
-                    break;
-                default:
-                    mv.visitLdcInsn(value);
+            case Type.BOOLEAN:
+                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Boolean",
+                        "TYPE", CLDESC);
+                break;
+            case Type.CHAR:
+                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Character",
+                        "TYPE", CLDESC);
+                break;
+            case Type.BYTE:
+                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Byte", "TYPE",
+                        CLDESC);
+                break;
+            case Type.SHORT:
+                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Short", "TYPE",
+                        CLDESC);
+                break;
+            case Type.INT:
+                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Integer",
+                        "TYPE", CLDESC);
+                break;
+            case Type.FLOAT:
+                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Float", "TYPE",
+                        CLDESC);
+                break;
+            case Type.LONG:
+                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Long", "TYPE",
+                        CLDESC);
+                break;
+            case Type.DOUBLE:
+                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Double",
+                        "TYPE", CLDESC);
+                break;
+            default:
+                mv.visitLdcInsn(value);
             }
         }
     }
@@ -514,7 +517,8 @@
     /**
      * Generates the instruction to push a handle on the stack.
      *
-     * @param handle the handle to be pushed on the stack.
+     * @param handle
+     *            the handle to be pushed on the stack.
      */
     public void push(final Handle handle) {
         mv.visitLdcInsn(handle);
@@ -528,7 +532,8 @@
      * Returns the index of the given method argument in the frame's local
      * variables array.
      *
-     * @param arg the index of a method argument.
+     * @param arg
+     *            the index of a method argument.
      * @return the index of the given method argument in the frame's local
      *         variables array.
      */
@@ -543,8 +548,10 @@
     /**
      * Generates the instruction to push a local variable on the stack.
      *
-     * @param type the type of the local variable to be loaded.
-     * @param index an index in the frame's local variables array.
+     * @param type
+     *            the type of the local variable to be loaded.
+     * @param index
+     *            an index in the frame's local variables array.
      */
     private void loadInsn(final Type type, final int index) {
         mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), index);
@@ -554,8 +561,10 @@
      * Generates the instruction to store the top stack value in a local
      * variable.
      *
-     * @param type the type of the local variable to be stored.
-     * @param index an index in the frame's local variables array.
+     * @param type
+     *            the type of the local variable to be stored.
+     * @param index
+     *            an index in the frame's local variables array.
      */
     private void storeInsn(final Type type, final int index) {
         mv.visitVarInsn(type.getOpcode(Opcodes.ISTORE), index);
@@ -566,7 +575,8 @@
      */
     public void loadThis() {
         if ((access & Opcodes.ACC_STATIC) != 0) {
-            throw new IllegalStateException("no 'this' pointer within static method");
+            throw new IllegalStateException(
+                    "no 'this' pointer within static method");
         }
         mv.visitVarInsn(Opcodes.ALOAD, 0);
     }
@@ -574,7 +584,8 @@
     /**
      * Generates the instruction to load the given method argument on the stack.
      *
-     * @param arg the index of a method argument.
+     * @param arg
+     *            the index of a method argument.
      */
     public void loadArg(final int arg) {
         loadInsn(argumentTypes[arg], getArgIndex(arg));
@@ -584,8 +595,10 @@
      * Generates the instructions to load the given method arguments on the
      * stack.
      *
-     * @param arg the index of the first method argument to be loaded.
-     * @param count the number of method arguments to be loaded.
+     * @param arg
+     *            the index of the first method argument to be loaded.
+     * @param count
+     *            the number of method arguments to be loaded.
      */
     public void loadArgs(final int arg, final int count) {
         int index = getArgIndex(arg);
@@ -623,7 +636,8 @@
      * Generates the instruction to store the top stack value in the given
      * method argument.
      *
-     * @param arg the index of a method argument.
+     * @param arg
+     *            the index of a method argument.
      */
     public void storeArg(final int arg) {
         storeInsn(argumentTypes[arg], getArgIndex(arg));
@@ -636,8 +650,9 @@
     /**
      * Returns the type of the given local variable.
      *
-     * @param local a local variable identifier, as returned by
-     *        {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
+     * @param local
+     *            a local variable identifier, as returned by
+     *            {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
      * @return the type of the given local variable.
      */
     public Type getLocalType(final int local) {
@@ -656,8 +671,9 @@
     /**
      * Generates the instruction to load the given local variable on the stack.
      *
-     * @param local a local variable identifier, as returned by
-     *        {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
+     * @param local
+     *            a local variable identifier, as returned by
+     *            {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
      */
     public void loadLocal(final int local) {
         loadInsn(getLocalType(local), local);
@@ -666,9 +682,11 @@
     /**
      * Generates the instruction to load the given local variable on the stack.
      *
-     * @param local a local variable identifier, as returned by
-     *        {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
-     * @param type the type of this local variable.
+     * @param local
+     *            a local variable identifier, as returned by
+     *            {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
+     * @param type
+     *            the type of this local variable.
      */
     public void loadLocal(final int local, final Type type) {
         setLocalType(local, type);
@@ -679,8 +697,9 @@
      * Generates the instruction to store the top stack value in the given local
      * variable.
      *
-     * @param local a local variable identifier, as returned by
-     *        {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
+     * @param local
+     *            a local variable identifier, as returned by
+     *            {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
      */
     public void storeLocal(final int local) {
         storeInsn(getLocalType(local), local);
@@ -690,9 +709,11 @@
      * Generates the instruction to store the top stack value in the given local
      * variable.
      *
-     * @param local a local variable identifier, as returned by
-     *        {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
-     * @param type the type of this local variable.
+     * @param local
+     *            a local variable identifier, as returned by
+     *            {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
+     * @param type
+     *            the type of this local variable.
      */
     public void storeLocal(final int local, final Type type) {
         setLocalType(local, type);
@@ -702,7 +723,8 @@
     /**
      * Generates the instruction to load an element from an array.
      *
-     * @param type the type of the array element to be loaded.
+     * @param type
+     *            the type of the array element to be loaded.
      */
     public void arrayLoad(final Type type) {
         mv.visitInsn(type.getOpcode(Opcodes.IALOAD));
@@ -711,7 +733,8 @@
     /**
      * Generates the instruction to store an element in an array.
      *
-     * @param type the type of the array element to be stored.
+     * @param type
+     *            the type of the array element to be stored.
      */
     public void arrayStore(final Type type) {
         mv.visitInsn(type.getOpcode(Opcodes.IASTORE));
@@ -787,8 +810,10 @@
     /**
      * Generates the instructions to swap the top two stack values.
      *
-     * @param prev type of the top - 1 stack value.
-     * @param type type of the top stack value.
+     * @param prev
+     *            type of the top - 1 stack value.
+     * @param type
+     *            type of the top stack value.
      */
     public void swap(final Type prev, final Type type) {
         if (type.getSize() == 1) {
@@ -817,9 +842,11 @@
      * Generates the instruction to do the specified mathematical or logical
      * operation.
      *
-     * @param op a mathematical or logical operation. Must be one of ADD, SUB,
-     *        MUL, DIV, REM, NEG, SHL, SHR, USHR, AND, OR, XOR.
-     * @param type the type of the operand(s) for this operation.
+     * @param op
+     *            a mathematical or logical operation. Must be one of ADD, SUB,
+     *            MUL, DIV, REM, NEG, SHL, SHR, USHR, AND, OR, XOR.
+     * @param type
+     *            the type of the operand(s) for this operation.
      */
     public void math(final int op, final Type type) {
         mv.visitInsn(type.getOpcode(op));
@@ -837,8 +864,10 @@
     /**
      * Generates the instruction to increment the given local variable.
      *
-     * @param local the local variable to be incremented.
-     * @param amount the amount by which the local variable must be incremented.
+     * @param local
+     *            the local variable to be incremented.
+     * @param amount
+     *            the amount by which the local variable must be incremented.
      */
     public void iinc(final int local, final int amount) {
         mv.visitIincInsn(local, amount);
@@ -848,8 +877,10 @@
      * Generates the instructions to cast a numerical value from one type to
      * another.
      *
-     * @param from the type of the top stack value
-     * @param to the type into which this value must be cast.
+     * @param from
+     *            the type of the top stack value
+     * @param to
+     *            the type into which this value must be cast.
      */
     public void cast(final Type from, final Type to) {
         if (from != to) {
@@ -904,22 +935,22 @@
 
     private static Type getBoxedType(final Type type) {
         switch (type.getSort()) {
-            case Type.BYTE:
-                return BYTE_TYPE;
-            case Type.BOOLEAN:
-                return BOOLEAN_TYPE;
-            case Type.SHORT:
-                return SHORT_TYPE;
-            case Type.CHAR:
-                return CHARACTER_TYPE;
-            case Type.INT:
-                return INTEGER_TYPE;
-            case Type.FLOAT:
-                return FLOAT_TYPE;
-            case Type.LONG:
-                return LONG_TYPE;
-            case Type.DOUBLE:
-                return DOUBLE_TYPE;
+        case Type.BYTE:
+            return BYTE_TYPE;
+        case Type.BOOLEAN:
+            return BOOLEAN_TYPE;
+        case Type.SHORT:
+            return SHORT_TYPE;
+        case Type.CHAR:
+            return CHARACTER_TYPE;
+        case Type.INT:
+            return INTEGER_TYPE;
+        case Type.FLOAT:
+            return FLOAT_TYPE;
+        case Type.LONG:
+            return LONG_TYPE;
+        case Type.DOUBLE:
+            return DOUBLE_TYPE;
         }
         return type;
     }
@@ -928,7 +959,8 @@
      * Generates the instructions to box the top stack value. This value is
      * replaced by its boxed equivalent on top of the stack.
      *
-     * @param type the type of the top stack value.
+     * @param type
+     *            the type of the top stack value.
      */
     public void box(final Type type) {
         if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
@@ -949,8 +981,7 @@
                 dupX1();
                 swap();
             }
-            invokeConstructor(boxed, new Method("<init>",
-                    Type.VOID_TYPE,
+            invokeConstructor(boxed, new Method("<init>", Type.VOID_TYPE,
                     new Type[] { type }));
         }
     }
@@ -960,7 +991,8 @@
      * valueOf() method. This value is replaced by its boxed equivalent on top
      * of the stack.
      *
-     * @param type the type of the top stack value.
+     * @param type
+     *            the type of the top stack value.
      */
     public void valueOf(final Type type) {
         if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
@@ -970,8 +1002,7 @@
             push((String) null);
         } else {
             Type boxed = getBoxedType(type);
-            invokeStatic(boxed, new Method("valueOf",
-                    boxed,
+            invokeStatic(boxed, new Method("valueOf", boxed,
                     new Type[] { type }));
         }
     }
@@ -980,35 +1011,36 @@
      * Generates the instructions to unbox the top stack value. This value is
      * replaced by its unboxed equivalent on top of the stack.
      *
-     * @param type the type of the top stack value.
+     * @param type
+     *            the type of the top stack value.
      */
     public void unbox(final Type type) {
         Type t = NUMBER_TYPE;
         Method sig = null;
         switch (type.getSort()) {
-            case Type.VOID:
-                return;
-            case Type.CHAR:
-                t = CHARACTER_TYPE;
-                sig = CHAR_VALUE;
-                break;
-            case Type.BOOLEAN:
-                t = BOOLEAN_TYPE;
-                sig = BOOLEAN_VALUE;
-                break;
-            case Type.DOUBLE:
-                sig = DOUBLE_VALUE;
-                break;
-            case Type.FLOAT:
-                sig = FLOAT_VALUE;
-                break;
-            case Type.LONG:
-                sig = LONG_VALUE;
-                break;
-            case Type.INT:
-            case Type.SHORT:
-            case Type.BYTE:
-                sig = INT_VALUE;
+        case Type.VOID:
+            return;
+        case Type.CHAR:
+            t = CHARACTER_TYPE;
+            sig = CHAR_VALUE;
+            break;
+        case Type.BOOLEAN:
+            t = BOOLEAN_TYPE;
+            sig = BOOLEAN_VALUE;
+            break;
+        case Type.DOUBLE:
+            sig = DOUBLE_VALUE;
+            break;
+        case Type.FLOAT:
+            sig = FLOAT_VALUE;
+            break;
+        case Type.LONG:
+            sig = LONG_VALUE;
+            break;
+        case Type.INT:
+        case Type.SHORT:
+        case Type.BYTE:
+            sig = INT_VALUE;
         }
         if (sig == null) {
             checkCast(type);
@@ -1034,7 +1066,8 @@
     /**
      * Marks the current code position with the given label.
      *
-     * @param label a label.
+     * @param label
+     *            a label.
      */
     public void mark(final Label label) {
         mv.visitLabel(label);
@@ -1055,58 +1088,63 @@
      * Generates the instructions to jump to a label based on the comparison of
      * the top two stack values.
      *
-     * @param type the type of the top two stack values.
-     * @param mode how these values must be compared. One of EQ, NE, LT, GE, GT,
-     *        LE.
-     * @param label where to jump if the comparison result is <tt>true</tt>.
+     * @param type
+     *            the type of the top two stack values.
+     * @param mode
+     *            how these values must be compared. One of EQ, NE, LT, GE, GT,
+     *            LE.
+     * @param label
+     *            where to jump if the comparison result is <tt>true</tt>.
      */
     public void ifCmp(final Type type, final int mode, final Label label) {
         switch (type.getSort()) {
-            case Type.LONG:
-                mv.visitInsn(Opcodes.LCMP);
-                break;
-            case Type.DOUBLE:
-                mv.visitInsn(mode == GE || mode == GT ? Opcodes.DCMPG : Opcodes.DCMPL);
-                break;
-            case Type.FLOAT:
-                mv.visitInsn(mode == GE || mode == GT ? Opcodes.FCMPG : Opcodes.FCMPL);
-                break;
-            case Type.ARRAY:
-            case Type.OBJECT:
-                switch (mode) {
-                    case EQ:
-                        mv.visitJumpInsn(Opcodes.IF_ACMPEQ, label);
-                        return;
-                    case NE:
-                        mv.visitJumpInsn(Opcodes.IF_ACMPNE, label);
-                        return;
-                }
-                throw new IllegalArgumentException("Bad comparison for type "
-                        + type);
-            default:
-                int intOp = -1;
-                switch (mode) {
-                    case EQ:
-                        intOp = Opcodes.IF_ICMPEQ;
-                        break;
-                    case NE:
-                        intOp = Opcodes.IF_ICMPNE;
-                        break;
-                    case GE:
-                        intOp = Opcodes.IF_ICMPGE;
-                        break;
-                    case LT:
-                        intOp = Opcodes.IF_ICMPLT;
-                        break;
-                    case LE:
-                        intOp = Opcodes.IF_ICMPLE;
-                        break;
-                    case GT:
-                        intOp = Opcodes.IF_ICMPGT;
-                        break;
-                }
-                mv.visitJumpInsn(intOp, label);
+        case Type.LONG:
+            mv.visitInsn(Opcodes.LCMP);
+            break;
+        case Type.DOUBLE:
+            mv.visitInsn(mode == GE || mode == GT ? Opcodes.DCMPL
+                    : Opcodes.DCMPG);
+            break;
+        case Type.FLOAT:
+            mv.visitInsn(mode == GE || mode == GT ? Opcodes.FCMPL
+                    : Opcodes.FCMPG);
+            break;
+        case Type.ARRAY:
+        case Type.OBJECT:
+            switch (mode) {
+            case EQ:
+                mv.visitJumpInsn(Opcodes.IF_ACMPEQ, label);
                 return;
+            case NE:
+                mv.visitJumpInsn(Opcodes.IF_ACMPNE, label);
+                return;
+            }
+            throw new IllegalArgumentException("Bad comparison for type "
+                    + type);
+        default:
+            int intOp = -1;
+            switch (mode) {
+            case EQ:
+                intOp = Opcodes.IF_ICMPEQ;
+                break;
+            case NE:
+                intOp = Opcodes.IF_ICMPNE;
+                break;
+            case GE:
+                intOp = Opcodes.IF_ICMPGE;
+                break;
+            case LT:
+                intOp = Opcodes.IF_ICMPLT;
+                break;
+            case LE:
+                intOp = Opcodes.IF_ICMPLE;
+                break;
+            case GT:
+                intOp = Opcodes.IF_ICMPGT;
+                break;
+            }
+            mv.visitJumpInsn(intOp, label);
+            return;
         }
         mv.visitJumpInsn(mode, label);
     }
@@ -1115,9 +1153,11 @@
      * Generates the instructions to jump to a label based on the comparison of
      * the top two integer stack values.
      *
-     * @param mode how these values must be compared. One of EQ, NE, LT, GE, GT,
-     *        LE.
-     * @param label where to jump if the comparison result is <tt>true</tt>.
+     * @param mode
+     *            how these values must be compared. One of EQ, NE, LT, GE, GT,
+     *            LE.
+     * @param label
+     *            where to jump if the comparison result is <tt>true</tt>.
      */
     public void ifICmp(final int mode, final Label label) {
         ifCmp(Type.INT_TYPE, mode, label);
@@ -1127,9 +1167,11 @@
      * Generates the instructions to jump to a label based on the comparison of
      * the top integer stack value with zero.
      *
-     * @param mode how these values must be compared. One of EQ, NE, LT, GE, GT,
-     *        LE.
-     * @param label where to jump if the comparison result is <tt>true</tt>.
+     * @param mode
+     *            how these values must be compared. One of EQ, NE, LT, GE, GT,
+     *            LE.
+     * @param label
+     *            where to jump if the comparison result is <tt>true</tt>.
      */
     public void ifZCmp(final int mode, final Label label) {
         mv.visitJumpInsn(mode, label);
@@ -1139,7 +1181,8 @@
      * Generates the instruction to jump to the given label if the top stack
      * value is null.
      *
-     * @param label where to jump if the condition is <tt>true</tt>.
+     * @param label
+     *            where to jump if the condition is <tt>true</tt>.
      */
     public void ifNull(final Label label) {
         mv.visitJumpInsn(Opcodes.IFNULL, label);
@@ -1149,7 +1192,8 @@
      * Generates the instruction to jump to the given label if the top stack
      * value is not null.
      *
-     * @param label where to jump if the condition is <tt>true</tt>.
+     * @param label
+     *            where to jump if the condition is <tt>true</tt>.
      */
     public void ifNonNull(final Label label) {
         mv.visitJumpInsn(Opcodes.IFNONNULL, label);
@@ -1158,7 +1202,8 @@
     /**
      * Generates the instruction to jump to the given label.
      *
-     * @param label where to jump if the condition is <tt>true</tt>.
+     * @param label
+     *            where to jump if the condition is <tt>true</tt>.
      */
     public void goTo(final Label label) {
         mv.visitJumpInsn(Opcodes.GOTO, label);
@@ -1167,8 +1212,9 @@
     /**
      * Generates a RET instruction.
      *
-     * @param local a local variable identifier, as returned by
-     *        {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
+     * @param local
+     *            a local variable identifier, as returned by
+     *            {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
      */
     public void ret(final int local) {
         mv.visitVarInsn(Opcodes.RET, local);
@@ -1177,13 +1223,13 @@
     /**
      * Generates the instructions for a switch statement.
      *
-     * @param keys the switch case keys.
-     * @param generator a generator to generate the code for the switch cases.
+     * @param keys
+     *            the switch case keys.
+     * @param generator
+     *            a generator to generate the code for the switch cases.
      */
-    public void tableSwitch(
-        final int[] keys,
-        final TableSwitchGenerator generator)
-    {
+    public void tableSwitch(final int[] keys,
+            final TableSwitchGenerator generator) {
         float density;
         if (keys.length == 0) {
             density = 0;
@@ -1197,19 +1243,20 @@
     /**
      * Generates the instructions for a switch statement.
      *
-     * @param keys the switch case keys.
-     * @param generator a generator to generate the code for the switch cases.
-     * @param useTable <tt>true</tt> to use a TABLESWITCH instruction, or
-     *        <tt>false</tt> to use a LOOKUPSWITCH instruction.
+     * @param keys
+     *            the switch case keys.
+     * @param generator
+     *            a generator to generate the code for the switch cases.
+     * @param useTable
+     *            <tt>true</tt> to use a TABLESWITCH instruction, or
+     *            <tt>false</tt> to use a LOOKUPSWITCH instruction.
      */
-    public void tableSwitch(
-        final int[] keys,
-        final TableSwitchGenerator generator,
-        final boolean useTable)
-    {
+    public void tableSwitch(final int[] keys,
+            final TableSwitchGenerator generator, final boolean useTable) {
         for (int i = 1; i < keys.length; ++i) {
             if (keys[i] < keys[i - 1]) {
-                throw new IllegalArgumentException("keys must be sorted ascending");
+                throw new IllegalArgumentException(
+                        "keys must be sorted ascending");
             }
         }
         Label def = newLabel();
@@ -1264,20 +1311,18 @@
     /**
      * Generates a get field or set field instruction.
      *
-     * @param opcode the instruction's opcode.
-     * @param ownerType the class in which the field is defined.
-     * @param name the name of the field.
-     * @param fieldType the type of the field.
+     * @param opcode
+     *            the instruction's opcode.
+     * @param ownerType
+     *            the class in which the field is defined.
+     * @param name
+     *            the name of the field.
+     * @param fieldType
+     *            the type of the field.
      */
-    private void fieldInsn(
-        final int opcode,
-        final Type ownerType,
-        final String name,
-        final Type fieldType)
-    {
-        mv.visitFieldInsn(opcode,
-                ownerType.getInternalName(),
-                name,
+    private void fieldInsn(final int opcode, final Type ownerType,
+            final String name, final Type fieldType) {
+        mv.visitFieldInsn(opcode, ownerType.getInternalName(), name,
                 fieldType.getDescriptor());
     }
 
@@ -1285,24 +1330,28 @@
      * Generates the instruction to push the value of a static field on the
      * stack.
      *
-     * @param owner the class in which the field is defined.
-     * @param name the name of the field.
-     * @param type the type of the field.
+     * @param owner
+     *            the class in which the field is defined.
+     * @param name
+     *            the name of the field.
+     * @param type
+     *            the type of the field.
      */
-    public void getStatic(final Type owner, final String name, final Type type)
-    {
+    public void getStatic(final Type owner, final String name, final Type type) {
         fieldInsn(Opcodes.GETSTATIC, owner, name, type);
     }
 
     /**
      * Generates the instruction to store the top stack value in a static field.
      *
-     * @param owner the class in which the field is defined.
-     * @param name the name of the field.
-     * @param type the type of the field.
+     * @param owner
+     *            the class in which the field is defined.
+     * @param name
+     *            the name of the field.
+     * @param type
+     *            the type of the field.
      */
-    public void putStatic(final Type owner, final String name, final Type type)
-    {
+    public void putStatic(final Type owner, final String name, final Type type) {
         fieldInsn(Opcodes.PUTSTATIC, owner, name, type);
     }
 
@@ -1310,9 +1359,12 @@
      * Generates the instruction to push the value of a non static field on the
      * stack.
      *
-     * @param owner the class in which the field is defined.
-     * @param name the name of the field.
-     * @param type the type of the field.
+     * @param owner
+     *            the class in which the field is defined.
+     * @param name
+     *            the name of the field.
+     * @param type
+     *            the type of the field.
      */
     public void getField(final Type owner, final String name, final Type type) {
         fieldInsn(Opcodes.GETFIELD, owner, name, type);
@@ -1322,9 +1374,12 @@
      * Generates the instruction to store the top stack value in a non static
      * field.
      *
-     * @param owner the class in which the field is defined.
-     * @param name the name of the field.
-     * @param type the type of the field.
+     * @param owner
+     *            the class in which the field is defined.
+     * @param name
+     *            the name of the field.
+     * @param type
+     *            the type of the field.
      */
     public void putField(final Type owner, final String name, final Type type) {
         fieldInsn(Opcodes.PUTFIELD, owner, name, type);
@@ -1337,29 +1392,28 @@
     /**
      * Generates an invoke method instruction.
      *
-     * @param opcode the instruction's opcode.
-     * @param type the class in which the method is defined.
-     * @param method the method to be invoked.
+     * @param opcode
+     *            the instruction's opcode.
+     * @param type
+     *            the class in which the method is defined.
+     * @param method
+     *            the method to be invoked.
      */
-    private void invokeInsn(
-        final int opcode,
-        final Type type,
-        final Method method)
-    {
-        String owner = type.getSort() == Type.ARRAY
-                ? type.getDescriptor()
+    private void invokeInsn(final int opcode, final Type type,
+            final Method method) {
+        String owner = type.getSort() == Type.ARRAY ? type.getDescriptor()
                 : type.getInternalName();
-        mv.visitMethodInsn(opcode,
-                owner,
-                method.getName(),
+        mv.visitMethodInsn(opcode, owner, method.getName(),
                 method.getDescriptor());
     }
 
     /**
      * Generates the instruction to invoke a normal method.
      *
-     * @param owner the class in which the method is defined.
-     * @param method the method to be invoked.
+     * @param owner
+     *            the class in which the method is defined.
+     * @param method
+     *            the method to be invoked.
      */
     public void invokeVirtual(final Type owner, final Method method) {
         invokeInsn(Opcodes.INVOKEVIRTUAL, owner, method);
@@ -1368,8 +1422,10 @@
     /**
      * Generates the instruction to invoke a constructor.
      *
-     * @param type the class in which the constructor is defined.
-     * @param method the constructor to be invoked.
+     * @param type
+     *            the class in which the constructor is defined.
+     * @param method
+     *            the constructor to be invoked.
      */
     public void invokeConstructor(final Type type, final Method method) {
         invokeInsn(Opcodes.INVOKESPECIAL, type, method);
@@ -1378,8 +1434,10 @@
     /**
      * Generates the instruction to invoke a static method.
      *
-     * @param owner the class in which the method is defined.
-     * @param method the method to be invoked.
+     * @param owner
+     *            the class in which the method is defined.
+     * @param method
+     *            the method to be invoked.
      */
     public void invokeStatic(final Type owner, final Method method) {
         invokeInsn(Opcodes.INVOKESTATIC, owner, method);
@@ -1388,8 +1446,10 @@
     /**
      * Generates the instruction to invoke an interface method.
      *
-     * @param owner the class in which the method is defined.
-     * @param method the method to be invoked.
+     * @param owner
+     *            the class in which the method is defined.
+     * @param method
+     *            the method to be invoked.
      */
     public void invokeInterface(final Type owner, final Method method) {
         invokeInsn(Opcodes.INVOKEINTERFACE, owner, method);
@@ -1398,16 +1458,21 @@
     /**
      * Generates an invokedynamic instruction.
      *
-     * @param name the method's name.
-     * @param desc the method's descriptor (see {@link Type Type}).
-     * @param bsm the bootstrap method.
-     * @param bsmArgs the bootstrap method constant arguments. Each argument
-     *        must be an {@link Integer}, {@link Float}, {@link Long},
-     *        {@link Double}, {@link String}, {@link Type} or {@link Handle}
-     *        value. This method is allowed to modify the content of the array
-     *        so a caller should expect that this array may change.
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor (see {@link Type Type}).
+     * @param bsm
+     *            the bootstrap method.
+     * @param bsmArgs
+     *            the bootstrap method constant arguments. Each argument must be
+     *            an {@link Integer}, {@link Float}, {@link Long},
+     *            {@link Double}, {@link String}, {@link Type} or {@link Handle}
+     *            value. This method is allowed to modify the content of the
+     *            array so a caller should expect that this array may change.
      */
-    public void invokeDynamic(String name, String desc, Handle bsm, Object... bsmArgs) {
+    public void invokeDynamic(String name, String desc, Handle bsm,
+            Object... bsmArgs) {
         mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
     }
 
@@ -1418,8 +1483,10 @@
     /**
      * Generates a type dependent instruction.
      *
-     * @param opcode the instruction's opcode.
-     * @param type the instruction's operand.
+     * @param opcode
+     *            the instruction's opcode.
+     * @param type
+     *            the instruction's operand.
      */
     private void typeInsn(final int opcode, final Type type) {
         mv.visitTypeInsn(opcode, type.getInternalName());
@@ -1428,7 +1495,8 @@
     /**
      * Generates the instruction to create a new object.
      *
-     * @param type the class of the object to be created.
+     * @param type
+     *            the class of the object to be created.
      */
     public void newInstance(final Type type) {
         typeInsn(Opcodes.NEW, type);
@@ -1437,38 +1505,39 @@
     /**
      * Generates the instruction to create a new array.
      *
-     * @param type the type of the array elements.
+     * @param type
+     *            the type of the array elements.
      */
     public void newArray(final Type type) {
         int typ;
         switch (type.getSort()) {
-            case Type.BOOLEAN:
-                typ = Opcodes.T_BOOLEAN;
-                break;
-            case Type.CHAR:
-                typ = Opcodes.T_CHAR;
-                break;
-            case Type.BYTE:
-                typ = Opcodes.T_BYTE;
-                break;
-            case Type.SHORT:
-                typ = Opcodes.T_SHORT;
-                break;
-            case Type.INT:
-                typ = Opcodes.T_INT;
-                break;
-            case Type.FLOAT:
-                typ = Opcodes.T_FLOAT;
-                break;
-            case Type.LONG:
-                typ = Opcodes.T_LONG;
-                break;
-            case Type.DOUBLE:
-                typ = Opcodes.T_DOUBLE;
-                break;
-            default:
-                typeInsn(Opcodes.ANEWARRAY, type);
-                return;
+        case Type.BOOLEAN:
+            typ = Opcodes.T_BOOLEAN;
+            break;
+        case Type.CHAR:
+            typ = Opcodes.T_CHAR;
+            break;
+        case Type.BYTE:
+            typ = Opcodes.T_BYTE;
+            break;
+        case Type.SHORT:
+            typ = Opcodes.T_SHORT;
+            break;
+        case Type.INT:
+            typ = Opcodes.T_INT;
+            break;
+        case Type.FLOAT:
+            typ = Opcodes.T_FLOAT;
+            break;
+        case Type.LONG:
+            typ = Opcodes.T_LONG;
+            break;
+        case Type.DOUBLE:
+            typ = Opcodes.T_DOUBLE;
+            break;
+        default:
+            typeInsn(Opcodes.ANEWARRAY, type);
+            return;
         }
         mv.visitIntInsn(Opcodes.NEWARRAY, typ);
     }
@@ -1495,8 +1564,10 @@
      * Generates the instructions to create and throw an exception. The
      * exception class must have a constructor with a single String argument.
      *
-     * @param type the class of the exception to be thrown.
-     * @param msg the detailed message of the exception.
+     * @param type
+     *            the class of the exception to be thrown.
+     * @param msg
+     *            the detailed message of the exception.
      */
     public void throwException(final Type type, final String msg) {
         newInstance(type);
@@ -1510,7 +1581,8 @@
      * Generates the instruction to check that the top stack value is of the
      * given type.
      *
-     * @param type a class or interface type.
+     * @param type
+     *            a class or interface type.
      */
     public void checkCast(final Type type) {
         if (!type.equals(OBJECT_TYPE)) {
@@ -1522,7 +1594,8 @@
      * Generates the instruction to test if the top stack value is of the given
      * type.
      *
-     * @param type a class or interface type.
+     * @param type
+     *            a class or interface type.
      */
     public void instanceOf(final Type type) {
         typeInsn(Opcodes.INSTANCEOF, type);
@@ -1559,20 +1632,21 @@
     /**
      * Marks the start of an exception handler.
      *
-     * @param start beginning of the exception handler's scope (inclusive).
-     * @param end end of the exception handler's scope (exclusive).
-     * @param exception internal name of the type of exceptions handled by the
-     *        handler.
+     * @param start
+     *            beginning of the exception handler's scope (inclusive).
+     * @param end
+     *            end of the exception handler's scope (exclusive).
+     * @param exception
+     *            internal name of the type of exceptions handled by the
+     *            handler.
      */
-    public void catchException(
-        final Label start,
-        final Label end,
-        final Type exception)
-    {
+    public void catchException(final Label start, final Label end,
+            final Type exception) {
         if (exception == null) {
             mv.visitTryCatchBlock(start, end, mark(), null);
         } else {
-            mv.visitTryCatchBlock(start, end, mark(), exception.getInternalName());
+            mv.visitTryCatchBlock(start, end, mark(),
+                    exception.getInternalName());
         }
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java
index e563b23..912b622 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java
@@ -80,18 +80,21 @@
      * constructor</i>. Instead, they must use the
      * {@link #InstructionAdapter(int, MethodVisitor)} version.
      *
-     * @param mv the method visitor to which this adapter delegates calls.
+     * @param mv
+     *            the method visitor to which this adapter delegates calls.
      */
     public InstructionAdapter(final MethodVisitor mv) {
-        this(Opcodes.ASM4, mv);
+        this(Opcodes.ASM5, mv);
     }
 
     /**
      * Creates a new {@link InstructionAdapter}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
-     * @param mv the method visitor to which this adapter delegates calls.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param mv
+     *            the method visitor to which this adapter delegates calls.
      */
     protected InstructionAdapter(final int api, final MethodVisitor mv) {
         super(api, mv);
@@ -100,394 +103,394 @@
     @Override
     public void visitInsn(final int opcode) {
         switch (opcode) {
-            case Opcodes.NOP:
-                nop();
-                break;
-            case Opcodes.ACONST_NULL:
-                aconst(null);
-                break;
-            case Opcodes.ICONST_M1:
-            case Opcodes.ICONST_0:
-            case Opcodes.ICONST_1:
-            case Opcodes.ICONST_2:
-            case Opcodes.ICONST_3:
-            case Opcodes.ICONST_4:
-            case Opcodes.ICONST_5:
-                iconst(opcode - Opcodes.ICONST_0);
-                break;
-            case Opcodes.LCONST_0:
-            case Opcodes.LCONST_1:
-                lconst(opcode - Opcodes.LCONST_0);
-                break;
-            case Opcodes.FCONST_0:
-            case Opcodes.FCONST_1:
-            case Opcodes.FCONST_2:
-                fconst(opcode - Opcodes.FCONST_0);
-                break;
-            case Opcodes.DCONST_0:
-            case Opcodes.DCONST_1:
-                dconst(opcode - Opcodes.DCONST_0);
-                break;
-            case Opcodes.IALOAD:
-                aload(Type.INT_TYPE);
-                break;
-            case Opcodes.LALOAD:
-                aload(Type.LONG_TYPE);
-                break;
-            case Opcodes.FALOAD:
-                aload(Type.FLOAT_TYPE);
-                break;
-            case Opcodes.DALOAD:
-                aload(Type.DOUBLE_TYPE);
-                break;
-            case Opcodes.AALOAD:
-                aload(OBJECT_TYPE);
-                break;
-            case Opcodes.BALOAD:
-                aload(Type.BYTE_TYPE);
-                break;
-            case Opcodes.CALOAD:
-                aload(Type.CHAR_TYPE);
-                break;
-            case Opcodes.SALOAD:
-                aload(Type.SHORT_TYPE);
-                break;
-            case Opcodes.IASTORE:
-                astore(Type.INT_TYPE);
-                break;
-            case Opcodes.LASTORE:
-                astore(Type.LONG_TYPE);
-                break;
-            case Opcodes.FASTORE:
-                astore(Type.FLOAT_TYPE);
-                break;
-            case Opcodes.DASTORE:
-                astore(Type.DOUBLE_TYPE);
-                break;
-            case Opcodes.AASTORE:
-                astore(OBJECT_TYPE);
-                break;
-            case Opcodes.BASTORE:
-                astore(Type.BYTE_TYPE);
-                break;
-            case Opcodes.CASTORE:
-                astore(Type.CHAR_TYPE);
-                break;
-            case Opcodes.SASTORE:
-                astore(Type.SHORT_TYPE);
-                break;
-            case Opcodes.POP:
-                pop();
-                break;
-            case Opcodes.POP2:
-                pop2();
-                break;
-            case Opcodes.DUP:
-                dup();
-                break;
-            case Opcodes.DUP_X1:
-                dupX1();
-                break;
-            case Opcodes.DUP_X2:
-                dupX2();
-                break;
-            case Opcodes.DUP2:
-                dup2();
-                break;
-            case Opcodes.DUP2_X1:
-                dup2X1();
-                break;
-            case Opcodes.DUP2_X2:
-                dup2X2();
-                break;
-            case Opcodes.SWAP:
-                swap();
-                break;
-            case Opcodes.IADD:
-                add(Type.INT_TYPE);
-                break;
-            case Opcodes.LADD:
-                add(Type.LONG_TYPE);
-                break;
-            case Opcodes.FADD:
-                add(Type.FLOAT_TYPE);
-                break;
-            case Opcodes.DADD:
-                add(Type.DOUBLE_TYPE);
-                break;
-            case Opcodes.ISUB:
-                sub(Type.INT_TYPE);
-                break;
-            case Opcodes.LSUB:
-                sub(Type.LONG_TYPE);
-                break;
-            case Opcodes.FSUB:
-                sub(Type.FLOAT_TYPE);
-                break;
-            case Opcodes.DSUB:
-                sub(Type.DOUBLE_TYPE);
-                break;
-            case Opcodes.IMUL:
-                mul(Type.INT_TYPE);
-                break;
-            case Opcodes.LMUL:
-                mul(Type.LONG_TYPE);
-                break;
-            case Opcodes.FMUL:
-                mul(Type.FLOAT_TYPE);
-                break;
-            case Opcodes.DMUL:
-                mul(Type.DOUBLE_TYPE);
-                break;
-            case Opcodes.IDIV:
-                div(Type.INT_TYPE);
-                break;
-            case Opcodes.LDIV:
-                div(Type.LONG_TYPE);
-                break;
-            case Opcodes.FDIV:
-                div(Type.FLOAT_TYPE);
-                break;
-            case Opcodes.DDIV:
-                div(Type.DOUBLE_TYPE);
-                break;
-            case Opcodes.IREM:
-                rem(Type.INT_TYPE);
-                break;
-            case Opcodes.LREM:
-                rem(Type.LONG_TYPE);
-                break;
-            case Opcodes.FREM:
-                rem(Type.FLOAT_TYPE);
-                break;
-            case Opcodes.DREM:
-                rem(Type.DOUBLE_TYPE);
-                break;
-            case Opcodes.INEG:
-                neg(Type.INT_TYPE);
-                break;
-            case Opcodes.LNEG:
-                neg(Type.LONG_TYPE);
-                break;
-            case Opcodes.FNEG:
-                neg(Type.FLOAT_TYPE);
-                break;
-            case Opcodes.DNEG:
-                neg(Type.DOUBLE_TYPE);
-                break;
-            case Opcodes.ISHL:
-                shl(Type.INT_TYPE);
-                break;
-            case Opcodes.LSHL:
-                shl(Type.LONG_TYPE);
-                break;
-            case Opcodes.ISHR:
-                shr(Type.INT_TYPE);
-                break;
-            case Opcodes.LSHR:
-                shr(Type.LONG_TYPE);
-                break;
-            case Opcodes.IUSHR:
-                ushr(Type.INT_TYPE);
-                break;
-            case Opcodes.LUSHR:
-                ushr(Type.LONG_TYPE);
-                break;
-            case Opcodes.IAND:
-                and(Type.INT_TYPE);
-                break;
-            case Opcodes.LAND:
-                and(Type.LONG_TYPE);
-                break;
-            case Opcodes.IOR:
-                or(Type.INT_TYPE);
-                break;
-            case Opcodes.LOR:
-                or(Type.LONG_TYPE);
-                break;
-            case Opcodes.IXOR:
-                xor(Type.INT_TYPE);
-                break;
-            case Opcodes.LXOR:
-                xor(Type.LONG_TYPE);
-                break;
-            case Opcodes.I2L:
-                cast(Type.INT_TYPE, Type.LONG_TYPE);
-                break;
-            case Opcodes.I2F:
-                cast(Type.INT_TYPE, Type.FLOAT_TYPE);
-                break;
-            case Opcodes.I2D:
-                cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
-                break;
-            case Opcodes.L2I:
-                cast(Type.LONG_TYPE, Type.INT_TYPE);
-                break;
-            case Opcodes.L2F:
-                cast(Type.LONG_TYPE, Type.FLOAT_TYPE);
-                break;
-            case Opcodes.L2D:
-                cast(Type.LONG_TYPE, Type.DOUBLE_TYPE);
-                break;
-            case Opcodes.F2I:
-                cast(Type.FLOAT_TYPE, Type.INT_TYPE);
-                break;
-            case Opcodes.F2L:
-                cast(Type.FLOAT_TYPE, Type.LONG_TYPE);
-                break;
-            case Opcodes.F2D:
-                cast(Type.FLOAT_TYPE, Type.DOUBLE_TYPE);
-                break;
-            case Opcodes.D2I:
-                cast(Type.DOUBLE_TYPE, Type.INT_TYPE);
-                break;
-            case Opcodes.D2L:
-                cast(Type.DOUBLE_TYPE, Type.LONG_TYPE);
-                break;
-            case Opcodes.D2F:
-                cast(Type.DOUBLE_TYPE, Type.FLOAT_TYPE);
-                break;
-            case Opcodes.I2B:
-                cast(Type.INT_TYPE, Type.BYTE_TYPE);
-                break;
-            case Opcodes.I2C:
-                cast(Type.INT_TYPE, Type.CHAR_TYPE);
-                break;
-            case Opcodes.I2S:
-                cast(Type.INT_TYPE, Type.SHORT_TYPE);
-                break;
-            case Opcodes.LCMP:
-                lcmp();
-                break;
-            case Opcodes.FCMPL:
-                cmpl(Type.FLOAT_TYPE);
-                break;
-            case Opcodes.FCMPG:
-                cmpg(Type.FLOAT_TYPE);
-                break;
-            case Opcodes.DCMPL:
-                cmpl(Type.DOUBLE_TYPE);
-                break;
-            case Opcodes.DCMPG:
-                cmpg(Type.DOUBLE_TYPE);
-                break;
-            case Opcodes.IRETURN:
-                areturn(Type.INT_TYPE);
-                break;
-            case Opcodes.LRETURN:
-                areturn(Type.LONG_TYPE);
-                break;
-            case Opcodes.FRETURN:
-                areturn(Type.FLOAT_TYPE);
-                break;
-            case Opcodes.DRETURN:
-                areturn(Type.DOUBLE_TYPE);
-                break;
-            case Opcodes.ARETURN:
-                areturn(OBJECT_TYPE);
-                break;
-            case Opcodes.RETURN:
-                areturn(Type.VOID_TYPE);
-                break;
-            case Opcodes.ARRAYLENGTH:
-                arraylength();
-                break;
-            case Opcodes.ATHROW:
-                athrow();
-                break;
-            case Opcodes.MONITORENTER:
-                monitorenter();
-                break;
-            case Opcodes.MONITOREXIT:
-                monitorexit();
-                break;
-            default:
-                throw new IllegalArgumentException();
+        case Opcodes.NOP:
+            nop();
+            break;
+        case Opcodes.ACONST_NULL:
+            aconst(null);
+            break;
+        case Opcodes.ICONST_M1:
+        case Opcodes.ICONST_0:
+        case Opcodes.ICONST_1:
+        case Opcodes.ICONST_2:
+        case Opcodes.ICONST_3:
+        case Opcodes.ICONST_4:
+        case Opcodes.ICONST_5:
+            iconst(opcode - Opcodes.ICONST_0);
+            break;
+        case Opcodes.LCONST_0:
+        case Opcodes.LCONST_1:
+            lconst(opcode - Opcodes.LCONST_0);
+            break;
+        case Opcodes.FCONST_0:
+        case Opcodes.FCONST_1:
+        case Opcodes.FCONST_2:
+            fconst(opcode - Opcodes.FCONST_0);
+            break;
+        case Opcodes.DCONST_0:
+        case Opcodes.DCONST_1:
+            dconst(opcode - Opcodes.DCONST_0);
+            break;
+        case Opcodes.IALOAD:
+            aload(Type.INT_TYPE);
+            break;
+        case Opcodes.LALOAD:
+            aload(Type.LONG_TYPE);
+            break;
+        case Opcodes.FALOAD:
+            aload(Type.FLOAT_TYPE);
+            break;
+        case Opcodes.DALOAD:
+            aload(Type.DOUBLE_TYPE);
+            break;
+        case Opcodes.AALOAD:
+            aload(OBJECT_TYPE);
+            break;
+        case Opcodes.BALOAD:
+            aload(Type.BYTE_TYPE);
+            break;
+        case Opcodes.CALOAD:
+            aload(Type.CHAR_TYPE);
+            break;
+        case Opcodes.SALOAD:
+            aload(Type.SHORT_TYPE);
+            break;
+        case Opcodes.IASTORE:
+            astore(Type.INT_TYPE);
+            break;
+        case Opcodes.LASTORE:
+            astore(Type.LONG_TYPE);
+            break;
+        case Opcodes.FASTORE:
+            astore(Type.FLOAT_TYPE);
+            break;
+        case Opcodes.DASTORE:
+            astore(Type.DOUBLE_TYPE);
+            break;
+        case Opcodes.AASTORE:
+            astore(OBJECT_TYPE);
+            break;
+        case Opcodes.BASTORE:
+            astore(Type.BYTE_TYPE);
+            break;
+        case Opcodes.CASTORE:
+            astore(Type.CHAR_TYPE);
+            break;
+        case Opcodes.SASTORE:
+            astore(Type.SHORT_TYPE);
+            break;
+        case Opcodes.POP:
+            pop();
+            break;
+        case Opcodes.POP2:
+            pop2();
+            break;
+        case Opcodes.DUP:
+            dup();
+            break;
+        case Opcodes.DUP_X1:
+            dupX1();
+            break;
+        case Opcodes.DUP_X2:
+            dupX2();
+            break;
+        case Opcodes.DUP2:
+            dup2();
+            break;
+        case Opcodes.DUP2_X1:
+            dup2X1();
+            break;
+        case Opcodes.DUP2_X2:
+            dup2X2();
+            break;
+        case Opcodes.SWAP:
+            swap();
+            break;
+        case Opcodes.IADD:
+            add(Type.INT_TYPE);
+            break;
+        case Opcodes.LADD:
+            add(Type.LONG_TYPE);
+            break;
+        case Opcodes.FADD:
+            add(Type.FLOAT_TYPE);
+            break;
+        case Opcodes.DADD:
+            add(Type.DOUBLE_TYPE);
+            break;
+        case Opcodes.ISUB:
+            sub(Type.INT_TYPE);
+            break;
+        case Opcodes.LSUB:
+            sub(Type.LONG_TYPE);
+            break;
+        case Opcodes.FSUB:
+            sub(Type.FLOAT_TYPE);
+            break;
+        case Opcodes.DSUB:
+            sub(Type.DOUBLE_TYPE);
+            break;
+        case Opcodes.IMUL:
+            mul(Type.INT_TYPE);
+            break;
+        case Opcodes.LMUL:
+            mul(Type.LONG_TYPE);
+            break;
+        case Opcodes.FMUL:
+            mul(Type.FLOAT_TYPE);
+            break;
+        case Opcodes.DMUL:
+            mul(Type.DOUBLE_TYPE);
+            break;
+        case Opcodes.IDIV:
+            div(Type.INT_TYPE);
+            break;
+        case Opcodes.LDIV:
+            div(Type.LONG_TYPE);
+            break;
+        case Opcodes.FDIV:
+            div(Type.FLOAT_TYPE);
+            break;
+        case Opcodes.DDIV:
+            div(Type.DOUBLE_TYPE);
+            break;
+        case Opcodes.IREM:
+            rem(Type.INT_TYPE);
+            break;
+        case Opcodes.LREM:
+            rem(Type.LONG_TYPE);
+            break;
+        case Opcodes.FREM:
+            rem(Type.FLOAT_TYPE);
+            break;
+        case Opcodes.DREM:
+            rem(Type.DOUBLE_TYPE);
+            break;
+        case Opcodes.INEG:
+            neg(Type.INT_TYPE);
+            break;
+        case Opcodes.LNEG:
+            neg(Type.LONG_TYPE);
+            break;
+        case Opcodes.FNEG:
+            neg(Type.FLOAT_TYPE);
+            break;
+        case Opcodes.DNEG:
+            neg(Type.DOUBLE_TYPE);
+            break;
+        case Opcodes.ISHL:
+            shl(Type.INT_TYPE);
+            break;
+        case Opcodes.LSHL:
+            shl(Type.LONG_TYPE);
+            break;
+        case Opcodes.ISHR:
+            shr(Type.INT_TYPE);
+            break;
+        case Opcodes.LSHR:
+            shr(Type.LONG_TYPE);
+            break;
+        case Opcodes.IUSHR:
+            ushr(Type.INT_TYPE);
+            break;
+        case Opcodes.LUSHR:
+            ushr(Type.LONG_TYPE);
+            break;
+        case Opcodes.IAND:
+            and(Type.INT_TYPE);
+            break;
+        case Opcodes.LAND:
+            and(Type.LONG_TYPE);
+            break;
+        case Opcodes.IOR:
+            or(Type.INT_TYPE);
+            break;
+        case Opcodes.LOR:
+            or(Type.LONG_TYPE);
+            break;
+        case Opcodes.IXOR:
+            xor(Type.INT_TYPE);
+            break;
+        case Opcodes.LXOR:
+            xor(Type.LONG_TYPE);
+            break;
+        case Opcodes.I2L:
+            cast(Type.INT_TYPE, Type.LONG_TYPE);
+            break;
+        case Opcodes.I2F:
+            cast(Type.INT_TYPE, Type.FLOAT_TYPE);
+            break;
+        case Opcodes.I2D:
+            cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
+            break;
+        case Opcodes.L2I:
+            cast(Type.LONG_TYPE, Type.INT_TYPE);
+            break;
+        case Opcodes.L2F:
+            cast(Type.LONG_TYPE, Type.FLOAT_TYPE);
+            break;
+        case Opcodes.L2D:
+            cast(Type.LONG_TYPE, Type.DOUBLE_TYPE);
+            break;
+        case Opcodes.F2I:
+            cast(Type.FLOAT_TYPE, Type.INT_TYPE);
+            break;
+        case Opcodes.F2L:
+            cast(Type.FLOAT_TYPE, Type.LONG_TYPE);
+            break;
+        case Opcodes.F2D:
+            cast(Type.FLOAT_TYPE, Type.DOUBLE_TYPE);
+            break;
+        case Opcodes.D2I:
+            cast(Type.DOUBLE_TYPE, Type.INT_TYPE);
+            break;
+        case Opcodes.D2L:
+            cast(Type.DOUBLE_TYPE, Type.LONG_TYPE);
+            break;
+        case Opcodes.D2F:
+            cast(Type.DOUBLE_TYPE, Type.FLOAT_TYPE);
+            break;
+        case Opcodes.I2B:
+            cast(Type.INT_TYPE, Type.BYTE_TYPE);
+            break;
+        case Opcodes.I2C:
+            cast(Type.INT_TYPE, Type.CHAR_TYPE);
+            break;
+        case Opcodes.I2S:
+            cast(Type.INT_TYPE, Type.SHORT_TYPE);
+            break;
+        case Opcodes.LCMP:
+            lcmp();
+            break;
+        case Opcodes.FCMPL:
+            cmpl(Type.FLOAT_TYPE);
+            break;
+        case Opcodes.FCMPG:
+            cmpg(Type.FLOAT_TYPE);
+            break;
+        case Opcodes.DCMPL:
+            cmpl(Type.DOUBLE_TYPE);
+            break;
+        case Opcodes.DCMPG:
+            cmpg(Type.DOUBLE_TYPE);
+            break;
+        case Opcodes.IRETURN:
+            areturn(Type.INT_TYPE);
+            break;
+        case Opcodes.LRETURN:
+            areturn(Type.LONG_TYPE);
+            break;
+        case Opcodes.FRETURN:
+            areturn(Type.FLOAT_TYPE);
+            break;
+        case Opcodes.DRETURN:
+            areturn(Type.DOUBLE_TYPE);
+            break;
+        case Opcodes.ARETURN:
+            areturn(OBJECT_TYPE);
+            break;
+        case Opcodes.RETURN:
+            areturn(Type.VOID_TYPE);
+            break;
+        case Opcodes.ARRAYLENGTH:
+            arraylength();
+            break;
+        case Opcodes.ATHROW:
+            athrow();
+            break;
+        case Opcodes.MONITORENTER:
+            monitorenter();
+            break;
+        case Opcodes.MONITOREXIT:
+            monitorexit();
+            break;
+        default:
+            throw new IllegalArgumentException();
         }
     }
 
     @Override
     public void visitIntInsn(final int opcode, final int operand) {
         switch (opcode) {
-            case Opcodes.BIPUSH:
-                iconst(operand);
+        case Opcodes.BIPUSH:
+            iconst(operand);
+            break;
+        case Opcodes.SIPUSH:
+            iconst(operand);
+            break;
+        case Opcodes.NEWARRAY:
+            switch (operand) {
+            case Opcodes.T_BOOLEAN:
+                newarray(Type.BOOLEAN_TYPE);
                 break;
-            case Opcodes.SIPUSH:
-                iconst(operand);
+            case Opcodes.T_CHAR:
+                newarray(Type.CHAR_TYPE);
                 break;
-            case Opcodes.NEWARRAY:
-                switch (operand) {
-                    case Opcodes.T_BOOLEAN:
-                        newarray(Type.BOOLEAN_TYPE);
-                        break;
-                    case Opcodes.T_CHAR:
-                        newarray(Type.CHAR_TYPE);
-                        break;
-                    case Opcodes.T_BYTE:
-                        newarray(Type.BYTE_TYPE);
-                        break;
-                    case Opcodes.T_SHORT:
-                        newarray(Type.SHORT_TYPE);
-                        break;
-                    case Opcodes.T_INT:
-                        newarray(Type.INT_TYPE);
-                        break;
-                    case Opcodes.T_FLOAT:
-                        newarray(Type.FLOAT_TYPE);
-                        break;
-                    case Opcodes.T_LONG:
-                        newarray(Type.LONG_TYPE);
-                        break;
-                    case Opcodes.T_DOUBLE:
-                        newarray(Type.DOUBLE_TYPE);
-                        break;
-                    default:
-                        throw new IllegalArgumentException();
-                }
+            case Opcodes.T_BYTE:
+                newarray(Type.BYTE_TYPE);
+                break;
+            case Opcodes.T_SHORT:
+                newarray(Type.SHORT_TYPE);
+                break;
+            case Opcodes.T_INT:
+                newarray(Type.INT_TYPE);
+                break;
+            case Opcodes.T_FLOAT:
+                newarray(Type.FLOAT_TYPE);
+                break;
+            case Opcodes.T_LONG:
+                newarray(Type.LONG_TYPE);
+                break;
+            case Opcodes.T_DOUBLE:
+                newarray(Type.DOUBLE_TYPE);
                 break;
             default:
                 throw new IllegalArgumentException();
+            }
+            break;
+        default:
+            throw new IllegalArgumentException();
         }
     }
 
     @Override
     public void visitVarInsn(final int opcode, final int var) {
         switch (opcode) {
-            case Opcodes.ILOAD:
-                load(var, Type.INT_TYPE);
-                break;
-            case Opcodes.LLOAD:
-                load(var, Type.LONG_TYPE);
-                break;
-            case Opcodes.FLOAD:
-                load(var, Type.FLOAT_TYPE);
-                break;
-            case Opcodes.DLOAD:
-                load(var, Type.DOUBLE_TYPE);
-                break;
-            case Opcodes.ALOAD:
-                load(var, OBJECT_TYPE);
-                break;
-            case Opcodes.ISTORE:
-                store(var, Type.INT_TYPE);
-                break;
-            case Opcodes.LSTORE:
-                store(var, Type.LONG_TYPE);
-                break;
-            case Opcodes.FSTORE:
-                store(var, Type.FLOAT_TYPE);
-                break;
-            case Opcodes.DSTORE:
-                store(var, Type.DOUBLE_TYPE);
-                break;
-            case Opcodes.ASTORE:
-                store(var, OBJECT_TYPE);
-                break;
-            case Opcodes.RET:
-                ret(var);
-                break;
-            default:
-                throw new IllegalArgumentException();
+        case Opcodes.ILOAD:
+            load(var, Type.INT_TYPE);
+            break;
+        case Opcodes.LLOAD:
+            load(var, Type.LONG_TYPE);
+            break;
+        case Opcodes.FLOAD:
+            load(var, Type.FLOAT_TYPE);
+            break;
+        case Opcodes.DLOAD:
+            load(var, Type.DOUBLE_TYPE);
+            break;
+        case Opcodes.ALOAD:
+            load(var, OBJECT_TYPE);
+            break;
+        case Opcodes.ISTORE:
+            store(var, Type.INT_TYPE);
+            break;
+        case Opcodes.LSTORE:
+            store(var, Type.LONG_TYPE);
+            break;
+        case Opcodes.FSTORE:
+            store(var, Type.FLOAT_TYPE);
+            break;
+        case Opcodes.DSTORE:
+            store(var, Type.DOUBLE_TYPE);
+            break;
+        case Opcodes.ASTORE:
+            store(var, OBJECT_TYPE);
+            break;
+        case Opcodes.RET:
+            ret(var);
+            break;
+        default:
+            throw new IllegalArgumentException();
         }
     }
 
@@ -495,142 +498,130 @@
     public void visitTypeInsn(final int opcode, final String type) {
         Type t = Type.getObjectType(type);
         switch (opcode) {
-            case Opcodes.NEW:
-                anew(t);
-                break;
-            case Opcodes.ANEWARRAY:
-                newarray(t);
-                break;
-            case Opcodes.CHECKCAST:
-                checkcast(t);
-                break;
-            case Opcodes.INSTANCEOF:
-                instanceOf(t);
-                break;
-            default:
-                throw new IllegalArgumentException();
+        case Opcodes.NEW:
+            anew(t);
+            break;
+        case Opcodes.ANEWARRAY:
+            newarray(t);
+            break;
+        case Opcodes.CHECKCAST:
+            checkcast(t);
+            break;
+        case Opcodes.INSTANCEOF:
+            instanceOf(t);
+            break;
+        default:
+            throw new IllegalArgumentException();
         }
     }
 
     @Override
-    public void visitFieldInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitFieldInsn(final int opcode, final String owner,
+            final String name, final String desc) {
         switch (opcode) {
-            case Opcodes.GETSTATIC:
-                getstatic(owner, name, desc);
-                break;
-            case Opcodes.PUTSTATIC:
-                putstatic(owner, name, desc);
-                break;
-            case Opcodes.GETFIELD:
-                getfield(owner, name, desc);
-                break;
-            case Opcodes.PUTFIELD:
-                putfield(owner, name, desc);
-                break;
-            default:
-                throw new IllegalArgumentException();
+        case Opcodes.GETSTATIC:
+            getstatic(owner, name, desc);
+            break;
+        case Opcodes.PUTSTATIC:
+            putstatic(owner, name, desc);
+            break;
+        case Opcodes.GETFIELD:
+            getfield(owner, name, desc);
+            break;
+        case Opcodes.PUTFIELD:
+            putfield(owner, name, desc);
+            break;
+        default:
+            throw new IllegalArgumentException();
         }
     }
 
     @Override
-    public void visitMethodInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitMethodInsn(final int opcode, final String owner,
+            final String name, final String desc) {
         switch (opcode) {
-            case Opcodes.INVOKESPECIAL:
-                invokespecial(owner, name, desc);
-                break;
-            case Opcodes.INVOKEVIRTUAL:
-                invokevirtual(owner, name, desc);
-                break;
-            case Opcodes.INVOKESTATIC:
-                invokestatic(owner, name, desc);
-                break;
-            case Opcodes.INVOKEINTERFACE:
-                invokeinterface(owner, name, desc);
-                break;
-            default:
-                throw new IllegalArgumentException();
+        case Opcodes.INVOKESPECIAL:
+            invokespecial(owner, name, desc);
+            break;
+        case Opcodes.INVOKEVIRTUAL:
+            invokevirtual(owner, name, desc);
+            break;
+        case Opcodes.INVOKESTATIC:
+            invokestatic(owner, name, desc);
+            break;
+        case Opcodes.INVOKEINTERFACE:
+            invokeinterface(owner, name, desc);
+            break;
+        default:
+            throw new IllegalArgumentException();
         }
     }
 
     @Override
-    public void visitInvokeDynamicInsn(
-        String name,
-        String desc,
-        Handle bsm,
-        Object... bsmArgs)
-    {
-       invokedynamic(name, desc, bsm, bsmArgs);
+    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+            Object... bsmArgs) {
+        invokedynamic(name, desc, bsm, bsmArgs);
     }
 
     @Override
     public void visitJumpInsn(final int opcode, final Label label) {
         switch (opcode) {
-            case Opcodes.IFEQ:
-                ifeq(label);
-                break;
-            case Opcodes.IFNE:
-                ifne(label);
-                break;
-            case Opcodes.IFLT:
-                iflt(label);
-                break;
-            case Opcodes.IFGE:
-                ifge(label);
-                break;
-            case Opcodes.IFGT:
-                ifgt(label);
-                break;
-            case Opcodes.IFLE:
-                ifle(label);
-                break;
-            case Opcodes.IF_ICMPEQ:
-                ificmpeq(label);
-                break;
-            case Opcodes.IF_ICMPNE:
-                ificmpne(label);
-                break;
-            case Opcodes.IF_ICMPLT:
-                ificmplt(label);
-                break;
-            case Opcodes.IF_ICMPGE:
-                ificmpge(label);
-                break;
-            case Opcodes.IF_ICMPGT:
-                ificmpgt(label);
-                break;
-            case Opcodes.IF_ICMPLE:
-                ificmple(label);
-                break;
-            case Opcodes.IF_ACMPEQ:
-                ifacmpeq(label);
-                break;
-            case Opcodes.IF_ACMPNE:
-                ifacmpne(label);
-                break;
-            case Opcodes.GOTO:
-                goTo(label);
-                break;
-            case Opcodes.JSR:
-                jsr(label);
-                break;
-            case Opcodes.IFNULL:
-                ifnull(label);
-                break;
-            case Opcodes.IFNONNULL:
-                ifnonnull(label);
-                break;
-            default:
-                throw new IllegalArgumentException();
+        case Opcodes.IFEQ:
+            ifeq(label);
+            break;
+        case Opcodes.IFNE:
+            ifne(label);
+            break;
+        case Opcodes.IFLT:
+            iflt(label);
+            break;
+        case Opcodes.IFGE:
+            ifge(label);
+            break;
+        case Opcodes.IFGT:
+            ifgt(label);
+            break;
+        case Opcodes.IFLE:
+            ifle(label);
+            break;
+        case Opcodes.IF_ICMPEQ:
+            ificmpeq(label);
+            break;
+        case Opcodes.IF_ICMPNE:
+            ificmpne(label);
+            break;
+        case Opcodes.IF_ICMPLT:
+            ificmplt(label);
+            break;
+        case Opcodes.IF_ICMPGE:
+            ificmpge(label);
+            break;
+        case Opcodes.IF_ICMPGT:
+            ificmpgt(label);
+            break;
+        case Opcodes.IF_ICMPLE:
+            ificmple(label);
+            break;
+        case Opcodes.IF_ACMPEQ:
+            ifacmpeq(label);
+            break;
+        case Opcodes.IF_ACMPNE:
+            ifacmpne(label);
+            break;
+        case Opcodes.GOTO:
+            goTo(label);
+            break;
+        case Opcodes.JSR:
+            jsr(label);
+            break;
+        case Opcodes.IFNULL:
+            ifnull(label);
+            break;
+        case Opcodes.IFNONNULL:
+            ifnonnull(label);
+            break;
+        default:
+            throw new IllegalArgumentException();
         }
     }
 
@@ -682,21 +673,14 @@
     }
 
     @Override
-    public void visitTableSwitchInsn(
-        final int min,
-        final int max,
-        final Label dflt,
-        final Label... labels)
-    {
+    public void visitTableSwitchInsn(final int min, final int max,
+            final Label dflt, final Label... labels) {
         tableswitch(min, max, dflt, labels);
     }
 
     @Override
-    public void visitLookupSwitchInsn(
-        final Label dflt,
-        final int[] keys,
-        final Label[] labels)
-    {
+    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+            final Label[] labels) {
         lookupswitch(dflt, keys, labels);
     }
 
@@ -996,20 +980,13 @@
         mv.visitVarInsn(Opcodes.RET, var);
     }
 
-    public void tableswitch(
-        final int min,
-        final int max,
-        final Label dflt,
-        final Label... labels)
-    {
+    public void tableswitch(final int min, final int max, final Label dflt,
+            final Label... labels) {
         mv.visitTableSwitchInsn(min, max, dflt, labels);
     }
 
-    public void lookupswitch(
-        final Label dflt,
-        final int[] keys,
-        final Label[] labels)
-    {
+    public void lookupswitch(final Label dflt, final int[] keys,
+            final Label[] labels) {
         mv.visitLookupSwitchInsn(dflt, keys, labels);
     }
 
@@ -1017,76 +994,48 @@
         mv.visitInsn(t.getOpcode(Opcodes.IRETURN));
     }
 
-    public void getstatic(
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void getstatic(final String owner, final String name,
+            final String desc) {
         mv.visitFieldInsn(Opcodes.GETSTATIC, owner, name, desc);
     }
 
-    public void putstatic(
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void putstatic(final String owner, final String name,
+            final String desc) {
         mv.visitFieldInsn(Opcodes.PUTSTATIC, owner, name, desc);
     }
 
-    public void getfield(
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void getfield(final String owner, final String name,
+            final String desc) {
         mv.visitFieldInsn(Opcodes.GETFIELD, owner, name, desc);
     }
 
-    public void putfield(
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void putfield(final String owner, final String name,
+            final String desc) {
         mv.visitFieldInsn(Opcodes.PUTFIELD, owner, name, desc);
     }
 
-    public void invokevirtual(
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void invokevirtual(final String owner, final String name,
+            final String desc) {
         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, name, desc);
     }
 
-    public void invokespecial(
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void invokespecial(final String owner, final String name,
+            final String desc) {
         mv.visitMethodInsn(Opcodes.INVOKESPECIAL, owner, name, desc);
     }
 
-    public void invokestatic(
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void invokestatic(final String owner, final String name,
+            final String desc) {
         mv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, name, desc);
     }
 
-    public void invokeinterface(
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void invokeinterface(final String owner, final String name,
+            final String desc) {
         mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, owner, name, desc);
     }
 
-    public void invokedynamic(
-        String name,
-        String desc,
-        Handle bsm,
-        Object[] bsmArgs)
-    {
+    public void invokedynamic(String name, String desc, Handle bsm,
+            Object[] bsmArgs) {
         mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
     }
 
@@ -1097,33 +1046,33 @@
     public void newarray(final Type type) {
         int typ;
         switch (type.getSort()) {
-            case Type.BOOLEAN:
-                typ = Opcodes.T_BOOLEAN;
-                break;
-            case Type.CHAR:
-                typ = Opcodes.T_CHAR;
-                break;
-            case Type.BYTE:
-                typ = Opcodes.T_BYTE;
-                break;
-            case Type.SHORT:
-                typ = Opcodes.T_SHORT;
-                break;
-            case Type.INT:
-                typ = Opcodes.T_INT;
-                break;
-            case Type.FLOAT:
-                typ = Opcodes.T_FLOAT;
-                break;
-            case Type.LONG:
-                typ = Opcodes.T_LONG;
-                break;
-            case Type.DOUBLE:
-                typ = Opcodes.T_DOUBLE;
-                break;
-            default:
-                mv.visitTypeInsn(Opcodes.ANEWARRAY, type.getInternalName());
-                return;
+        case Type.BOOLEAN:
+            typ = Opcodes.T_BOOLEAN;
+            break;
+        case Type.CHAR:
+            typ = Opcodes.T_CHAR;
+            break;
+        case Type.BYTE:
+            typ = Opcodes.T_BYTE;
+            break;
+        case Type.SHORT:
+            typ = Opcodes.T_SHORT;
+            break;
+        case Type.INT:
+            typ = Opcodes.T_INT;
+            break;
+        case Type.FLOAT:
+            typ = Opcodes.T_FLOAT;
+            break;
+        case Type.LONG:
+            typ = Opcodes.T_LONG;
+            break;
+        case Type.DOUBLE:
+            typ = Opcodes.T_DOUBLE;
+            break;
+        default:
+            mv.visitTypeInsn(Opcodes.ANEWARRAY, type.getInternalName());
+            return;
         }
         mv.visitIntInsn(Opcodes.NEWARRAY, typ);
     }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter.java
index b8da61d..1a255b7 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter.java
@@ -96,10 +96,9 @@
     private static final boolean LOGGING = false;
 
     /**
-     * For each label that is jumped to by a JSR, we create a BitSet
-     * instance.
+     * For each label that is jumped to by a JSR, we create a BitSet instance.
      */
-    private final Map<LabelNode,BitSet> subroutineHeads = new HashMap<LabelNode,BitSet>();
+    private final Map<LabelNode, BitSet> subroutineHeads = new HashMap<LabelNode, BitSet>();
 
     /**
      * This subroutine instance denotes the line of execution that is not
@@ -120,55 +119,57 @@
      * {@link #JSRInlinerAdapter(int, MethodVisitor, int, String, String, String, String[])}
      * version.
      *
-     * @param mv the <code>MethodVisitor</code> to send the resulting inlined
-     *        method code to (use <code>null</code> for none).
-     * @param access the method's access flags (see {@link Opcodes}). This
-     *        parameter also indicates if the method is synthetic and/or
-     *        deprecated.
-     * @param name the method's name.
-     * @param desc the method's descriptor (see {@link Type}).
-     * @param signature the method's signature. May be <tt>null</tt>.
-     * @param exceptions the internal names of the method's exception classes
-     *        (see {@link Type#getInternalName() getInternalName}). May be
-     *        <tt>null</tt>.
+     * @param mv
+     *            the <code>MethodVisitor</code> to send the resulting inlined
+     *            method code to (use <code>null</code> for none).
+     * @param access
+     *            the method's access flags (see {@link Opcodes}). This
+     *            parameter also indicates if the method is synthetic and/or
+     *            deprecated.
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor (see {@link Type}).
+     * @param signature
+     *            the method's signature. May be <tt>null</tt>.
+     * @param exceptions
+     *            the internal names of the method's exception classes (see
+     *            {@link Type#getInternalName() getInternalName}). May be
+     *            <tt>null</tt>.
      */
-    public JSRInlinerAdapter(
-        final MethodVisitor mv,
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final String[] exceptions)
-    {
-        this(Opcodes.ASM4, mv, access, name, desc, signature, exceptions);
+    public JSRInlinerAdapter(final MethodVisitor mv, final int access,
+            final String name, final String desc, final String signature,
+            final String[] exceptions) {
+        this(Opcodes.ASM5, mv, access, name, desc, signature, exceptions);
     }
 
     /**
      * Creates a new JSRInliner.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
-     * @param mv the <code>MethodVisitor</code> to send the resulting inlined
-     *        method code to (use <code>null</code> for none).
-     * @param access the method's access flags (see {@link Opcodes}). This
-     *        parameter also indicates if the method is synthetic and/or
-     *        deprecated.
-     * @param name the method's name.
-     * @param desc the method's descriptor (see {@link Type}).
-     * @param signature the method's signature. May be <tt>null</tt>.
-     * @param exceptions the internal names of the method's exception classes
-     *        (see {@link Type#getInternalName() getInternalName}). May be
-     *        <tt>null</tt>.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param mv
+     *            the <code>MethodVisitor</code> to send the resulting inlined
+     *            method code to (use <code>null</code> for none).
+     * @param access
+     *            the method's access flags (see {@link Opcodes}). This
+     *            parameter also indicates if the method is synthetic and/or
+     *            deprecated.
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor (see {@link Type}).
+     * @param signature
+     *            the method's signature. May be <tt>null</tt>.
+     * @param exceptions
+     *            the internal names of the method's exception classes (see
+     *            {@link Type#getInternalName() getInternalName}). May be
+     *            <tt>null</tt>.
      */
-    protected JSRInlinerAdapter(
-        final int api,
-        final MethodVisitor mv,
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final String[] exceptions)
-    {
+    protected JSRInlinerAdapter(final int api, final MethodVisitor mv,
+            final int access, final String name, final String desc,
+            final String signature, final String[] exceptions) {
         super(api, access, name, desc, signature, exceptions);
         this.mv = mv;
     }
@@ -224,9 +225,9 @@
 
         // Go through the head of each subroutine and find any nodes reachable
         // to that subroutine without following any JSR links.
-        for (Iterator<Map.Entry<LabelNode,BitSet>> it = subroutineHeads.entrySet().iterator(); it.hasNext();)
-        {
-            Map.Entry<LabelNode,BitSet> entry = it.next();
+        for (Iterator<Map.Entry<LabelNode, BitSet>> it = subroutineHeads
+                .entrySet().iterator(); it.hasNext();) {
+            Map.Entry<LabelNode, BitSet> entry = it.next();
             LabelNode lab = entry.getKey();
             BitSet sub = entry.getValue();
             int index = instructions.indexOf(lab);
@@ -236,24 +237,22 @@
 
     /**
      * Performs a depth first search walking the normal byte code path starting
-     * at <code>index</code>, and adding each instruction encountered into
-     * the subroutine <code>sub</code>. After this walk is complete, iterates
-     * over the exception handlers to ensure that we also include those byte
-     * codes which are reachable through an exception that may be thrown during
-     * the execution of the subroutine. Invoked from
-     * <code>markSubroutines()</code>.
+     * at <code>index</code>, and adding each instruction encountered into the
+     * subroutine <code>sub</code>. After this walk is complete, iterates over
+     * the exception handlers to ensure that we also include those byte codes
+     * which are reachable through an exception that may be thrown during the
+     * execution of the subroutine. Invoked from <code>markSubroutines()</code>.
      *
-     * @param sub the subroutine whose instructions must be computed.
-     * @param index an instruction of this subroutine.
-     * @param anyvisited indexes of the already visited instructions, i.e.
-     *        marked as part of this subroutine or any previously computed
-     *        subroutine.
+     * @param sub
+     *            the subroutine whose instructions must be computed.
+     * @param index
+     *            an instruction of this subroutine.
+     * @param anyvisited
+     *            indexes of the already visited instructions, i.e. marked as
+     *            part of this subroutine or any previously computed subroutine.
      */
-    private void markSubroutineWalk(
-        final BitSet sub,
-        final int index,
-        final BitSet anyvisited)
-    {
+    private void markSubroutineWalk(final BitSet sub, final int index,
+            final BitSet anyvisited) {
         if (LOGGING) {
             log("markSubroutineWalk: sub=" + sub + " index=" + index);
         }
@@ -265,7 +264,8 @@
         boolean loop = true;
         while (loop) {
             loop = false;
-            for (Iterator<TryCatchBlockNode> it = tryCatchBlocks.iterator(); it.hasNext();) {
+            for (Iterator<TryCatchBlockNode> it = tryCatchBlocks.iterator(); it
+                    .hasNext();) {
                 TryCatchBlockNode trycatch = it.next();
 
                 if (LOGGING) {
@@ -297,20 +297,19 @@
 
     /**
      * Performs a simple DFS of the instructions, assigning each to the
-     * subroutine <code>sub</code>. Starts from <code>index</code>.
-     * Invoked only by <code>markSubroutineWalk()</code>.
+     * subroutine <code>sub</code>. Starts from <code>index</code>. Invoked only
+     * by <code>markSubroutineWalk()</code>.
      *
-     * @param sub the subroutine whose instructions must be computed.
-     * @param index an instruction of this subroutine.
-     * @param anyvisited indexes of the already visited instructions, i.e.
-     *        marked as part of this subroutine or any previously computed
-     *        subroutine.
+     * @param sub
+     *            the subroutine whose instructions must be computed.
+     * @param index
+     *            an instruction of this subroutine.
+     * @param anyvisited
+     *            indexes of the already visited instructions, i.e. marked as
+     *            part of this subroutine or any previously computed subroutine.
      */
-    private void markSubroutineWalkDFS(
-        final BitSet sub,
-        int index,
-        final BitSet anyvisited)
-    {
+    private void markSubroutineWalkDFS(final BitSet sub, int index,
+            final BitSet anyvisited) {
         while (true) {
             AbstractInsnNode node = instructions.get(index);
 
@@ -330,8 +329,7 @@
             anyvisited.set(index);
 
             if (node.getType() == AbstractInsnNode.JUMP_INSN
-                    && node.getOpcode() != JSR)
-            {
+                    && node.getOpcode() != JSR) {
                 // we do not follow recursively called subroutines here; but any
                 // other sort of branch we do follow
                 JumpInsnNode jnode = (JumpInsnNode) node;
@@ -362,22 +360,22 @@
             // check to see if this opcode falls through to the next instruction
             // or not; if not, return.
             switch (instructions.get(index).getOpcode()) {
-                case GOTO:
-                case RET:
-                case TABLESWITCH:
-                case LOOKUPSWITCH:
-                case IRETURN:
-                case LRETURN:
-                case FRETURN:
-                case DRETURN:
-                case ARETURN:
-                case RETURN:
-                case ATHROW:
-                    /*
-                     * note: this either returns from this subroutine, or a
-                     * parent subroutine which invoked it
-                     */
-                    return;
+            case GOTO:
+            case RET:
+            case TABLESWITCH:
+            case LOOKUPSWITCH:
+            case IRETURN:
+            case LRETURN:
+            case FRETURN:
+            case DRETURN:
+            case ARETURN:
+            case RETURN:
+            case ATHROW:
+                /*
+                 * note: this either returns from this subroutine, or a parent
+                 * subroutine which invoked it
+                 */
+                return;
             }
 
             // Use tail recursion here in the form of an outer while loop to
@@ -403,10 +401,7 @@
         List<LocalVariableNode> newLocalVariables = new ArrayList<LocalVariableNode>();
         while (!worklist.isEmpty()) {
             Instantiation inst = worklist.removeFirst();
-            emitSubroutine(inst,
-                    worklist,
-                    newInstructions,
-                    newTryCatchBlocks,
+            emitSubroutine(inst, worklist, newInstructions, newTryCatchBlocks,
                     newLocalVariables);
         }
         instructions = newInstructions;
@@ -416,24 +411,25 @@
 
     /**
      * Emits one instantiation of one subroutine, specified by
-     * <code>instant</code>. May add new instantiations that are invoked by
-     * this one to the <code>worklist</code> parameter, and new try/catch
-     * blocks to <code>newTryCatchBlocks</code>.
+     * <code>instant</code>. May add new instantiations that are invoked by this
+     * one to the <code>worklist</code> parameter, and new try/catch blocks to
+     * <code>newTryCatchBlocks</code>.
      *
-     * @param instant the instantiation that must be performed.
-     * @param worklist list of the instantiations that remain to be done.
-     * @param newInstructions the instruction list to which the instantiated
-     *        code must be appended.
-     * @param newTryCatchBlocks the exception handler list to which the
-     *        instantiated handlers must be appended.
+     * @param instant
+     *            the instantiation that must be performed.
+     * @param worklist
+     *            list of the instantiations that remain to be done.
+     * @param newInstructions
+     *            the instruction list to which the instantiated code must be
+     *            appended.
+     * @param newTryCatchBlocks
+     *            the exception handler list to which the instantiated handlers
+     *            must be appended.
      */
-    private void emitSubroutine(
-        final Instantiation instant,
-        final List<Instantiation> worklist,
-        final InsnList newInstructions,
-        final List<TryCatchBlockNode> newTryCatchBlocks,
-        final List<LocalVariableNode> newLocalVariables)
-    {
+    private void emitSubroutine(final Instantiation instant,
+            final List<Instantiation> worklist, final InsnList newInstructions,
+            final List<TryCatchBlockNode> newTryCatchBlocks,
+            final List<LocalVariableNode> newLocalVariables) {
         LabelNode duplbl = null;
 
         if (LOGGING) {
@@ -530,7 +526,8 @@
         }
 
         // Emit try/catch blocks that are relevant to this method.
-        for (Iterator<TryCatchBlockNode> it = tryCatchBlocks.iterator(); it.hasNext();) {
+        for (Iterator<TryCatchBlockNode> it = tryCatchBlocks.iterator(); it
+                .hasNext();) {
             TryCatchBlockNode trycatch = it.next();
 
             if (LOGGING) {
@@ -562,13 +559,12 @@
                 throw new RuntimeException("Internal error!");
             }
 
-            newTryCatchBlocks.add(new TryCatchBlockNode(start,
-                    end,
-                    handler,
+            newTryCatchBlocks.add(new TryCatchBlockNode(start, end, handler,
                     trycatch.type));
         }
 
-        for (Iterator<LocalVariableNode> it = localVariables.iterator(); it.hasNext();) {
+        for (Iterator<LocalVariableNode> it = localVariables.iterator(); it
+                .hasNext();) {
             LocalVariableNode lvnode = it.next();
             if (LOGGING) {
                 log("local var " + lvnode.name);
@@ -582,11 +578,7 @@
                 continue;
             }
             newLocalVariables.add(new LocalVariableNode(lvnode.name,
-                    lvnode.desc,
-                    lvnode.signature,
-                    start,
-                    end,
-                    lvnode.index));
+                    lvnode.desc, lvnode.signature, start, end, lvnode.index));
         }
     }
 
@@ -693,8 +685,8 @@
          * Typically, the return value is either <code>this</code> or
          * <code>null</code>. <code>this</code> indicates that this
          * instantiation will generate the version of this instruction that we
-         * will execute, and <code>null</code> indicates that this
-         * instantiation never executes the given instruction.
+         * will execute, and <code>null</code> indicates that this instantiation
+         * never executes the given instruction.
          *
          * Sometimes, however, an instruction can belong to multiple
          * subroutines; this is called a "dual citizen" instruction (though it
@@ -703,7 +695,8 @@
          * owner is the subroutine that appears lowest on the stack, and which
          * also owns the instruction in question.
          *
-         * @param i the index of the instruction in the original code
+         * @param i
+         *            the index of the instruction in the original code
          * @return the "owner" of a particular instruction relative to this
          *         instantiation.
          */
@@ -724,12 +717,13 @@
         }
 
         /**
-         * Looks up the label <code>l</code> in the <code>gotoTable</code>,
-         * thus translating it from a Label in the original code, to a Label in
-         * the inlined code that is appropriate for use by an instruction that
+         * Looks up the label <code>l</code> in the <code>gotoTable</code>, thus
+         * translating it from a Label in the original code, to a Label in the
+         * inlined code that is appropriate for use by an instruction that
          * branched to the original label.
          *
-         * @param l The label we will be translating
+         * @param l
+         *            The label we will be translating
          * @return a label for use by a branch instruction in the inlined code
          * @see #rangeLabel
          */
@@ -746,7 +740,8 @@
          * the inlined code that is appropriate for use by an try/catch or
          * variable use annotation.
          *
-         * @param l The label we will be translating
+         * @param l
+         *            The label we will be translating
          * @return a label for use by a try/catch or variable annotation in the
          *         original code
          * @see #rangeTable
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/LocalVariablesSorter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/LocalVariablesSorter.java
index 54d67a8..0353c49 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/LocalVariablesSorter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/LocalVariablesSorter.java
@@ -58,10 +58,12 @@
  */
 package jdk.internal.org.objectweb.asm.commons;
 
+import jdk.internal.org.objectweb.asm.AnnotationVisitor;
 import jdk.internal.org.objectweb.asm.Label;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.Type;
+import jdk.internal.org.objectweb.asm.TypePath;
 
 /**
  * A {@link MethodVisitor} that renumbers local variables in their order of
@@ -77,7 +79,8 @@
  */
 public class LocalVariablesSorter extends MethodVisitor {
 
-    private static final Type OBJECT_TYPE = Type.getObjectType("java/lang/Object");
+    private static final Type OBJECT_TYPE = Type
+            .getObjectType("java/lang/Object");
 
     /**
      * Mapping from old to new local variable indexes. A local variable at index
@@ -111,33 +114,33 @@
      * this constructor</i>. Instead, they must use the
      * {@link #LocalVariablesSorter(int, int, String, MethodVisitor)} version.
      *
-     * @param access access flags of the adapted method.
-     * @param desc the method's descriptor (see {@link Type Type}).
-     * @param mv the method visitor to which this adapter delegates calls.
+     * @param access
+     *            access flags of the adapted method.
+     * @param desc
+     *            the method's descriptor (see {@link Type Type}).
+     * @param mv
+     *            the method visitor to which this adapter delegates calls.
      */
-    public LocalVariablesSorter(
-        final int access,
-        final String desc,
-        final MethodVisitor mv)
-    {
-        this(Opcodes.ASM4, access, desc, mv);
+    public LocalVariablesSorter(final int access, final String desc,
+            final MethodVisitor mv) {
+        this(Opcodes.ASM5, access, desc, mv);
     }
 
     /**
      * Creates a new {@link LocalVariablesSorter}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
-     * @param access access flags of the adapted method.
-     * @param desc the method's descriptor (see {@link Type Type}).
-     * @param mv the method visitor to which this adapter delegates calls.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param access
+     *            access flags of the adapted method.
+     * @param desc
+     *            the method's descriptor (see {@link Type Type}).
+     * @param mv
+     *            the method visitor to which this adapter delegates calls.
      */
-    protected LocalVariablesSorter(
-        final int api,
-        final int access,
-        final String desc,
-        final MethodVisitor mv)
-    {
+    protected LocalVariablesSorter(final int api, final int access,
+            final String desc, final MethodVisitor mv) {
         super(api, mv);
         Type[] args = Type.getArgumentTypes(desc);
         nextLocal = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0;
@@ -151,32 +154,32 @@
     public void visitVarInsn(final int opcode, final int var) {
         Type type;
         switch (opcode) {
-            case Opcodes.LLOAD:
-            case Opcodes.LSTORE:
-                type = Type.LONG_TYPE;
-                break;
+        case Opcodes.LLOAD:
+        case Opcodes.LSTORE:
+            type = Type.LONG_TYPE;
+            break;
 
-            case Opcodes.DLOAD:
-            case Opcodes.DSTORE:
-                type = Type.DOUBLE_TYPE;
-                break;
+        case Opcodes.DLOAD:
+        case Opcodes.DSTORE:
+            type = Type.DOUBLE_TYPE;
+            break;
 
-            case Opcodes.FLOAD:
-            case Opcodes.FSTORE:
-                type = Type.FLOAT_TYPE;
-                break;
+        case Opcodes.FLOAD:
+        case Opcodes.FSTORE:
+            type = Type.FLOAT_TYPE;
+            break;
 
-            case Opcodes.ILOAD:
-            case Opcodes.ISTORE:
-                type = Type.INT_TYPE;
-                break;
+        case Opcodes.ILOAD:
+        case Opcodes.ISTORE:
+            type = Type.INT_TYPE;
+            break;
 
-            default:
+        default:
             // case Opcodes.ALOAD:
             // case Opcodes.ASTORE:
             // case RET:
-                type = OBJECT_TYPE;
-                break;
+            type = OBJECT_TYPE;
+            break;
         }
         mv.visitVarInsn(opcode, remap(var, type));
     }
@@ -192,28 +195,32 @@
     }
 
     @Override
-    public void visitLocalVariable(
-        final String name,
-        final String desc,
-        final String signature,
-        final Label start,
-        final Label end,
-        final int index)
-    {
+    public void visitLocalVariable(final String name, final String desc,
+            final String signature, final Label start, final Label end,
+            final int index) {
         int newIndex = remap(index, Type.getType(desc));
         mv.visitLocalVariable(name, desc, signature, start, end, newIndex);
     }
 
     @Override
-    public void visitFrame(
-        final int type,
-        final int nLocal,
-        final Object[] local,
-        final int nStack,
-        final Object[] stack)
-    {
+    public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
+            TypePath typePath, Label[] start, Label[] end, int[] index,
+            String desc, boolean visible) {
+        Type t = Type.getType(desc);
+        int[] newIndex = new int[index.length];
+        for (int i = 0; i < newIndex.length; ++i) {
+            newIndex[i] = remap(index[i], t);
+        }
+        return mv.visitLocalVariableAnnotation(typeRef, typePath, start, end,
+                newIndex, desc, visible);
+    }
+
+    @Override
+    public void visitFrame(final int type, final int nLocal,
+            final Object[] local, final int nStack, final Object[] stack) {
         if (type != Opcodes.F_NEW) { // uncompressed frame
-            throw new IllegalStateException("ClassReader.accept() should be called with EXPAND_FRAMES flag");
+            throw new IllegalStateException(
+                    "ClassReader.accept() should be called with EXPAND_FRAMES flag");
         }
 
         if (!changed) { // optimization for the case where mapping = identity
@@ -225,6 +232,8 @@
         Object[] oldLocals = new Object[newLocals.length];
         System.arraycopy(newLocals, 0, oldLocals, 0, oldLocals.length);
 
+        updateNewLocals(newLocals);
+
         // copies types from 'local' to 'newLocals'
         // 'newLocals' already contains the variables added with 'newLocal'
 
@@ -280,50 +289,74 @@
     /**
      * Creates a new local variable of the given type.
      *
-     * @param type the type of the local variable to be created.
+     * @param type
+     *            the type of the local variable to be created.
      * @return the identifier of the newly created local variable.
      */
     public int newLocal(final Type type) {
         Object t;
         switch (type.getSort()) {
-            case Type.BOOLEAN:
-            case Type.CHAR:
-            case Type.BYTE:
-            case Type.SHORT:
-            case Type.INT:
-                t = Opcodes.INTEGER;
-                break;
-            case Type.FLOAT:
-                t = Opcodes.FLOAT;
-                break;
-            case Type.LONG:
-                t = Opcodes.LONG;
-                break;
-            case Type.DOUBLE:
-                t = Opcodes.DOUBLE;
-                break;
-            case Type.ARRAY:
-                t = type.getDescriptor();
-                break;
-            // case Type.OBJECT:
-            default:
-                t = type.getInternalName();
-                break;
+        case Type.BOOLEAN:
+        case Type.CHAR:
+        case Type.BYTE:
+        case Type.SHORT:
+        case Type.INT:
+            t = Opcodes.INTEGER;
+            break;
+        case Type.FLOAT:
+            t = Opcodes.FLOAT;
+            break;
+        case Type.LONG:
+            t = Opcodes.LONG;
+            break;
+        case Type.DOUBLE:
+            t = Opcodes.DOUBLE;
+            break;
+        case Type.ARRAY:
+            t = type.getDescriptor();
+            break;
+        // case Type.OBJECT:
+        default:
+            t = type.getInternalName();
+            break;
         }
-        int local = nextLocal;
-        nextLocal += type.getSize();
+        int local = newLocalMapping(type);
         setLocalType(local, type);
         setFrameLocal(local, t);
         return local;
     }
 
     /**
-     * Sets the current type of the given local variable. The default
-     * implementation of this method does nothing.
+     * Notifies subclasses that a new stack map frame is being visited. The
+     * array argument contains the stack map frame types corresponding to the
+     * local variables added with {@link #newLocal}. This method can update
+     * these types in place for the stack map frame being visited. The default
+     * implementation of this method does nothing, i.e. a local variable added
+     * with {@link #newLocal} will have the same type in all stack map frames.
+     * But this behavior is not always the desired one, for instance if a local
+     * variable is added in the middle of a try/catch block: the frame for the
+     * exception handler should have a TOP type for this new local.
      *
-     * @param local a local variable identifier, as returned by {@link #newLocal
-     *        newLocal()}.
-     * @param type the type of the value being stored in the local variable
+     * @param newLocals
+     *            the stack map frame types corresponding to the local variables
+     *            added with {@link #newLocal} (and null for the others). The
+     *            format of this array is the same as in
+     *            {@link MethodVisitor#visitFrame}, except that long and double
+     *            types use two slots. The types for the current stack map frame
+     *            must be updated in place in this array.
+     */
+    protected void updateNewLocals(Object[] newLocals) {
+    }
+
+    /**
+     * Notifies subclasses that a local variable has been added or remapped. The
+     * default implementation of this method does nothing.
+     *
+     * @param local
+     *            a local variable identifier, as returned by {@link #newLocal
+     *            newLocal()}.
+     * @param type
+     *            the type of the value being stored in the local variable.
      */
     protected void setLocalType(final int local, final Type type) {
     }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/Method.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/Method.java
index f13f97b..df97a36 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/Method.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/Method.java
@@ -103,8 +103,10 @@
     /**
      * Creates a new {@link Method}.
      *
-     * @param name the method's name.
-     * @param desc the method's descriptor.
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor.
      */
     public Method(final String name, final String desc) {
         this.name = name;
@@ -114,22 +116,23 @@
     /**
      * Creates a new {@link Method}.
      *
-     * @param name the method's name.
-     * @param returnType the method's return type.
-     * @param argumentTypes the method's argument types.
+     * @param name
+     *            the method's name.
+     * @param returnType
+     *            the method's return type.
+     * @param argumentTypes
+     *            the method's argument types.
      */
-    public Method(
-        final String name,
-        final Type returnType,
-        final Type[] argumentTypes)
-    {
+    public Method(final String name, final Type returnType,
+            final Type[] argumentTypes) {
         this(name, Type.getMethodDescriptor(returnType, argumentTypes));
     }
 
     /**
      * Creates a new {@link Method}.
      *
-     * @param m a java.lang.reflect method descriptor
+     * @param m
+     *            a java.lang.reflect method descriptor
      * @return a {@link Method} corresponding to the given Java method
      *         declaration.
      */
@@ -140,7 +143,8 @@
     /**
      * Creates a new {@link Method}.
      *
-     * @param c a java.lang.reflect constructor descriptor
+     * @param c
+     *            a java.lang.reflect constructor descriptor
      * @return a {@link Method} corresponding to the given Java constructor
      *         declaration.
      */
@@ -152,20 +156,20 @@
      * Returns a {@link Method} corresponding to the given Java method
      * declaration.
      *
-     * @param method a Java method declaration, without argument names, of the
-     *        form "returnType name (argumentType1, ... argumentTypeN)", where
-     *        the types are in plain Java (e.g. "int", "float",
-     *        "java.util.List", ...). Classes of the java.lang package can be
-     *        specified by their unqualified name; all other classes names must
-     *        be fully qualified.
+     * @param method
+     *            a Java method declaration, without argument names, of the form
+     *            "returnType name (argumentType1, ... argumentTypeN)", where
+     *            the types are in plain Java (e.g. "int", "float",
+     *            "java.util.List", ...). Classes of the java.lang package can
+     *            be specified by their unqualified name; all other classes
+     *            names must be fully qualified.
      * @return a {@link Method} corresponding to the given Java method
      *         declaration.
-     * @throws IllegalArgumentException if <code>method</code> could not get
-     *         parsed.
+     * @throws IllegalArgumentException
+     *             if <code>method</code> could not get parsed.
      */
     public static Method getMethod(final String method)
-            throws IllegalArgumentException
-    {
+            throws IllegalArgumentException {
         return getMethod(method, false);
     }
 
@@ -173,26 +177,26 @@
      * Returns a {@link Method} corresponding to the given Java method
      * declaration.
      *
-     * @param method a Java method declaration, without argument names, of the
-     *        form "returnType name (argumentType1, ... argumentTypeN)", where
-     *        the types are in plain Java (e.g. "int", "float",
-     *        "java.util.List", ...). Classes of the java.lang package may be
-     *        specified by their unqualified name, depending on the
-     *        defaultPackage argument; all other classes names must be fully
-     *        qualified.
-     * @param defaultPackage true if unqualified class names belong to the
-     *        default package, or false if they correspond to java.lang classes.
-     *        For instance "Object" means "Object" if this option is true, or
-     *        "java.lang.Object" otherwise.
+     * @param method
+     *            a Java method declaration, without argument names, of the form
+     *            "returnType name (argumentType1, ... argumentTypeN)", where
+     *            the types are in plain Java (e.g. "int", "float",
+     *            "java.util.List", ...). Classes of the java.lang package may
+     *            be specified by their unqualified name, depending on the
+     *            defaultPackage argument; all other classes names must be fully
+     *            qualified.
+     * @param defaultPackage
+     *            true if unqualified class names belong to the default package,
+     *            or false if they correspond to java.lang classes. For instance
+     *            "Object" means "Object" if this option is true, or
+     *            "java.lang.Object" otherwise.
      * @return a {@link Method} corresponding to the given Java method
      *         declaration.
-     * @throws IllegalArgumentException if <code>method</code> could not get
-     *         parsed.
+     * @throws IllegalArgumentException
+     *             if <code>method</code> could not get parsed.
      */
-    public static Method getMethod(
-        final String method,
-        final boolean defaultPackage) throws IllegalArgumentException
-    {
+    public static Method getMethod(final String method,
+            final boolean defaultPackage) throws IllegalArgumentException {
         int space = method.indexOf(' ');
         int start = method.indexOf('(', space) + 1;
         int end = method.indexOf(')', start);
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java
index 2035511..2b4f720 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java
@@ -66,8 +66,8 @@
 import jdk.internal.org.objectweb.asm.signature.SignatureWriter;
 
 /**
- * A class responsible for remapping types and names.
- * Subclasses can override the following methods:
+ * A class responsible for remapping types and names. Subclasses can override
+ * the following methods:
  *
  * <ul>
  * <li>{@link #map(String)} - map type</li>
@@ -82,34 +82,34 @@
     public String mapDesc(String desc) {
         Type t = Type.getType(desc);
         switch (t.getSort()) {
-            case Type.ARRAY:
-                String s = mapDesc(t.getElementType().getDescriptor());
-                for (int i = 0; i < t.getDimensions(); ++i) {
-                    s = '[' + s;
-                }
-                return s;
-            case Type.OBJECT:
-                String newType = map(t.getInternalName());
-                if (newType != null) {
-                    return 'L' + newType + ';';
-                }
+        case Type.ARRAY:
+            String s = mapDesc(t.getElementType().getDescriptor());
+            for (int i = 0; i < t.getDimensions(); ++i) {
+                s = '[' + s;
+            }
+            return s;
+        case Type.OBJECT:
+            String newType = map(t.getInternalName());
+            if (newType != null) {
+                return 'L' + newType + ';';
+            }
         }
         return desc;
     }
 
     private Type mapType(Type t) {
         switch (t.getSort()) {
-            case Type.ARRAY:
-                String s = mapDesc(t.getElementType().getDescriptor());
-                for (int i = 0; i < t.getDimensions(); ++i) {
-                    s = '[' + s;
-                }
-                return Type.getType(s);
-            case Type.OBJECT:
-                s = map(t.getInternalName());
-                return s != null ? Type.getObjectType(s) : t;
-            case Type.METHOD:
-                return Type.getMethodType(mapMethodDesc(t.getDescriptor()));
+        case Type.ARRAY:
+            String s = mapDesc(t.getElementType().getDescriptor());
+            for (int i = 0; i < t.getDimensions(); ++i) {
+                s = '[' + s;
+            }
+            return Type.getType(s);
+        case Type.OBJECT:
+            s = map(t.getInternalName());
+            return s != null ? Type.getObjectType(s) : t;
+        case Type.METHOD:
+            return Type.getMethodType(mapMethodDesc(t.getDescriptor()));
         }
         return t;
     }
@@ -135,18 +135,14 @@
                 needMapping = true;
             }
             if (needMapping) {
-                newTypes[i] = newType == null
-                    ? type
-                    : newType;
+                newTypes[i] = newType == null ? type : newType;
             }
         }
-        return needMapping
-           ? newTypes
-           : types;
+        return needMapping ? newTypes : types;
     }
 
     public String mapMethodDesc(String desc) {
-        if("()V".equals(desc)) {
+        if ("()V".equals(desc)) {
             return desc;
         }
 
@@ -156,7 +152,7 @@
             s.append(mapDesc(args[i].getDescriptor()));
         }
         Type returnType = Type.getReturnType(desc);
-        if(returnType == Type.VOID_TYPE) {
+        if (returnType == Type.VOID_TYPE) {
             s.append(")V");
             return s.toString();
         }
@@ -170,9 +166,8 @@
         }
         if (value instanceof Handle) {
             Handle h = (Handle) value;
-            return new Handle(h.getTag(),
-                    mapType(h.getOwner()),
-                    mapMethodName(h.getOwner(), h.getName(), h.getDesc()),
+            return new Handle(h.getTag(), mapType(h.getOwner()), mapMethodName(
+                    h.getOwner(), h.getName(), h.getDesc()),
                     mapMethodDesc(h.getDesc()));
         }
         return value;
@@ -180,9 +175,10 @@
 
     /**
      *
-     * @param typeSignature true if signature is a FieldTypeSignature, such as
-     *        the signature parameter of the ClassVisitor.visitField or
-     *        MethodVisitor.visitLocalVariable methods
+     * @param typeSignature
+     *            true if signature is a FieldTypeSignature, such as the
+     *            signature parameter of the ClassVisitor.visitField or
+     *            MethodVisitor.visitLocalVariable methods
      */
     public String mapSignature(String signature, boolean typeSignature) {
         if (signature == null) {
@@ -200,17 +196,19 @@
     }
 
     protected SignatureVisitor createRemappingSignatureAdapter(
-        SignatureVisitor v)
-    {
+            SignatureVisitor v) {
         return new RemappingSignatureAdapter(v, this);
     }
 
     /**
      * Map method name to the new name. Subclasses can override.
      *
-     * @param owner owner of the method.
-     * @param name name of the method.
-     * @param desc descriptor of the method.
+     * @param owner
+     *            owner of the method.
+     * @param name
+     *            name of the method.
+     * @param desc
+     *            descriptor of the method.
      * @return new name of the method
      */
     public String mapMethodName(String owner, String name, String desc) {
@@ -220,8 +218,10 @@
     /**
      * Map invokedynamic method name to the new name. Subclasses can override.
      *
-     * @param name name of the invokedynamic.
-     * @param desc descriptor of the invokedynamic.
+     * @param name
+     *            name of the invokedynamic.
+     * @param desc
+     *            descriptor of the invokedynamic.
      * @return new invokdynamic name.
      */
     public String mapInvokeDynamicMethodName(String name, String desc) {
@@ -231,9 +231,12 @@
     /**
      * Map field name to the new name. Subclasses can override.
      *
-     * @param owner owner of the field.
-     * @param name name of the field
-     * @param desc descriptor of the field
+     * @param owner
+     *            owner of the field.
+     * @param name
+     *            name of the field
+     * @param desc
+     *            descriptor of the field
      * @return new name of the field.
      */
     public String mapFieldName(String owner, String name, String desc) {
@@ -242,7 +245,6 @@
 
     /**
      * Map type name to the new name. Subclasses can override.
-     *
      */
     public String map(String typeName) {
         return typeName;
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingAnnotationAdapter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingAnnotationAdapter.java
index ebe510d..b9a1bc8 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingAnnotationAdapter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingAnnotationAdapter.java
@@ -71,18 +71,13 @@
 
     protected final Remapper remapper;
 
-    public RemappingAnnotationAdapter(
-        final AnnotationVisitor av,
-        final Remapper remapper)
-    {
-        this(Opcodes.ASM4, av, remapper);
+    public RemappingAnnotationAdapter(final AnnotationVisitor av,
+            final Remapper remapper) {
+        this(Opcodes.ASM5, av, remapper);
     }
 
-    protected RemappingAnnotationAdapter(
-        final int api,
-        final AnnotationVisitor av,
-        final Remapper remapper)
-    {
+    protected RemappingAnnotationAdapter(final int api,
+            final AnnotationVisitor av, final Remapper remapper) {
         super(api, av);
         this.remapper = remapper;
     }
@@ -100,16 +95,14 @@
     @Override
     public AnnotationVisitor visitAnnotation(String name, String desc) {
         AnnotationVisitor v = av.visitAnnotation(name, remapper.mapDesc(desc));
-        return v == null ? null : (v == av
-                ? this
+        return v == null ? null : (v == av ? this
                 : new RemappingAnnotationAdapter(v, remapper));
     }
 
     @Override
     public AnnotationVisitor visitArray(String name) {
         AnnotationVisitor v = av.visitArray(name);
-        return v == null ? null : (v == av
-                ? this
+        return v == null ? null : (v == av ? this
                 : new RemappingAnnotationAdapter(v, remapper));
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingClassAdapter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingClassAdapter.java
index 44fe939..28b736b 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingClassAdapter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingClassAdapter.java
@@ -64,6 +64,7 @@
 import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.TypePath;
 
 /**
  * A {@link ClassVisitor} for type remapping.
@@ -76,96 +77,74 @@
 
     protected String className;
 
-    public RemappingClassAdapter(final ClassVisitor cv, final Remapper remapper)
-    {
-        this(Opcodes.ASM4, cv, remapper);
+    public RemappingClassAdapter(final ClassVisitor cv, final Remapper remapper) {
+        this(Opcodes.ASM5, cv, remapper);
     }
 
-    protected RemappingClassAdapter(
-        final int api,
-        final ClassVisitor cv,
-        final Remapper remapper)
-    {
+    protected RemappingClassAdapter(final int api, final ClassVisitor cv,
+            final Remapper remapper) {
         super(api, cv);
         this.remapper = remapper;
     }
 
     @Override
-    public void visit(
-        int version,
-        int access,
-        String name,
-        String signature,
-        String superName,
-        String[] interfaces)
-    {
+    public void visit(int version, int access, String name, String signature,
+            String superName, String[] interfaces) {
         this.className = name;
-        super.visit(version,
-                access,
-                remapper.mapType(name),
-                remapper.mapSignature(signature, false),
-                remapper.mapType(superName),
-                interfaces == null ? null
-                        : remapper.mapTypes(interfaces));
+        super.visit(version, access, remapper.mapType(name), remapper
+                .mapSignature(signature, false), remapper.mapType(superName),
+                interfaces == null ? null : remapper.mapTypes(interfaces));
     }
 
     @Override
     public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        AnnotationVisitor av;
-        av = super.visitAnnotation(remapper.mapDesc(desc), visible);
+        AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
+                visible);
         return av == null ? null : createRemappingAnnotationAdapter(av);
     }
 
     @Override
-    public FieldVisitor visitField(
-        int access,
-        String name,
-        String desc,
-        String signature,
-        Object value)
-    {
+    public AnnotationVisitor visitTypeAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath,
+                remapper.mapDesc(desc), visible);
+        return av == null ? null : createRemappingAnnotationAdapter(av);
+    }
+
+    @Override
+    public FieldVisitor visitField(int access, String name, String desc,
+            String signature, Object value) {
         FieldVisitor fv = super.visitField(access,
                 remapper.mapFieldName(className, name, desc),
-                remapper.mapDesc(desc),
-                remapper.mapSignature(signature, true),
+                remapper.mapDesc(desc), remapper.mapSignature(signature, true),
                 remapper.mapValue(value));
         return fv == null ? null : createRemappingFieldAdapter(fv);
     }
 
     @Override
-    public MethodVisitor visitMethod(
-        int access,
-        String name,
-        String desc,
-        String signature,
-        String[] exceptions)
-    {
+    public MethodVisitor visitMethod(int access, String name, String desc,
+            String signature, String[] exceptions) {
         String newDesc = remapper.mapMethodDesc(desc);
-        MethodVisitor mv = super.visitMethod(access,
-                remapper.mapMethodName(className, name, desc),
-                newDesc,
-                remapper.mapSignature(signature, false),
+        MethodVisitor mv = super.visitMethod(access, remapper.mapMethodName(
+                className, name, desc), newDesc, remapper.mapSignature(
+                signature, false),
                 exceptions == null ? null : remapper.mapTypes(exceptions));
-        return mv == null ? null : createRemappingMethodAdapter(access, newDesc, mv);
+        return mv == null ? null : createRemappingMethodAdapter(access,
+                newDesc, mv);
     }
 
     @Override
-    public void visitInnerClass(
-        String name,
-        String outerName,
-        String innerName,
-        int access)
-    {
-        super.visitInnerClass(remapper.mapType(name),
-                outerName == null ? null : remapper.mapType(outerName),
-                innerName, // TODO should it be changed?
-                access);
+    public void visitInnerClass(String name, String outerName,
+            String innerName, int access) {
+        // TODO should innerName be changed?
+        super.visitInnerClass(remapper.mapType(name), outerName == null ? null
+                : remapper.mapType(outerName), innerName, access);
     }
 
     @Override
     public void visitOuterClass(String owner, String name, String desc) {
-        super.visitOuterClass(remapper.mapType(owner),
-                name == null ? null : remapper.mapMethodName(owner, name, desc),
+        super.visitOuterClass(remapper.mapType(owner), name == null ? null
+                : remapper.mapMethodName(owner, name, desc),
                 desc == null ? null : remapper.mapMethodDesc(desc));
     }
 
@@ -173,17 +152,13 @@
         return new RemappingFieldAdapter(fv, remapper);
     }
 
-    protected MethodVisitor createRemappingMethodAdapter(
-        int access,
-        String newDesc,
-        MethodVisitor mv)
-    {
+    protected MethodVisitor createRemappingMethodAdapter(int access,
+            String newDesc, MethodVisitor mv) {
         return new RemappingMethodAdapter(access, newDesc, mv, remapper);
     }
 
     protected AnnotationVisitor createRemappingAnnotationAdapter(
-        AnnotationVisitor av)
-    {
+            AnnotationVisitor av) {
         return new RemappingAnnotationAdapter(av, remapper);
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingFieldAdapter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingFieldAdapter.java
index a47da70..9d94e5e 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingFieldAdapter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingFieldAdapter.java
@@ -62,6 +62,7 @@
 import jdk.internal.org.objectweb.asm.AnnotationVisitor;
 import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.TypePath;
 
 /**
  * A {@link FieldVisitor} adapter for type remapping.
@@ -72,23 +73,28 @@
 
     private final Remapper remapper;
 
-    public RemappingFieldAdapter(final FieldVisitor fv, final Remapper remapper)
-    {
-        this(Opcodes.ASM4, fv, remapper);
+    public RemappingFieldAdapter(final FieldVisitor fv, final Remapper remapper) {
+        this(Opcodes.ASM5, fv, remapper);
     }
 
-    protected RemappingFieldAdapter(
-        final int api,
-        final FieldVisitor fv,
-        final Remapper remapper)
-    {
+    protected RemappingFieldAdapter(final int api, final FieldVisitor fv,
+            final Remapper remapper) {
         super(api, fv);
         this.remapper = remapper;
     }
 
     @Override
     public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        AnnotationVisitor av = fv.visitAnnotation(remapper.mapDesc(desc), visible);
+        AnnotationVisitor av = fv.visitAnnotation(remapper.mapDesc(desc),
+                visible);
+        return av == null ? null : new RemappingAnnotationAdapter(av, remapper);
+    }
+
+    @Override
+    public AnnotationVisitor visitTypeAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath,
+                remapper.mapDesc(desc), visible);
         return av == null ? null : new RemappingAnnotationAdapter(av, remapper);
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java
index d4612b1..319d9de 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java
@@ -64,6 +64,7 @@
 import jdk.internal.org.objectweb.asm.Label;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.TypePath;
 
 /**
  * A {@link LocalVariablesSorter} for type mapping.
@@ -74,59 +75,51 @@
 
     protected final Remapper remapper;
 
-    public RemappingMethodAdapter(
-        final int access,
-        final String desc,
-        final MethodVisitor mv,
-        final Remapper remapper)
-    {
-        this(Opcodes.ASM4, access, desc, mv, remapper);
+    public RemappingMethodAdapter(final int access, final String desc,
+            final MethodVisitor mv, final Remapper remapper) {
+        this(Opcodes.ASM5, access, desc, mv, remapper);
     }
 
-    protected RemappingMethodAdapter(
-        final int api,
-        final int access,
-        final String desc,
-        final MethodVisitor mv,
-        final Remapper remapper)
-    {
+    protected RemappingMethodAdapter(final int api, final int access,
+            final String desc, final MethodVisitor mv, final Remapper remapper) {
         super(api, access, desc, mv);
         this.remapper = remapper;
     }
 
     @Override
     public AnnotationVisitor visitAnnotationDefault() {
-        AnnotationVisitor av = mv.visitAnnotationDefault();
+        AnnotationVisitor av = super.visitAnnotationDefault();
         return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
     }
 
     @Override
     public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        AnnotationVisitor av = mv.visitAnnotation(remapper.mapDesc(desc), visible);
-        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
-    }
-
-    @Override
-    public AnnotationVisitor visitParameterAnnotation(
-        int parameter,
-        String desc,
-        boolean visible)
-    {
-        AnnotationVisitor av = mv.visitParameterAnnotation(parameter,
-                remapper.mapDesc(desc),
+        AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
                 visible);
         return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
     }
 
     @Override
-    public void visitFrame(
-        int type,
-        int nLocal,
-        Object[] local,
-        int nStack,
-        Object[] stack)
-    {
-        super.visitFrame(type, nLocal, remapEntries(nLocal, local), nStack, remapEntries(nStack, stack));
+    public AnnotationVisitor visitTypeAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath,
+                remapper.mapDesc(desc), visible);
+        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
+    }
+
+    @Override
+    public AnnotationVisitor visitParameterAnnotation(int parameter,
+            String desc, boolean visible) {
+        AnnotationVisitor av = super.visitParameterAnnotation(parameter,
+                remapper.mapDesc(desc), visible);
+        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
+    }
+
+    @Override
+    public void visitFrame(int type, int nLocal, Object[] local, int nStack,
+            Object[] stack) {
+        super.visitFrame(type, nLocal, remapEntries(nLocal, local), nStack,
+                remapEntries(nStack, stack));
     }
 
     private Object[] remapEntries(int n, Object[] entries) {
@@ -138,9 +131,8 @@
                 }
                 do {
                     Object t = entries[i];
-                    newEntries[i++] = t instanceof String
-                            ? remapper.mapType((String) t)
-                            : t;
+                    newEntries[i++] = t instanceof String ? remapper
+                            .mapType((String) t) : t;
                 } while (i < n);
                 return newEntries;
             }
@@ -149,45 +141,30 @@
     }
 
     @Override
-    public void visitFieldInsn(
-        int opcode,
-        String owner,
-        String name,
-        String desc)
-    {
-        super.visitFieldInsn(opcode,
-                remapper.mapType(owner),
+    public void visitFieldInsn(int opcode, String owner, String name,
+            String desc) {
+        super.visitFieldInsn(opcode, remapper.mapType(owner),
                 remapper.mapFieldName(owner, name, desc),
                 remapper.mapDesc(desc));
     }
 
     @Override
-    public void visitMethodInsn(
-        int opcode,
-        String owner,
-        String name,
-        String desc)
-    {
-        super.visitMethodInsn(opcode,
-                remapper.mapType(owner),
+    public void visitMethodInsn(int opcode, String owner, String name,
+            String desc) {
+        super.visitMethodInsn(opcode, remapper.mapType(owner),
                 remapper.mapMethodName(owner, name, desc),
                 remapper.mapMethodDesc(desc));
     }
 
     @Override
-    public void visitInvokeDynamicInsn(
-        String name,
-        String desc,
-        Handle bsm,
-        Object... bsmArgs)
-    {
-        for(int i=0; i<bsmArgs.length; i++) {
+    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+            Object... bsmArgs) {
+        for (int i = 0; i < bsmArgs.length; i++) {
             bsmArgs[i] = remapper.mapValue(bsmArgs[i]);
         }
         super.visitInvokeDynamicInsn(
                 remapper.mapInvokeDynamicMethodName(name, desc),
-                remapper.mapMethodDesc(desc),
-                (Handle)remapper.mapValue(bsm),
+                remapper.mapMethodDesc(desc), (Handle) remapper.mapValue(bsm),
                 bsmArgs);
     }
 
@@ -207,30 +184,41 @@
     }
 
     @Override
-    public void visitTryCatchBlock(
-        Label start,
-        Label end,
-        Label handler,
-        String type)
-    {
-        super.visitTryCatchBlock(start, end, handler,
-                type == null ? null : remapper.mapType(type));
+    public AnnotationVisitor visitInsnAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        AnnotationVisitor av = super.visitInsnAnnotation(typeRef, typePath,
+                remapper.mapDesc(desc), visible);
+        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
     }
 
     @Override
-    public void visitLocalVariable(
-        String name,
-        String desc,
-        String signature,
-        Label start,
-        Label end,
-        int index)
-    {
-        super.visitLocalVariable(name,
-                remapper.mapDesc(desc),
-                remapper.mapSignature(signature, true),
-                start,
-                end,
-                index);
+    public void visitTryCatchBlock(Label start, Label end, Label handler,
+            String type) {
+        super.visitTryCatchBlock(start, end, handler, type == null ? null
+                : remapper.mapType(type));
+    }
+
+    @Override
+    public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        AnnotationVisitor av = super.visitTryCatchAnnotation(typeRef, typePath,
+                remapper.mapDesc(desc), visible);
+        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
+    }
+
+    @Override
+    public void visitLocalVariable(String name, String desc, String signature,
+            Label start, Label end, int index) {
+        super.visitLocalVariable(name, remapper.mapDesc(desc),
+                remapper.mapSignature(signature, true), start, end, index);
+    }
+
+    @Override
+    public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
+            TypePath typePath, Label[] start, Label[] end, int[] index,
+            String desc, boolean visible) {
+        AnnotationVisitor av = super.visitLocalVariableAnnotation(typeRef,
+                typePath, start, end, index, remapper.mapDesc(desc), visible);
+        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingSignatureAdapter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingSignatureAdapter.java
index e4c8071..458ee69 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingSignatureAdapter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingSignatureAdapter.java
@@ -75,18 +75,13 @@
 
     private String className;
 
-    public RemappingSignatureAdapter(
-        final SignatureVisitor v,
-        final Remapper remapper)
-    {
-        this(Opcodes.ASM4, v, remapper);
+    public RemappingSignatureAdapter(final SignatureVisitor v,
+            final Remapper remapper) {
+        this(Opcodes.ASM5, v, remapper);
     }
 
-    protected RemappingSignatureAdapter(
-        final int api,
-        final SignatureVisitor v,
-        final Remapper remapper)
-    {
+    protected RemappingSignatureAdapter(final int api,
+            final SignatureVisitor v, final Remapper remapper) {
         super(api);
         this.v = v;
         this.remapper = remapper;
@@ -102,7 +97,8 @@
     public void visitInnerClassType(String name) {
         className = className + '$' + name;
         String remappedName = remapper.mapType(className);
-        v.visitInnerClassType(remappedName.substring(remappedName.lastIndexOf('$') + 1));
+        v.visitInnerClassType(remappedName.substring(remappedName
+                .lastIndexOf('$') + 1));
     }
 
     @Override
@@ -183,5 +179,4 @@
     public void visitEnd() {
         v.visitEnd();
     }
-
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java
index 03e36ee..4050d0c 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java
@@ -192,20 +192,23 @@
      * this constructor</i>. Instead, they must use the
      * {@link #SerialVersionUIDAdder(int, ClassVisitor)} version.
      *
-     * @param cv a {@link ClassVisitor} to which this visitor will delegate
-     *        calls.
+     * @param cv
+     *            a {@link ClassVisitor} to which this visitor will delegate
+     *            calls.
      */
     public SerialVersionUIDAdder(final ClassVisitor cv) {
-        this(Opcodes.ASM4, cv);
+        this(Opcodes.ASM5, cv);
     }
 
     /**
      * Creates a new {@link SerialVersionUIDAdder}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
-     * @param cv a {@link ClassVisitor} to which this visitor will delegate
-     *        calls.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param cv
+     *            a {@link ClassVisitor} to which this visitor will delegate
+     *            calls.
      */
     protected SerialVersionUIDAdder(final int api, final ClassVisitor cv) {
         super(api, cv);
@@ -223,14 +226,9 @@
      * information (step 1,2, and 3) for SVUID computation.
      */
     @Override
-    public void visit(
-        final int version,
-        final int access,
-        final String name,
-        final String signature,
-        final String superName,
-        final String[] interfaces)
-    {
+    public void visit(final int version, final int access, final String name,
+            final String signature, final String superName,
+            final String[] interfaces) {
         computeSVUID = (access & Opcodes.ACC_INTERFACE) == 0;
 
         if (computeSVUID) {
@@ -247,13 +245,8 @@
      * 7). Also determine if there is a class initializer (step 6).
      */
     @Override
-    public MethodVisitor visitMethod(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final String[] exceptions)
-    {
+    public MethodVisitor visitMethod(final int access, final String name,
+            final String desc, final String signature, final String[] exceptions) {
         if (computeSVUID) {
             if ("<clinit>".equals(name)) {
                 hasStaticInitializer = true;
@@ -289,13 +282,8 @@
      * if the class already has a SVUID.
      */
     @Override
-    public FieldVisitor visitField(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final Object value)
-    {
+    public FieldVisitor visitField(final int access, final String name,
+            final String desc, final String signature, final Object value) {
         if (computeSVUID) {
             if ("serialVersionUID".equals(name)) {
                 // since the class already has SVUID, we won't be computing it.
@@ -309,12 +297,11 @@
              * computing serialVersionUID values.
              */
             if ((access & Opcodes.ACC_PRIVATE) == 0
-                    || (access & (Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT)) == 0)
-            {
+                    || (access & (Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT)) == 0) {
                 int mods = access
-                & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE
-                        | Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC
-                        | Opcodes.ACC_FINAL | Opcodes.ACC_VOLATILE | Opcodes.ACC_TRANSIENT);
+                        & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE
+                                | Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC
+                                | Opcodes.ACC_FINAL | Opcodes.ACC_VOLATILE | Opcodes.ACC_TRANSIENT);
                 svuidFields.add(new Item(name, mods, desc));
             }
         }
@@ -330,7 +317,8 @@
      * the class file in favor of the access bits InnerClass attribute.
      */
     @Override
-    public void visitInnerClass(final String aname, final String outerName, final String innerName, final int attr_access) {
+    public void visitInnerClass(final String aname, final String outerName,
+            final String innerName, final int attr_access) {
         if ((name != null) && name.equals(aname)) {
             this.access = attr_access;
         }
@@ -345,11 +333,7 @@
         // compute SVUID and add it to the class
         if (computeSVUID && !hasSVUID) {
             try {
-                super.visitField(Opcodes.ACC_FINAL + Opcodes.ACC_STATIC,
-                        "serialVersionUID",
-                        "J",
-                        null,
-                        new Long(computeSVUID()));
+                addSVUID(computeSVUID());
             } catch (Throwable e) {
                 throw new RuntimeException("Error while computing SVUID for "
                         + name, e);
@@ -364,12 +348,30 @@
     // ------------------------------------------------------------------------
 
     /**
-     * Returns the value of SVUID if the class doesn't have one already. Please
-     * note that 0 is returned if the class already has SVUID, thus use
-     * <code>isHasSVUID</code> to determine if the class already had an SVUID.
+     * Returns true if the class already has a SVUID field. The result of this
+     * method is only valid when visitEnd is or has been called.
+     *
+     * @return true if the class already has a SVUID field.
+     */
+    public boolean hasSVUID() {
+        return hasSVUID;
+    }
+
+    protected void addSVUID(long svuid) {
+        FieldVisitor fv = super.visitField(Opcodes.ACC_FINAL
+                + Opcodes.ACC_STATIC, "serialVersionUID", "J", null, new Long(
+                svuid));
+        if (fv != null) {
+            fv.visitEnd();
+        }
+    }
+
+    /**
+     * Computes and returns the value of SVUID.
      *
      * @return Returns the serial version UID
-     * @throws IOException if an I/O error occurs
+     * @throws IOException
+     *             if an I/O error occurs
      */
     protected long computeSVUID() throws IOException {
         ByteArrayOutputStream bos;
@@ -459,8 +461,8 @@
              * five int values named sha, the hash value would be computed as
              * follows:
              *
-             * long hash = ((sha[0] >>> 24) & 0xFF) | ((sha[0] >>> 16) & 0xFF) <<
-             * 8 | ((sha[0] >>> 8) & 0xFF) << 16 | ((sha[0] >>> 0) & 0xFF) <<
+             * long hash = ((sha[0] >>> 24) & 0xFF) | ((sha[0] >>> 16) & 0xFF)
+             * << 8 | ((sha[0] >>> 8) & 0xFF) << 16 | ((sha[0] >>> 0) & 0xFF) <<
              * 24 | ((sha[1] >>> 24) & 0xFF) << 32 | ((sha[1] >>> 16) & 0xFF) <<
              * 40 | ((sha[1] >>> 8) & 0xFF) << 48 | ((sha[1] >>> 0) & 0xFF) <<
              * 56;
@@ -481,7 +483,8 @@
     /**
      * Returns the SHA-1 message digest of the given value.
      *
-     * @param value the value whose SHA message digest must be computed.
+     * @param value
+     *            the value whose SHA message digest must be computed.
      * @return the SHA-1 message digest of the given value.
      */
     protected byte[] computeSHAdigest(final byte[] value) {
@@ -495,24 +498,24 @@
     /**
      * Sorts the items in the collection and writes it to the data output stream
      *
-     * @param itemCollection collection of items
-     * @param dos a <code>DataOutputStream</code> value
-     * @param dotted a <code>boolean</code> value
-     * @exception IOException if an error occurs
+     * @param itemCollection
+     *            collection of items
+     * @param dos
+     *            a <code>DataOutputStream</code> value
+     * @param dotted
+     *            a <code>boolean</code> value
+     * @exception IOException
+     *                if an error occurs
      */
-    private static void writeItems(
-        final Collection<Item> itemCollection,
-        final DataOutput dos,
-        final boolean dotted) throws IOException
-    {
+    private static void writeItems(final Collection<Item> itemCollection,
+            final DataOutput dos, final boolean dotted) throws IOException {
         int size = itemCollection.size();
         Item[] items = itemCollection.toArray(new Item[size]);
         Arrays.sort(items);
         for (int i = 0; i < size; i++) {
             dos.writeUTF(items[i].name);
             dos.writeInt(items[i].access);
-            dos.writeUTF(dotted
-                    ? items[i].desc.replace('/', '.')
+            dos.writeUTF(dotted ? items[i].desc.replace('/', '.')
                     : items[i].desc);
         }
     }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/StaticInitMerger.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/StaticInitMerger.java
index f459734..3514d09 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/StaticInitMerger.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/StaticInitMerger.java
@@ -78,39 +78,26 @@
     private int counter;
 
     public StaticInitMerger(final String prefix, final ClassVisitor cv) {
-        this(Opcodes.ASM4, prefix, cv);
+        this(Opcodes.ASM5, prefix, cv);
     }
 
-    protected StaticInitMerger(
-        final int api,
-        final String prefix,
-        final ClassVisitor cv)
-    {
+    protected StaticInitMerger(final int api, final String prefix,
+            final ClassVisitor cv) {
         super(api, cv);
         this.prefix = prefix;
     }
 
     @Override
-    public void visit(
-        final int version,
-        final int access,
-        final String name,
-        final String signature,
-        final String superName,
-        final String[] interfaces)
-    {
+    public void visit(final int version, final int access, final String name,
+            final String signature, final String superName,
+            final String[] interfaces) {
         cv.visit(version, access, name, signature, superName, interfaces);
         this.name = name;
     }
 
     @Override
-    public MethodVisitor visitMethod(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final String[] exceptions)
-    {
+    public MethodVisitor visitMethod(final int access, final String name,
+            final String desc, final String signature, final String[] exceptions) {
         MethodVisitor mv;
         if ("<clinit>".equals(name)) {
             int a = Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC;
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/TableSwitchGenerator.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/TableSwitchGenerator.java
index a500983..98d2a7f 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/TableSwitchGenerator.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/TableSwitchGenerator.java
@@ -72,8 +72,10 @@
     /**
      * Generates the code for a switch case.
      *
-     * @param key the switch case key.
-     * @param end a label that corresponds to the end of the switch statement.
+     * @param key
+     *            the switch case key.
+     * @param end
+     *            a label that corresponds to the end of the switch statement.
      */
     void generateCase(int key, Label end);
 
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/TryCatchBlockSorter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/TryCatchBlockSorter.java
index dd024e3..0b2be35 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/TryCatchBlockSorter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/TryCatchBlockSorter.java
@@ -66,6 +66,7 @@
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.tree.MethodNode;
 import jdk.internal.org.objectweb.asm.tree.TryCatchBlockNode;
+import jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode;
 
 /**
  * A {@link MethodVisitor} adapter to sort the exception handlers. The handlers
@@ -83,26 +84,15 @@
  */
 public class TryCatchBlockSorter extends MethodNode {
 
-    public TryCatchBlockSorter(
-        final MethodVisitor mv,
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final String[] exceptions)
-    {
-        this(Opcodes.ASM4, mv, access, name, desc, signature, exceptions);
+    public TryCatchBlockSorter(final MethodVisitor mv, final int access,
+            final String name, final String desc, final String signature,
+            final String[] exceptions) {
+        this(Opcodes.ASM5, mv, access, name, desc, signature, exceptions);
     }
 
-    protected TryCatchBlockSorter(
-        final int api,
-        final MethodVisitor mv,
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final String[] exceptions)
-    {
+    protected TryCatchBlockSorter(final int api, final MethodVisitor mv,
+            final int access, final String name, final String desc,
+            final String signature, final String[] exceptions) {
         super(api, access, name, desc, signature, exceptions);
         this.mv = mv;
     }
@@ -125,6 +115,10 @@
             }
         };
         Collections.sort(tryCatchBlocks, comp);
+        // Updates the 'target' of each try catch block annotation.
+        for (int i = 0; i < tryCatchBlocks.size(); ++i) {
+            tryCatchBlocks.get(i).updateIndex(i);
+        }
         if (mv != null) {
             accept(mv);
         }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureReader.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureReader.java
index b737c12..50bb566 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureReader.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureReader.java
@@ -75,8 +75,9 @@
     /**
      * Constructs a {@link SignatureReader} for the given signature.
      *
-     * @param signature A <i>ClassSignature</i>, <i>MethodTypeSignature</i>,
-     *        or <i>FieldTypeSignature</i>.
+     * @param signature
+     *            A <i>ClassSignature</i>, <i>MethodTypeSignature</i>, or
+     *            <i>FieldTypeSignature</i>.
      */
     public SignatureReader(final String signature) {
         this.signature = signature;
@@ -87,15 +88,15 @@
      * {@link SignatureReader}. This signature is the one specified in the
      * constructor (see {@link #SignatureReader(String) SignatureReader}). This
      * method is intended to be called on a {@link SignatureReader} that was
-     * created using a <i>ClassSignature</i> (such as the
+     * created using a <i>ClassSignature</i> (such as the <code>signature</code>
+     * parameter of the {@link jdk.internal.org.objectweb.asm.ClassVisitor#visit
+     * ClassVisitor.visit} method) or a <i>MethodTypeSignature</i> (such as the
      * <code>signature</code> parameter of the
-     * {@link jdk.internal.org.objectweb.asm.ClassVisitor#visit ClassVisitor.visit} method)
-     * or a <i>MethodTypeSignature</i> (such as the <code>signature</code>
-     * parameter of the
-     * {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitMethod ClassVisitor.visitMethod}
-     * method).
+     * {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitMethod
+     * ClassVisitor.visitMethod} method).
      *
-     * @param v the visitor that must visit this signature.
+     * @param v
+     *            the visitor that must visit this signature.
      */
     public void accept(final SignatureVisitor v) {
         String signature = this.signature;
@@ -147,12 +148,12 @@
      * method is intended to be called on a {@link SignatureReader} that was
      * created using a <i>FieldTypeSignature</i>, such as the
      * <code>signature</code> parameter of the
-     * {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitField
-     * ClassVisitor.visitField} or {@link
-     * jdk.internal.org.objectweb.asm.MethodVisitor#visitLocalVariable
+     * {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitField ClassVisitor.visitField}
+     * or {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLocalVariable
      * MethodVisitor.visitLocalVariable} methods.
      *
-     * @param v the visitor that must visit this signature.
+     * @param v
+     *            the visitor that must visit this signature.
      */
     public void acceptType(final SignatureVisitor v) {
         parseType(this.signature, 0, v);
@@ -161,98 +162,96 @@
     /**
      * Parses a field type signature and makes the given visitor visit it.
      *
-     * @param signature a string containing the signature that must be parsed.
-     * @param pos index of the first character of the signature to parsed.
-     * @param v the visitor that must visit this signature.
+     * @param signature
+     *            a string containing the signature that must be parsed.
+     * @param pos
+     *            index of the first character of the signature to parsed.
+     * @param v
+     *            the visitor that must visit this signature.
      * @return the index of the first character after the parsed signature.
      */
-    private static int parseType(
-        final String signature,
-        int pos,
-        final SignatureVisitor v)
-    {
+    private static int parseType(final String signature, int pos,
+            final SignatureVisitor v) {
         char c;
         int start, end;
         boolean visited, inner;
         String name;
 
         switch (c = signature.charAt(pos++)) {
-            case 'Z':
-            case 'C':
-            case 'B':
-            case 'S':
-            case 'I':
-            case 'F':
-            case 'J':
-            case 'D':
-            case 'V':
-                v.visitBaseType(c);
-                return pos;
+        case 'Z':
+        case 'C':
+        case 'B':
+        case 'S':
+        case 'I':
+        case 'F':
+        case 'J':
+        case 'D':
+        case 'V':
+            v.visitBaseType(c);
+            return pos;
 
-            case '[':
-                return parseType(signature, pos, v.visitArrayType());
+        case '[':
+            return parseType(signature, pos, v.visitArrayType());
 
-            case 'T':
-                end = signature.indexOf(';', pos);
-                v.visitTypeVariable(signature.substring(pos, end));
-                return end + 1;
+        case 'T':
+            end = signature.indexOf(';', pos);
+            v.visitTypeVariable(signature.substring(pos, end));
+            return end + 1;
 
-            default: // case 'L':
-                start = pos;
-                visited = false;
-                inner = false;
-                for (;;) {
-                    switch (c = signature.charAt(pos++)) {
-                        case '.':
-                        case ';':
-                            if (!visited) {
-                                name = signature.substring(start, pos - 1);
-                                if (inner) {
-                                    v.visitInnerClassType(name);
-                                } else {
-                                    v.visitClassType(name);
-                                }
-                            }
-                            if (c == ';') {
-                                v.visitEnd();
-                                return pos;
-                            }
-                            start = pos;
-                            visited = false;
-                            inner = true;
+        default: // case 'L':
+            start = pos;
+            visited = false;
+            inner = false;
+            for (;;) {
+                switch (c = signature.charAt(pos++)) {
+                case '.':
+                case ';':
+                    if (!visited) {
+                        name = signature.substring(start, pos - 1);
+                        if (inner) {
+                            v.visitInnerClassType(name);
+                        } else {
+                            v.visitClassType(name);
+                        }
+                    }
+                    if (c == ';') {
+                        v.visitEnd();
+                        return pos;
+                    }
+                    start = pos;
+                    visited = false;
+                    inner = true;
+                    break;
+
+                case '<':
+                    name = signature.substring(start, pos - 1);
+                    if (inner) {
+                        v.visitInnerClassType(name);
+                    } else {
+                        v.visitClassType(name);
+                    }
+                    visited = true;
+                    top: for (;;) {
+                        switch (c = signature.charAt(pos)) {
+                        case '>':
+                            break top;
+                        case '*':
+                            ++pos;
+                            v.visitTypeArgument();
                             break;
-
-                        case '<':
-                            name = signature.substring(start, pos - 1);
-                            if (inner) {
-                                v.visitInnerClassType(name);
-                            } else {
-                                v.visitClassType(name);
-                            }
-                            visited = true;
-                            top: for (;;) {
-                                switch (c = signature.charAt(pos)) {
-                                    case '>':
-                                        break top;
-                                    case '*':
-                                        ++pos;
-                                        v.visitTypeArgument();
-                                        break;
-                                    case '+':
-                                    case '-':
-                                        pos = parseType(signature,
-                                                pos + 1,
-                                                v.visitTypeArgument(c));
-                                        break;
-                                    default:
-                                        pos = parseType(signature,
-                                                pos,
-                                                v.visitTypeArgument('='));
-                                        break;
-                                }
-                            }
+                        case '+':
+                        case '-':
+                            pos = parseType(signature, pos + 1,
+                                    v.visitTypeArgument(c));
+                            break;
+                        default:
+                            pos = parseType(signature, pos,
+                                    v.visitTypeArgument('='));
+                            break;
+                        }
                     }
                 }
+            }
         }
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureVisitor.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureVisitor.java
index d3699c1..5b9cb70 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureVisitor.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureVisitor.java
@@ -64,21 +64,21 @@
  * A visitor to visit a generic signature. The methods of this interface must be
  * called in one of the three following orders (the last one is the only valid
  * order for a {@link SignatureVisitor} that is returned by a method of this
- * interface): <ul> <li><i>ClassSignature</i> = (
- * <tt>visitFormalTypeParameter</tt>
- *   <tt>visitClassBound</tt>?
- * <tt>visitInterfaceBound</tt>* )* ( <tt>visitSuperClass</tt>
- *   <tt>visitInterface</tt>* )</li>
+ * interface):
+ * <ul>
+ * <li><i>ClassSignature</i> = ( <tt>visitFormalTypeParameter</tt>
+ * <tt>visitClassBound</tt>? <tt>visitInterfaceBound</tt>* )* (
+ * <tt>visitSuperClass</tt> <tt>visitInterface</tt>* )</li>
  * <li><i>MethodSignature</i> = ( <tt>visitFormalTypeParameter</tt>
- *   <tt>visitClassBound</tt>?
- * <tt>visitInterfaceBound</tt>* )* ( <tt>visitParameterType</tt>*
- * <tt>visitReturnType</tt>
- *   <tt>visitExceptionType</tt>* )</li> <li><i>TypeSignature</i> =
- * <tt>visitBaseType</tt> | <tt>visitTypeVariable</tt> |
- * <tt>visitArrayType</tt> | (
+ * <tt>visitClassBound</tt>? <tt>visitInterfaceBound</tt>* )* (
+ * <tt>visitParameterType</tt>* <tt>visitReturnType</tt>
+ * <tt>visitExceptionType</tt>* )</li>
+ * <li><i>TypeSignature</i> = <tt>visitBaseType</tt> |
+ * <tt>visitTypeVariable</tt> | <tt>visitArrayType</tt> | (
  * <tt>visitClassType</tt> <tt>visitTypeArgument</tt>* (
- * <tt>visitInnerClassType</tt> <tt>visitTypeArgument</tt>* )*
- * <tt>visitEnd</tt> ) )</li> </ul>
+ * <tt>visitInnerClassType</tt> <tt>visitTypeArgument</tt>* )* <tt>visitEnd</tt>
+ * ) )</li>
+ * </ul>
  *
  * @author Thomas Hallgren
  * @author Eric Bruneton
@@ -102,24 +102,29 @@
 
     /**
      * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4}.
+     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
      */
     protected final int api;
 
     /**
      * Constructs a new {@link SignatureVisitor}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
      */
     public SignatureVisitor(final int api) {
+        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+            throw new IllegalArgumentException();
+        }
         this.api = api;
     }
 
     /**
      * Visits a formal type parameter.
      *
-     * @param name the name of the formal parameter.
+     * @param name
+     *            the name of the formal parameter.
      */
     public void visitFormalTypeParameter(String name) {
     }
@@ -191,8 +196,9 @@
     /**
      * Visits a signature corresponding to a primitive type.
      *
-     * @param descriptor the descriptor of the primitive type, or 'V' for
-     *        <tt>void</tt>.
+     * @param descriptor
+     *            the descriptor of the primitive type, or 'V' for <tt>void</tt>
+     *            .
      */
     public void visitBaseType(char descriptor) {
     }
@@ -200,7 +206,8 @@
     /**
      * Visits a signature corresponding to a type variable.
      *
-     * @param name the name of the type variable.
+     * @param name
+     *            the name of the type variable.
      */
     public void visitTypeVariable(String name) {
     }
@@ -219,7 +226,8 @@
      * Starts the visit of a signature corresponding to a class or interface
      * type.
      *
-     * @param name the internal name of the class or interface.
+     * @param name
+     *            the internal name of the class or interface.
      */
     public void visitClassType(String name) {
     }
@@ -227,7 +235,8 @@
     /**
      * Visits an inner class.
      *
-     * @param name the local name of the inner class in its enclosing class.
+     * @param name
+     *            the local name of the inner class in its enclosing class.
      */
     public void visitInnerClassType(String name) {
     }
@@ -242,7 +251,8 @@
     /**
      * Visits a type argument of the last visited class or inner class type.
      *
-     * @param wildcard '+', '-' or '='.
+     * @param wildcard
+     *            '+', '-' or '='.
      * @return a non null visitor to visit the signature of the type argument.
      */
     public SignatureVisitor visitTypeArgument(char wildcard) {
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureWriter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureWriter.java
index b341e00..0d76166 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureWriter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureWriter.java
@@ -95,7 +95,7 @@
      * Constructs a new {@link SignatureWriter} object.
      */
     public SignatureWriter() {
-        super(Opcodes.ASM4);
+        super(Opcodes.ASM5);
     }
 
     // ------------------------------------------------------------------------
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/AbstractInsnNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/AbstractInsnNode.java
index a965476..8ea77fc 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/AbstractInsnNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/AbstractInsnNode.java
@@ -58,6 +58,7 @@
  */
 package jdk.internal.org.objectweb.asm.tree;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
@@ -157,6 +158,28 @@
     protected int opcode;
 
     /**
+     * The runtime visible type annotations of this instruction. This field is
+     * only used for real instructions (i.e. not for labels, frames, or line
+     * number nodes). This list is a list of {@link TypeAnnotationNode} objects.
+     * May be <tt>null</tt>.
+     *
+     * @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
+     * @label visible
+     */
+    public List<TypeAnnotationNode> visibleTypeAnnotations;
+
+    /**
+     * The runtime invisible type annotations of this instruction. This field is
+     * only used for real instructions (i.e. not for labels, frames, or line
+     * number nodes). This list is a list of {@link TypeAnnotationNode} objects.
+     * May be <tt>null</tt>.
+     *
+     * @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
+     * @label invisible
+     */
+    public List<TypeAnnotationNode> invisibleTypeAnnotations;
+
+    /**
      * Previous instruction in the list to which this instruction belongs.
      */
     AbstractInsnNode prev;
@@ -177,7 +200,8 @@
     /**
      * Constructs a new {@link AbstractInsnNode}.
      *
-     * @param opcode the opcode of the instruction to be constructed.
+     * @param opcode
+     *            the opcode of the instruction to be constructed.
      */
     protected AbstractInsnNode(final int opcode) {
         this.opcode = opcode;
@@ -226,42 +250,106 @@
     /**
      * Makes the given code visitor visit this instruction.
      *
-     * @param cv a code visitor.
+     * @param cv
+     *            a code visitor.
      */
     public abstract void accept(final MethodVisitor cv);
 
     /**
+     * Makes the given visitor visit the annotations of this instruction.
+     *
+     * @param mv
+     *            a method visitor.
+     */
+    protected final void acceptAnnotations(final MethodVisitor mv) {
+        int n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations
+                .size();
+        for (int i = 0; i < n; ++i) {
+            TypeAnnotationNode an = visibleTypeAnnotations.get(i);
+            an.accept(mv.visitInsnAnnotation(an.typeRef, an.typePath, an.desc,
+                    true));
+        }
+        n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
+                .size();
+        for (int i = 0; i < n; ++i) {
+            TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
+            an.accept(mv.visitInsnAnnotation(an.typeRef, an.typePath, an.desc,
+                    false));
+        }
+    }
+
+    /**
      * Returns a copy of this instruction.
      *
-     * @param labels a map from LabelNodes to cloned LabelNodes.
+     * @param labels
+     *            a map from LabelNodes to cloned LabelNodes.
      * @return a copy of this instruction. The returned instruction does not
      *         belong to any {@link InsnList}.
      */
-    public abstract AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels);
+    public abstract AbstractInsnNode clone(
+            final Map<LabelNode, LabelNode> labels);
 
     /**
      * Returns the clone of the given label.
      *
-     * @param label a label.
-     * @param map a map from LabelNodes to cloned LabelNodes.
+     * @param label
+     *            a label.
+     * @param map
+     *            a map from LabelNodes to cloned LabelNodes.
      * @return the clone of the given label.
      */
-    static LabelNode clone(final LabelNode label, final Map<LabelNode, LabelNode> map) {
+    static LabelNode clone(final LabelNode label,
+            final Map<LabelNode, LabelNode> map) {
         return map.get(label);
     }
 
     /**
      * Returns the clones of the given labels.
      *
-     * @param labels a list of labels.
-     * @param map a map from LabelNodes to cloned LabelNodes.
+     * @param labels
+     *            a list of labels.
+     * @param map
+     *            a map from LabelNodes to cloned LabelNodes.
      * @return the clones of the given labels.
      */
-    static LabelNode[] clone(final List<LabelNode> labels, final Map<LabelNode, LabelNode> map) {
+    static LabelNode[] clone(final List<LabelNode> labels,
+            final Map<LabelNode, LabelNode> map) {
         LabelNode[] clones = new LabelNode[labels.size()];
         for (int i = 0; i < clones.length; ++i) {
             clones[i] = map.get(labels.get(i));
         }
         return clones;
     }
+
+    /**
+     * Clones the annotations of the given instruction into this instruction.
+     *
+     * @param insn
+     *            the source instruction.
+     * @return this instruction.
+     */
+    protected final AbstractInsnNode cloneAnnotations(
+            final AbstractInsnNode insn) {
+        if (insn.visibleTypeAnnotations != null) {
+            this.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>();
+            for (int i = 0; i < insn.visibleTypeAnnotations.size(); ++i) {
+                TypeAnnotationNode src = insn.visibleTypeAnnotations.get(i);
+                TypeAnnotationNode ann = new TypeAnnotationNode(src.typeRef,
+                        src.typePath, src.desc);
+                src.accept(ann);
+                this.visibleTypeAnnotations.add(ann);
+            }
+        }
+        if (insn.invisibleTypeAnnotations != null) {
+            this.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>();
+            for (int i = 0; i < insn.invisibleTypeAnnotations.size(); ++i) {
+                TypeAnnotationNode src = insn.invisibleTypeAnnotations.get(i);
+                TypeAnnotationNode ann = new TypeAnnotationNode(src.typeRef,
+                        src.typePath, src.desc);
+                src.accept(ann);
+                this.invisibleTypeAnnotations.add(ann);
+            }
+        }
+        return this;
+    }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java
index 6f53ed7..57b88f1 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java
@@ -84,8 +84,8 @@
      * {@link Double}, {@link String} or {@link jdk.internal.org.objectweb.asm.Type}, or an
      * two elements String array (for enumeration values), a
      * {@link AnnotationNode}, or a {@link List} of values of one of the
-     * preceding types. The list may be <tt>null</tt> if there is no name
-     * value pair.
+     * preceding types. The list may be <tt>null</tt> if there is no name value
+     * pair.
      */
     public List<Object> values;
 
@@ -94,18 +94,21 @@
      * constructor</i>. Instead, they must use the
      * {@link #AnnotationNode(int, String)} version.
      *
-     * @param desc the class descriptor of the annotation class.
+     * @param desc
+     *            the class descriptor of the annotation class.
      */
     public AnnotationNode(final String desc) {
-        this(Opcodes.ASM4, desc);
+        this(Opcodes.ASM5, desc);
     }
 
     /**
      * Constructs a new {@link AnnotationNode}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
-     * @param desc the class descriptor of the annotation class.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param desc
+     *            the class descriptor of the annotation class.
      */
     public AnnotationNode(final int api, final String desc) {
         super(api);
@@ -115,10 +118,11 @@
     /**
      * Constructs a new {@link AnnotationNode} to visit an array value.
      *
-     * @param values where the visited values must be stored.
+     * @param values
+     *            where the visited values must be stored.
      */
     AnnotationNode(final List<Object> values) {
-        super(Opcodes.ASM4);
+        super(Opcodes.ASM5);
         this.values = values;
     }
 
@@ -138,11 +142,8 @@
     }
 
     @Override
-    public void visitEnum(
-        final String name,
-        final String desc,
-        final String value)
-    {
+    public void visitEnum(final String name, final String desc,
+            final String value) {
         if (values == null) {
             values = new ArrayList<Object>(this.desc != null ? 2 : 1);
         }
@@ -153,10 +154,8 @@
     }
 
     @Override
-    public AnnotationVisitor visitAnnotation(
-        final String name,
-        final String desc)
-    {
+    public AnnotationVisitor visitAnnotation(final String name,
+            final String desc) {
         if (values == null) {
             values = new ArrayList<Object>(this.desc != null ? 2 : 1);
         }
@@ -195,7 +194,9 @@
      * recursively, do not contain elements that were introduced in more recent
      * versions of the ASM API than the given version.
      *
-     * @param api an ASM API version. Must be one of {@link Opcodes#ASM4}.
+     * @param api
+     *            an ASM API version. Must be one of {@link Opcodes#ASM4} or
+     *            {@link Opcodes#ASM5}.
      */
     public void check(final int api) {
         // nothing to do
@@ -204,7 +205,8 @@
     /**
      * Makes the given visitor visit this annotation.
      *
-     * @param av an annotation visitor. Maybe <tt>null</tt>.
+     * @param av
+     *            an annotation visitor. Maybe <tt>null</tt>.
      */
     public void accept(final AnnotationVisitor av) {
         if (av != null) {
@@ -222,15 +224,15 @@
     /**
      * Makes the given visitor visit a given annotation value.
      *
-     * @param av an annotation visitor. Maybe <tt>null</tt>.
-     * @param name the value name.
-     * @param value the actual value.
+     * @param av
+     *            an annotation visitor. Maybe <tt>null</tt>.
+     * @param name
+     *            the value name.
+     * @param value
+     *            the actual value.
      */
-    static void accept(
-        final AnnotationVisitor av,
-        final String name,
-        final Object value)
-    {
+    static void accept(final AnnotationVisitor av, final String name,
+            final Object value) {
         if (av != null) {
             if (value instanceof String[]) {
                 String[] typeconst = (String[]) value;
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/ClassNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/ClassNode.java
index 81b36c8..cb70518 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/ClassNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/ClassNode.java
@@ -68,6 +68,7 @@
 import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.TypePath;
 
 /**
  * A node that represents a class.
@@ -94,15 +95,15 @@
     public String name;
 
     /**
-     * The signature of the class. Mayt be <tt>null</tt>.
+     * The signature of the class. May be <tt>null</tt>.
      */
     public String signature;
 
     /**
      * The internal of name of the super class (see
      * {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}). For
-     * interfaces, the super class is {@link Object}. May be <tt>null</tt>,
-     * but only for the {@link Object} class.
+     * interfaces, the super class is {@link Object}. May be <tt>null</tt>, but
+     * only for the {@link Object} class.
      */
     public String superName;
 
@@ -120,7 +121,7 @@
     public String sourceFile;
 
     /**
-     * Debug information to compute the correspondance between source and
+     * Debug information to compute the correspondence between source and
      * compiled elements of the class. May be <tt>null</tt>.
      */
     public String sourceDebug;
@@ -138,8 +139,8 @@
     public String outerMethod;
 
     /**
-     * The descriptor of the method that contains the class, or <tt>null</tt>
-     * if the class is not enclosed in a method.
+     * The descriptor of the method that contains the class, or <tt>null</tt> if
+     * the class is not enclosed in a method.
      */
     public String outerMethodDesc;
 
@@ -162,6 +163,24 @@
     public List<AnnotationNode> invisibleAnnotations;
 
     /**
+     * The runtime visible type annotations of this class. This list is a list
+     * of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
+     *
+     * @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
+     * @label visible
+     */
+    public List<TypeAnnotationNode> visibleTypeAnnotations;
+
+    /**
+     * The runtime invisible type annotations of this class. This list is a list
+     * of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
+     *
+     * @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
+     * @label invisible
+     */
+    public List<TypeAnnotationNode> invisibleTypeAnnotations;
+
+    /**
      * The non standard attributes of this class. This list is a list of
      * {@link Attribute} objects. May be <tt>null</tt>.
      *
@@ -199,14 +218,15 @@
      * version.
      */
     public ClassNode() {
-        this(Opcodes.ASM4);
+        this(Opcodes.ASM5);
     }
 
     /**
      * Constructs a new {@link ClassNode}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
      */
     public ClassNode(final int api) {
         super(api);
@@ -221,14 +241,9 @@
     // ------------------------------------------------------------------------
 
     @Override
-    public void visit(
-        final int version,
-        final int access,
-        final String name,
-        final String signature,
-        final String superName,
-        final String[] interfaces)
-    {
+    public void visit(final int version, final int access, final String name,
+            final String signature, final String superName,
+            final String[] interfaces) {
         this.version = version;
         this.access = access;
         this.name = name;
@@ -246,21 +261,16 @@
     }
 
     @Override
-    public void visitOuterClass(
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitOuterClass(final String owner, final String name,
+            final String desc) {
         outerClass = owner;
         outerMethod = name;
         outerMethodDesc = desc;
     }
 
     @Override
-    public AnnotationVisitor visitAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public AnnotationVisitor visitAnnotation(final String desc,
+            final boolean visible) {
         AnnotationNode an = new AnnotationNode(desc);
         if (visible) {
             if (visibleAnnotations == null) {
@@ -277,6 +287,24 @@
     }
 
     @Override
+    public AnnotationVisitor visitTypeAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
+        if (visible) {
+            if (visibleTypeAnnotations == null) {
+                visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
+            }
+            visibleTypeAnnotations.add(an);
+        } else {
+            if (invisibleTypeAnnotations == null) {
+                invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
+            }
+            invisibleTypeAnnotations.add(an);
+        }
+        return an;
+    }
+
+    @Override
     public void visitAttribute(final Attribute attr) {
         if (attrs == null) {
             attrs = new ArrayList<Attribute>(1);
@@ -285,44 +313,25 @@
     }
 
     @Override
-    public void visitInnerClass(
-        final String name,
-        final String outerName,
-        final String innerName,
-        final int access)
-    {
-        InnerClassNode icn = new InnerClassNode(name,
-                outerName,
-                innerName,
+    public void visitInnerClass(final String name, final String outerName,
+            final String innerName, final int access) {
+        InnerClassNode icn = new InnerClassNode(name, outerName, innerName,
                 access);
         innerClasses.add(icn);
     }
 
     @Override
-    public FieldVisitor visitField(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final Object value)
-    {
+    public FieldVisitor visitField(final int access, final String name,
+            final String desc, final String signature, final Object value) {
         FieldNode fn = new FieldNode(access, name, desc, signature, value);
         fields.add(fn);
         return fn;
     }
 
     @Override
-    public MethodVisitor visitMethod(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final String[] exceptions)
-    {
-        MethodNode mn = new MethodNode(access,
-                name,
-                desc,
-                signature,
+    public MethodVisitor visitMethod(final int access, final String name,
+            final String desc, final String signature, final String[] exceptions) {
+        MethodNode mn = new MethodNode(access, name, desc, signature,
                 exceptions);
         methods.add(mn);
         return mn;
@@ -342,16 +351,34 @@
      * contain elements that were introduced in more recent versions of the ASM
      * API than the given version.
      *
-     * @param api an ASM API version. Must be one of {@link Opcodes#ASM4}.
+     * @param api
+     *            an ASM API version. Must be one of {@link Opcodes#ASM4} or
+     *            {@link Opcodes#ASM5}.
      */
     public void check(final int api) {
-        // nothing to do
+        if (api == Opcodes.ASM4) {
+            if (visibleTypeAnnotations != null
+                    && visibleTypeAnnotations.size() > 0) {
+                throw new RuntimeException();
+            }
+            if (invisibleTypeAnnotations != null
+                    && invisibleTypeAnnotations.size() > 0) {
+                throw new RuntimeException();
+            }
+            for (FieldNode f : fields) {
+                f.check(api);
+            }
+            for (MethodNode m : methods) {
+                m.check(api);
+            }
+        }
     }
 
     /**
      * Makes the given class visitor visit this class.
      *
-     * @param cv a class visitor.
+     * @param cv
+     *            a class visitor.
      */
     public void accept(final ClassVisitor cv) {
         // visits header
@@ -378,6 +405,19 @@
             AnnotationNode an = invisibleAnnotations.get(i);
             an.accept(cv.visitAnnotation(an.desc, false));
         }
+        n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size();
+        for (i = 0; i < n; ++i) {
+            TypeAnnotationNode an = visibleTypeAnnotations.get(i);
+            an.accept(cv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
+                    true));
+        }
+        n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
+                .size();
+        for (i = 0; i < n; ++i) {
+            TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
+            an.accept(cv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
+                    false));
+        }
         n = attrs == null ? 0 : attrs.size();
         for (i = 0; i < n; ++i) {
             cv.visitAttribute(attrs.get(i));
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/FieldInsnNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/FieldInsnNode.java
index b6bcca9..407a1ee 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/FieldInsnNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/FieldInsnNode.java
@@ -89,19 +89,20 @@
     /**
      * Constructs a new {@link FieldInsnNode}.
      *
-     * @param opcode the opcode of the type instruction to be constructed. This
-     *        opcode must be GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
-     * @param owner the internal name of the field's owner class (see
-     *        {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}).
-     * @param name the field's name.
-     * @param desc the field's descriptor (see {@link jdk.internal.org.objectweb.asm.Type}).
+     * @param opcode
+     *            the opcode of the type instruction to be constructed. This
+     *            opcode must be GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
+     * @param owner
+     *            the internal name of the field's owner class (see
+     *            {@link jdk.internal.org.objectweb.asm.Type#getInternalName()
+     *            getInternalName}).
+     * @param name
+     *            the field's name.
+     * @param desc
+     *            the field's descriptor (see {@link jdk.internal.org.objectweb.asm.Type}).
      */
-    public FieldInsnNode(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public FieldInsnNode(final int opcode, final String owner,
+            final String name, final String desc) {
         super(opcode);
         this.owner = owner;
         this.name = name;
@@ -111,8 +112,9 @@
     /**
      * Sets the opcode of this instruction.
      *
-     * @param opcode the new instruction opcode. This opcode must be GETSTATIC,
-     *        PUTSTATIC, GETFIELD or PUTFIELD.
+     * @param opcode
+     *            the new instruction opcode. This opcode must be GETSTATIC,
+     *            PUTSTATIC, GETFIELD or PUTFIELD.
      */
     public void setOpcode(final int opcode) {
         this.opcode = opcode;
@@ -124,12 +126,14 @@
     }
 
     @Override
-    public void accept(final MethodVisitor cv) {
-        cv.visitFieldInsn(opcode, owner, name, desc);
+    public void accept(final MethodVisitor mv) {
+        mv.visitFieldInsn(opcode, owner, name, desc);
+        acceptAnnotations(mv);
     }
 
     @Override
     public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
-        return new FieldInsnNode(opcode, owner, name, desc);
+        return new FieldInsnNode(opcode, owner, name, desc)
+                .cloneAnnotations(this);
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/FieldNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/FieldNode.java
index d25842b..a155d2c 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/FieldNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/FieldNode.java
@@ -66,6 +66,7 @@
 import jdk.internal.org.objectweb.asm.ClassVisitor;
 import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.TypePath;
 
 /**
  * A node that represents a field.
@@ -96,8 +97,8 @@
     public String signature;
 
     /**
-     * The field's initial value. This field, which may be <tt>null</tt> if
-     * the field does not have an initial value, must be an {@link Integer}, a
+     * The field's initial value. This field, which may be <tt>null</tt> if the
+     * field does not have an initial value, must be an {@link Integer}, a
      * {@link Float}, a {@link Long}, a {@link Double} or a {@link String}.
      */
     public Object value;
@@ -121,6 +122,24 @@
     public List<AnnotationNode> invisibleAnnotations;
 
     /**
+     * The runtime visible type annotations of this field. This list is a list
+     * of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
+     *
+     * @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
+     * @label visible
+     */
+    public List<TypeAnnotationNode> visibleTypeAnnotations;
+
+    /**
+     * The runtime invisible type annotations of this field. This list is a list
+     * of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
+     *
+     * @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
+     * @label invisible
+     */
+    public List<TypeAnnotationNode> invisibleTypeAnnotations;
+
+    /**
      * The non standard attributes of this field. This list is a list of
      * {@link Attribute} objects. May be <tt>null</tt>.
      *
@@ -133,26 +152,26 @@
      * constructor</i>. Instead, they must use the
      * {@link #FieldNode(int, int, String, String, String, Object)} version.
      *
-     * @param access the field's access flags (see
-     *        {@link jdk.internal.org.objectweb.asm.Opcodes}). This parameter also indicates
-     *        if the field is synthetic and/or deprecated.
-     * @param name the field's name.
-     * @param desc the field's descriptor (see {@link jdk.internal.org.objectweb.asm.Type
-     *        Type}).
-     * @param signature the field's signature.
-     * @param value the field's initial value. This parameter, which may be
-     *        <tt>null</tt> if the field does not have an initial value, must be
-     *        an {@link Integer}, a {@link Float}, a {@link Long}, a
-     *        {@link Double} or a {@link String}.
+     * @param access
+     *            the field's access flags (see
+     *            {@link jdk.internal.org.objectweb.asm.Opcodes}). This parameter also
+     *            indicates if the field is synthetic and/or deprecated.
+     * @param name
+     *            the field's name.
+     * @param desc
+     *            the field's descriptor (see {@link jdk.internal.org.objectweb.asm.Type
+     *            Type}).
+     * @param signature
+     *            the field's signature.
+     * @param value
+     *            the field's initial value. This parameter, which may be
+     *            <tt>null</tt> if the field does not have an initial value,
+     *            must be an {@link Integer}, a {@link Float}, a {@link Long}, a
+     *            {@link Double} or a {@link String}.
      */
-    public FieldNode(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final Object value)
-    {
-        this(Opcodes.ASM4, access, name, desc, signature, value);
+    public FieldNode(final int access, final String name, final String desc,
+            final String signature, final Object value) {
+        this(Opcodes.ASM5, access, name, desc, signature, value);
     }
 
     /**
@@ -160,28 +179,28 @@
      * constructor</i>. Instead, they must use the
      * {@link #FieldNode(int, int, String, String, String, Object)} version.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
-     * @param access the field's access flags (see
-     *        {@link jdk.internal.org.objectweb.asm.Opcodes}). This parameter also indicates
-     *        if the field is synthetic and/or deprecated.
-     * @param name the field's name.
-     * @param desc the field's descriptor (see {@link jdk.internal.org.objectweb.asm.Type
-     *        Type}).
-     * @param signature the field's signature.
-     * @param value the field's initial value. This parameter, which may be
-     *        <tt>null</tt> if the field does not have an initial value, must be
-     *        an {@link Integer}, a {@link Float}, a {@link Long}, a
-     *        {@link Double} or a {@link String}.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param access
+     *            the field's access flags (see
+     *            {@link jdk.internal.org.objectweb.asm.Opcodes}). This parameter also
+     *            indicates if the field is synthetic and/or deprecated.
+     * @param name
+     *            the field's name.
+     * @param desc
+     *            the field's descriptor (see {@link jdk.internal.org.objectweb.asm.Type
+     *            Type}).
+     * @param signature
+     *            the field's signature.
+     * @param value
+     *            the field's initial value. This parameter, which may be
+     *            <tt>null</tt> if the field does not have an initial value,
+     *            must be an {@link Integer}, a {@link Float}, a {@link Long}, a
+     *            {@link Double} or a {@link String}.
      */
-    public FieldNode(
-        final int api,
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final Object value)
-    {
+    public FieldNode(final int api, final int access, final String name,
+            final String desc, final String signature, final Object value) {
         super(api);
         this.access = access;
         this.name = name;
@@ -195,10 +214,8 @@
     // ------------------------------------------------------------------------
 
     @Override
-    public AnnotationVisitor visitAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public AnnotationVisitor visitAnnotation(final String desc,
+            final boolean visible) {
         AnnotationNode an = new AnnotationNode(desc);
         if (visible) {
             if (visibleAnnotations == null) {
@@ -215,6 +232,24 @@
     }
 
     @Override
+    public AnnotationVisitor visitTypeAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
+        if (visible) {
+            if (visibleTypeAnnotations == null) {
+                visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
+            }
+            visibleTypeAnnotations.add(an);
+        } else {
+            if (invisibleTypeAnnotations == null) {
+                invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
+            }
+            invisibleTypeAnnotations.add(an);
+        }
+        return an;
+    }
+
+    @Override
     public void visitAttribute(final Attribute attr) {
         if (attrs == null) {
             attrs = new ArrayList<Attribute>(1);
@@ -236,16 +271,28 @@
      * contain elements that were introduced in more recent versions of the ASM
      * API than the given version.
      *
-     * @param api an ASM API version. Must be one of {@link Opcodes#ASM4}.
+     * @param api
+     *            an ASM API version. Must be one of {@link Opcodes#ASM4} or
+     *            {@link Opcodes#ASM5}.
      */
     public void check(final int api) {
-        // nothing to do
+        if (api == Opcodes.ASM4) {
+            if (visibleTypeAnnotations != null
+                    && visibleTypeAnnotations.size() > 0) {
+                throw new RuntimeException();
+            }
+            if (invisibleTypeAnnotations != null
+                    && invisibleTypeAnnotations.size() > 0) {
+                throw new RuntimeException();
+            }
+        }
     }
 
     /**
      * Makes the given class visitor visit this field.
      *
-     * @param cv a class visitor.
+     * @param cv
+     *            a class visitor.
      */
     public void accept(final ClassVisitor cv) {
         FieldVisitor fv = cv.visitField(access, name, desc, signature, value);
@@ -263,6 +310,19 @@
             AnnotationNode an = invisibleAnnotations.get(i);
             an.accept(fv.visitAnnotation(an.desc, false));
         }
+        n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size();
+        for (i = 0; i < n; ++i) {
+            TypeAnnotationNode an = visibleTypeAnnotations.get(i);
+            an.accept(fv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
+                    true));
+        }
+        n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
+                .size();
+        for (i = 0; i < n; ++i) {
+            TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
+            an.accept(fv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
+                    false));
+        }
         n = attrs == null ? 0 : attrs.size();
         for (i = 0; i < n; ++i) {
             fv.visitAttribute(attrs.get(i));
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/FrameNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/FrameNode.java
index 42975b3..02a26b2 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/FrameNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/FrameNode.java
@@ -74,8 +74,9 @@
  * the target of a jump instruction, or that starts an exception handler block.
  * The stack map frame types must describe the values of the local variables and
  * of the operand stack elements <i>just before</i> <b>i</b> is executed. <br>
- * <br> (*) this is mandatory only for classes whose version is greater than or
- * equal to {@link Opcodes#V1_6 V1_6}.
+ * <br>
+ * (*) this is mandatory only for classes whose version is greater than or equal
+ * to {@link Opcodes#V1_6 V1_6}.
  *
  * @author Eric Bruneton
  */
@@ -112,48 +113,48 @@
     /**
      * Constructs a new {@link FrameNode}.
      *
-     * @param type the type of this frame. Must be {@link Opcodes#F_NEW} for
-     *        expanded frames, or {@link Opcodes#F_FULL},
-     *        {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP},
-     *        {@link Opcodes#F_SAME} or {@link Opcodes#F_APPEND},
-     *        {@link Opcodes#F_SAME1} for compressed frames.
-     * @param nLocal number of local variables of this stack map frame.
-     * @param local the types of the local variables of this stack map frame.
-     *        Elements of this list can be Integer, String or LabelNode objects
-     *        (for primitive, reference and uninitialized types respectively -
-     *        see {@link MethodVisitor}).
-     * @param nStack number of operand stack elements of this stack map frame.
-     * @param stack the types of the operand stack elements of this stack map
-     *        frame. Elements of this list can be Integer, String or LabelNode
-     *        objects (for primitive, reference and uninitialized types
-     *        respectively - see {@link MethodVisitor}).
+     * @param type
+     *            the type of this frame. Must be {@link Opcodes#F_NEW} for
+     *            expanded frames, or {@link Opcodes#F_FULL},
+     *            {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP},
+     *            {@link Opcodes#F_SAME} or {@link Opcodes#F_APPEND},
+     *            {@link Opcodes#F_SAME1} for compressed frames.
+     * @param nLocal
+     *            number of local variables of this stack map frame.
+     * @param local
+     *            the types of the local variables of this stack map frame.
+     *            Elements of this list can be Integer, String or LabelNode
+     *            objects (for primitive, reference and uninitialized types
+     *            respectively - see {@link MethodVisitor}).
+     * @param nStack
+     *            number of operand stack elements of this stack map frame.
+     * @param stack
+     *            the types of the operand stack elements of this stack map
+     *            frame. Elements of this list can be Integer, String or
+     *            LabelNode objects (for primitive, reference and uninitialized
+     *            types respectively - see {@link MethodVisitor}).
      */
-    public FrameNode(
-        final int type,
-        final int nLocal,
-        final Object[] local,
-        final int nStack,
-        final Object[] stack)
-    {
+    public FrameNode(final int type, final int nLocal, final Object[] local,
+            final int nStack, final Object[] stack) {
         super(-1);
         this.type = type;
         switch (type) {
-            case Opcodes.F_NEW:
-            case Opcodes.F_FULL:
-                this.local = asList(nLocal, local);
-                this.stack = asList(nStack, stack);
-                break;
-            case Opcodes.F_APPEND:
-                this.local = asList(nLocal, local);
-                break;
-            case Opcodes.F_CHOP:
-                this.local = Arrays.asList(new Object[nLocal]);
-                break;
-            case Opcodes.F_SAME:
-                break;
-            case Opcodes.F_SAME1:
-                this.stack = asList(1, stack);
-                break;
+        case Opcodes.F_NEW:
+        case Opcodes.F_FULL:
+            this.local = asList(nLocal, local);
+            this.stack = asList(nStack, stack);
+            break;
+        case Opcodes.F_APPEND:
+            this.local = asList(nLocal, local);
+            break;
+        case Opcodes.F_CHOP:
+            this.local = Arrays.asList(new Object[nLocal]);
+            break;
+        case Opcodes.F_SAME:
+            break;
+        case Opcodes.F_SAME1:
+            this.stack = asList(1, stack);
+            break;
         }
     }
 
@@ -165,31 +166,29 @@
     /**
      * Makes the given visitor visit this stack map frame.
      *
-     * @param mv a method visitor.
+     * @param mv
+     *            a method visitor.
      */
     @Override
     public void accept(final MethodVisitor mv) {
         switch (type) {
-            case Opcodes.F_NEW:
-            case Opcodes.F_FULL:
-                mv.visitFrame(type,
-                        local.size(),
-                        asArray(local),
-                        stack.size(),
-                        asArray(stack));
-                break;
-            case Opcodes.F_APPEND:
-                mv.visitFrame(type, local.size(), asArray(local), 0, null);
-                break;
-            case Opcodes.F_CHOP:
-                mv.visitFrame(type, local.size(), null, 0, null);
-                break;
-            case Opcodes.F_SAME:
-                mv.visitFrame(type, 0, null, 0, null);
-                break;
-            case Opcodes.F_SAME1:
-                mv.visitFrame(type, 0, null, 1, asArray(stack));
-                break;
+        case Opcodes.F_NEW:
+        case Opcodes.F_FULL:
+            mv.visitFrame(type, local.size(), asArray(local), stack.size(),
+                    asArray(stack));
+            break;
+        case Opcodes.F_APPEND:
+            mv.visitFrame(type, local.size(), asArray(local), 0, null);
+            break;
+        case Opcodes.F_CHOP:
+            mv.visitFrame(type, local.size(), null, 0, null);
+            break;
+        case Opcodes.F_SAME:
+            mv.visitFrame(type, 0, null, 0, null);
+            break;
+        case Opcodes.F_SAME1:
+            mv.visitFrame(type, 0, null, 1, asArray(stack));
+            break;
         }
     }
 
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/IincInsnNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/IincInsnNode.java
index 2c390e5..7be4de6 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/IincInsnNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/IincInsnNode.java
@@ -83,8 +83,10 @@
     /**
      * Constructs a new {@link IincInsnNode}.
      *
-     * @param var index of the local variable to be incremented.
-     * @param incr increment amount to increment the local variable by.
+     * @param var
+     *            index of the local variable to be incremented.
+     * @param incr
+     *            increment amount to increment the local variable by.
      */
     public IincInsnNode(final int var, final int incr) {
         super(Opcodes.IINC);
@@ -100,10 +102,11 @@
     @Override
     public void accept(final MethodVisitor mv) {
         mv.visitIincInsn(var, incr);
+        acceptAnnotations(mv);
     }
 
     @Override
     public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
-        return new IincInsnNode(var, incr);
+        return new IincInsnNode(var, incr).cloneAnnotations(this);
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InnerClassNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InnerClassNode.java
index 38e19d9..88fe0a8 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InnerClassNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InnerClassNode.java
@@ -75,8 +75,8 @@
 
     /**
      * The internal name of the class to which the inner class belongs (see
-     * {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}). May
-     * be <tt>null</tt>.
+     * {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}). May be
+     * <tt>null</tt>.
      */
     public String outerName;
 
@@ -95,24 +95,23 @@
     /**
      * Constructs a new {@link InnerClassNode}.
      *
-     * @param name the internal name of an inner class (see
-     *        {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}).
-     * @param outerName the internal name of the class to which the inner class
-     *        belongs (see
-     *        {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}).
-     *        May be <tt>null</tt>.
-     * @param innerName the (simple) name of the inner class inside its
-     *        enclosing class. May be <tt>null</tt> for anonymous inner
-     *        classes.
-     * @param access the access flags of the inner class as originally declared
-     *        in the enclosing class.
+     * @param name
+     *            the internal name of an inner class (see
+     *            {@link jdk.internal.org.objectweb.asm.Type#getInternalName()
+     *            getInternalName}).
+     * @param outerName
+     *            the internal name of the class to which the inner class
+     *            belongs (see {@link jdk.internal.org.objectweb.asm.Type#getInternalName()
+     *            getInternalName}). May be <tt>null</tt>.
+     * @param innerName
+     *            the (simple) name of the inner class inside its enclosing
+     *            class. May be <tt>null</tt> for anonymous inner classes.
+     * @param access
+     *            the access flags of the inner class as originally declared in
+     *            the enclosing class.
      */
-    public InnerClassNode(
-        final String name,
-        final String outerName,
-        final String innerName,
-        final int access)
-    {
+    public InnerClassNode(final String name, final String outerName,
+            final String innerName, final int access) {
         this.name = name;
         this.outerName = outerName;
         this.innerName = innerName;
@@ -122,7 +121,8 @@
     /**
      * Makes the given class visitor visit this inner class.
      *
-     * @param cv a class visitor.
+     * @param cv
+     *            a class visitor.
      */
     public void accept(final ClassVisitor cv) {
         cv.visitInnerClass(name, outerName, innerName, access);
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java
index d1c2f5c..2ba917c 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java
@@ -102,8 +102,8 @@
     /**
      * Returns the first instruction in this list.
      *
-     * @return the first instruction in this list, or <tt>null</tt> if the
-     *         list is empty.
+     * @return the first instruction in this list, or <tt>null</tt> if the list
+     *         is empty.
      */
     public AbstractInsnNode getFirst() {
         return first;
@@ -125,9 +125,11 @@
      * time it is called. Once the cache is built, this method run in constant
      * time. This cache is invalidated by all the methods that modify the list.
      *
-     * @param index the index of the instruction that must be returned.
+     * @param index
+     *            the index of the instruction that must be returned.
      * @return the instruction whose index is given.
-     * @throws IndexOutOfBoundsException if (index < 0 || index >= size()).
+     * @throws IndexOutOfBoundsException
+     *             if (index &lt; 0 || index &gt;= size()).
      */
     public AbstractInsnNode get(final int index) {
         if (index < 0 || index >= size) {
@@ -140,11 +142,12 @@
     }
 
     /**
-     * Returns <tt>true</tt> if the given instruction belongs to this list.
-     * This method always scans the instructions of this list until it finds the
+     * Returns <tt>true</tt> if the given instruction belongs to this list. This
+     * method always scans the instructions of this list until it finds the
      * given instruction or reaches the end of the list.
      *
-     * @param insn an instruction.
+     * @param insn
+     *            an instruction.
      * @return <tt>true</tt> if the given instruction belongs to this list.
      */
     public boolean contains(final AbstractInsnNode insn) {
@@ -162,7 +165,8 @@
      * constant time. The cache is invalidated by all the methods that modify
      * the list.
      *
-     * @param insn an instruction <i>of this list</i>.
+     * @param insn
+     *            an instruction <i>of this list</i>.
      * @return the index of the given instruction in this list. <i>The result of
      *         this method is undefined if the given instruction does not belong
      *         to this list</i>. Use {@link #contains contains} to test if an
@@ -178,7 +182,8 @@
     /**
      * Makes the given visitor visit all of the instructions in this list.
      *
-     * @param mv the method visitor that must visit the instructions.
+     * @param mv
+     *            the method visitor that must visit the instructions.
      */
     public void accept(final MethodVisitor mv) {
         AbstractInsnNode insn = first;
@@ -227,9 +232,11 @@
     /**
      * Replaces an instruction of this list with another instruction.
      *
-     * @param location an instruction <i>of this list</i>.
-     * @param insn another instruction, <i>which must not belong to any
-     *        {@link InsnList}</i>.
+     * @param location
+     *            an instruction <i>of this list</i>.
+     * @param insn
+     *            another instruction, <i>which must not belong to any
+     *            {@link InsnList}</i>.
      */
     public void set(final AbstractInsnNode location, final AbstractInsnNode insn) {
         AbstractInsnNode next = location.next;
@@ -261,8 +268,9 @@
     /**
      * Adds the given instruction to the end of this list.
      *
-     * @param insn an instruction, <i>which must not belong to any
-     *        {@link InsnList}</i>.
+     * @param insn
+     *            an instruction, <i>which must not belong to any
+     *            {@link InsnList}</i>.
      */
     public void add(final AbstractInsnNode insn) {
         ++size;
@@ -281,8 +289,9 @@
     /**
      * Adds the given instructions to the end of this list.
      *
-     * @param insns an instruction list, which is cleared during the process.
-     *        This list must be different from 'this'.
+     * @param insns
+     *            an instruction list, which is cleared during the process. This
+     *            list must be different from 'this'.
      */
     public void add(final InsnList insns) {
         if (insns.size == 0) {
@@ -305,8 +314,9 @@
     /**
      * Inserts the given instruction at the begining of this list.
      *
-     * @param insn an instruction, <i>which must not belong to any
-     *        {@link InsnList}</i>.
+     * @param insn
+     *            an instruction, <i>which must not belong to any
+     *            {@link InsnList}</i>.
      */
     public void insert(final AbstractInsnNode insn) {
         ++size;
@@ -325,8 +335,9 @@
     /**
      * Inserts the given instructions at the begining of this list.
      *
-     * @param insns an instruction list, which is cleared during the process.
-     *        This list must be different from 'this'.
+     * @param insns
+     *            an instruction list, which is cleared during the process. This
+     *            list must be different from 'this'.
      */
     public void insert(final InsnList insns) {
         if (insns.size == 0) {
@@ -349,12 +360,15 @@
     /**
      * Inserts the given instruction after the specified instruction.
      *
-     * @param location an instruction <i>of this list</i> after which insn must be
-     *        inserted.
-     * @param insn the instruction to be inserted, <i>which must not belong to
-     *        any {@link InsnList}</i>.
+     * @param location
+     *            an instruction <i>of this list</i> after which insn must be
+     *            inserted.
+     * @param insn
+     *            the instruction to be inserted, <i>which must not belong to
+     *            any {@link InsnList}</i>.
      */
-    public void insert(final AbstractInsnNode location, final AbstractInsnNode insn) {
+    public void insert(final AbstractInsnNode location,
+            final AbstractInsnNode insn) {
         ++size;
         AbstractInsnNode next = location.next;
         if (next == null) {
@@ -372,10 +386,12 @@
     /**
      * Inserts the given instructions after the specified instruction.
      *
-     * @param location an instruction <i>of this list</i> after which the
-     *        instructions must be inserted.
-     * @param insns the instruction list to be inserted, which is cleared during
-     *        the process. This list must be different from 'this'.
+     * @param location
+     *            an instruction <i>of this list</i> after which the
+     *            instructions must be inserted.
+     * @param insns
+     *            the instruction list to be inserted, which is cleared during
+     *            the process. This list must be different from 'this'.
      */
     public void insert(final AbstractInsnNode location, final InsnList insns) {
         if (insns.size == 0) {
@@ -400,12 +416,15 @@
     /**
      * Inserts the given instruction before the specified instruction.
      *
-     * @param location an instruction <i>of this list</i> before which insn must be
-     *        inserted.
-     * @param insn the instruction to be inserted, <i>which must not belong to
-     *        any {@link InsnList}</i>.
+     * @param location
+     *            an instruction <i>of this list</i> before which insn must be
+     *            inserted.
+     * @param insn
+     *            the instruction to be inserted, <i>which must not belong to
+     *            any {@link InsnList}</i>.
      */
-    public void insertBefore(final AbstractInsnNode location, final AbstractInsnNode insn) {
+    public void insertBefore(final AbstractInsnNode location,
+            final AbstractInsnNode insn) {
         ++size;
         AbstractInsnNode prev = location.prev;
         if (prev == null) {
@@ -423,37 +442,39 @@
     /**
      * Inserts the given instructions before the specified instruction.
      *
-     * @param location  an instruction <i>of this list</i> before which the instructions
-     *        must be inserted.
-     * @param insns the instruction list to be inserted, which is cleared during
-     *        the process. This list must be different from 'this'.
+     * @param location
+     *            an instruction <i>of this list</i> before which the
+     *            instructions must be inserted.
+     * @param insns
+     *            the instruction list to be inserted, which is cleared during
+     *            the process. This list must be different from 'this'.
      */
-    public void insertBefore(final AbstractInsnNode location, final InsnList insns) {
+    public void insertBefore(final AbstractInsnNode location,
+            final InsnList insns) {
         if (insns.size == 0) {
             return;
         }
         size += insns.size;
         AbstractInsnNode ifirst = insns.first;
         AbstractInsnNode ilast = insns.last;
-        AbstractInsnNode prev = location .prev;
+        AbstractInsnNode prev = location.prev;
         if (prev == null) {
             first = ifirst;
         } else {
             prev.next = ifirst;
         }
-        location .prev = ilast;
-        ilast.next = location ;
+        location.prev = ilast;
+        ilast.next = location;
         ifirst.prev = prev;
         cache = null;
         insns.removeAll(false);
     }
 
-
-
     /**
      * Removes the given instruction from this list.
      *
-     * @param insn the instruction <i>of this list</i> that must be removed.
+     * @param insn
+     *            the instruction <i>of this list</i> that must be removed.
      */
     public void remove(final AbstractInsnNode insn) {
         --size;
@@ -485,8 +506,9 @@
     /**
      * Removes all of the instructions of this list.
      *
-     * @param mark if the instructions must be marked as no longer belonging to
-     *        any {@link InsnList}.
+     * @param mark
+     *            if the instructions must be marked as no longer belonging to
+     *            any {@link InsnList}.
      */
     void removeAll(final boolean mark) {
         if (mark) {
@@ -528,14 +550,14 @@
     }
 
     // this class is not generified because it will create bridges
-    private final class InsnListIterator implements ListIterator/*<AbstractInsnNode>*/ {
+    private final class InsnListIterator implements ListIterator {
 
         AbstractInsnNode next;
 
         AbstractInsnNode prev;
 
         InsnListIterator(int index) {
-            if(index==size()) {
+            if (index == size()) {
                 next = null;
                 prev = getLast();
             } else {
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InsnNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InsnNode.java
index 62ac385..10e0c1a 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InsnNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InsnNode.java
@@ -72,20 +72,22 @@
     /**
      * Constructs a new {@link InsnNode}.
      *
-     * @param opcode the opcode of the instruction to be constructed. This
-     *        opcode must be NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
-     *        ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1,
-     *        FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD,
-     *        FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE,
-     *        FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2,
-     *        DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP, IADD, LADD,
-     *        FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV,
-     *        LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG,
-     *        ISHL, LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR,
-     *        LXOR, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F,
-     *        I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN,
-     *        FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW,
-     *        MONITORENTER, or MONITOREXIT.
+     * @param opcode
+     *            the opcode of the instruction to be constructed. This opcode
+     *            must be NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
+     *            ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1,
+     *            FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD,
+     *            LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD,
+     *            IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE,
+     *            SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1,
+     *            DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB,
+     *            IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM,
+     *            FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR,
+     *            IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D,
+     *            L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S,
+     *            LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
+     *            DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER,
+     *            or MONITOREXIT.
      */
     public InsnNode(final int opcode) {
         super(opcode);
@@ -99,15 +101,17 @@
     /**
      * Makes the given visitor visit this instruction.
      *
-     * @param mv a method visitor.
+     * @param mv
+     *            a method visitor.
      */
     @Override
     public void accept(final MethodVisitor mv) {
         mv.visitInsn(opcode);
+        acceptAnnotations(mv);
     }
 
     @Override
     public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
-        return new InsnNode(opcode);
+        return new InsnNode(opcode).cloneAnnotations(this);
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/IntInsnNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/IntInsnNode.java
index d1b88f5..5e744d1 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/IntInsnNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/IntInsnNode.java
@@ -77,9 +77,11 @@
     /**
      * Constructs a new {@link IntInsnNode}.
      *
-     * @param opcode the opcode of the instruction to be constructed. This
-     *        opcode must be BIPUSH, SIPUSH or NEWARRAY.
-     * @param operand the operand of the instruction to be constructed.
+     * @param opcode
+     *            the opcode of the instruction to be constructed. This opcode
+     *            must be BIPUSH, SIPUSH or NEWARRAY.
+     * @param operand
+     *            the operand of the instruction to be constructed.
      */
     public IntInsnNode(final int opcode, final int operand) {
         super(opcode);
@@ -89,8 +91,9 @@
     /**
      * Sets the opcode of this instruction.
      *
-     * @param opcode the new instruction opcode. This opcode must be BIPUSH,
-     *        SIPUSH or NEWARRAY.
+     * @param opcode
+     *            the new instruction opcode. This opcode must be BIPUSH, SIPUSH
+     *            or NEWARRAY.
      */
     public void setOpcode(final int opcode) {
         this.opcode = opcode;
@@ -104,10 +107,11 @@
     @Override
     public void accept(final MethodVisitor mv) {
         mv.visitIntInsn(opcode, operand);
+        acceptAnnotations(mv);
     }
 
     @Override
     public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
-        return new IntInsnNode(opcode, operand);
+        return new IntInsnNode(opcode, operand).cloneAnnotations(this);
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InvokeDynamicInsnNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InvokeDynamicInsnNode.java
index 2370b30..12a40ba 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InvokeDynamicInsnNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InvokeDynamicInsnNode.java
@@ -94,17 +94,17 @@
     /**
      * Constructs a new {@link InvokeDynamicInsnNode}.
      *
-     * @param name invokedynamic name.
-     * @param desc invokedynamic descriptor (see {@link jdk.internal.org.objectweb.asm.Type}).
-     * @param bsm the bootstrap method.
-     * @param bsmArgs the boostrap constant arguments.
+     * @param name
+     *            invokedynamic name.
+     * @param desc
+     *            invokedynamic descriptor (see {@link jdk.internal.org.objectweb.asm.Type}).
+     * @param bsm
+     *            the bootstrap method.
+     * @param bsmArgs
+     *            the boostrap constant arguments.
      */
-    public InvokeDynamicInsnNode(
-        final String name,
-        final String desc,
-        final Handle bsm,
-        final Object... bsmArgs)
-    {
+    public InvokeDynamicInsnNode(final String name, final String desc,
+            final Handle bsm, final Object... bsmArgs) {
         super(Opcodes.INVOKEDYNAMIC);
         this.name = name;
         this.desc = desc;
@@ -120,10 +120,12 @@
     @Override
     public void accept(final MethodVisitor mv) {
         mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
+        acceptAnnotations(mv);
     }
 
     @Override
     public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
-        return new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs);
+        return new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs)
+                .cloneAnnotations(this);
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/JumpInsnNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/JumpInsnNode.java
index 265e1c8..42b34ec 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/JumpInsnNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/JumpInsnNode.java
@@ -79,13 +79,15 @@
     /**
      * Constructs a new {@link JumpInsnNode}.
      *
-     * @param opcode the opcode of the type instruction to be constructed. This
-     *        opcode must be IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
-     *        IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ,
-     *        IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
-     * @param label the operand of the instruction to be constructed. This
-     *        operand is a label that designates the instruction to which the
-     *        jump instruction may jump.
+     * @param opcode
+     *            the opcode of the type instruction to be constructed. This
+     *            opcode must be IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
+     *            IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
+     *            IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
+     * @param label
+     *            the operand of the instruction to be constructed. This operand
+     *            is a label that designates the instruction to which the jump
+     *            instruction may jump.
      */
     public JumpInsnNode(final int opcode, final LabelNode label) {
         super(opcode);
@@ -95,10 +97,11 @@
     /**
      * Sets the opcode of this instruction.
      *
-     * @param opcode the new instruction opcode. This opcode must be IFEQ, IFNE,
-     *        IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT,
-     *        IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR,
-     *        IFNULL or IFNONNULL.
+     * @param opcode
+     *            the new instruction opcode. This opcode must be IFEQ, IFNE,
+     *            IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT,
+     *            IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO,
+     *            JSR, IFNULL or IFNONNULL.
      */
     public void setOpcode(final int opcode) {
         this.opcode = opcode;
@@ -112,10 +115,12 @@
     @Override
     public void accept(final MethodVisitor mv) {
         mv.visitJumpInsn(opcode, label.getLabel());
+        acceptAnnotations(mv);
     }
 
     @Override
     public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
-        return new JumpInsnNode(opcode, clone(label, labels));
+        return new JumpInsnNode(opcode, clone(label, labels))
+                .cloneAnnotations(this);
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LdcInsnNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LdcInsnNode.java
index 7220d91..ef43505 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LdcInsnNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LdcInsnNode.java
@@ -80,9 +80,10 @@
     /**
      * Constructs a new {@link LdcInsnNode}.
      *
-     * @param cst the constant to be loaded on the stack. This parameter must be
-     *        a non null {@link Integer}, a {@link Float}, a {@link Long}, a
-     *        {@link Double} or a {@link String}.
+     * @param cst
+     *            the constant to be loaded on the stack. This parameter must be
+     *            a non null {@link Integer}, a {@link Float}, a {@link Long}, a
+     *            {@link Double} or a {@link String}.
      */
     public LdcInsnNode(final Object cst) {
         super(Opcodes.LDC);
@@ -97,10 +98,11 @@
     @Override
     public void accept(final MethodVisitor mv) {
         mv.visitLdcInsn(cst);
+        acceptAnnotations(mv);
     }
 
     @Override
     public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
-        return new LdcInsnNode(cst);
+        return new LdcInsnNode(cst).cloneAnnotations(this);
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LineNumberNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LineNumberNode.java
index 7160d30..ca5add0 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LineNumberNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LineNumberNode.java
@@ -84,9 +84,11 @@
     /**
      * Constructs a new {@link LineNumberNode}.
      *
-     * @param line a line number. This number refers to the source file from
-     *        which the class was compiled.
-     * @param start the first instruction corresponding to this line number.
+     * @param line
+     *            a line number. This number refers to the source file from
+     *            which the class was compiled.
+     * @param start
+     *            the first instruction corresponding to this line number.
      */
     public LineNumberNode(final int line, final LabelNode start) {
         super(-1);
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableAnnotationNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableAnnotationNode.java
new file mode 100644
index 0000000..6bb549b
--- /dev/null
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableAnnotationNode.java
@@ -0,0 +1,186 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm.tree;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.Label;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.TypePath;
+import jdk.internal.org.objectweb.asm.TypeReference;
+
+/**
+ * A node that represents a type annotation on a local or resource variable.
+ *
+ * @author Eric Bruneton
+ */
+public class LocalVariableAnnotationNode extends TypeAnnotationNode {
+
+    /**
+     * The fist instructions corresponding to the continuous ranges that make
+     * the scope of this local variable (inclusive). Must not be <tt>null</tt>.
+     */
+    public List<LabelNode> start;
+
+    /**
+     * The last instructions corresponding to the continuous ranges that make
+     * the scope of this local variable (exclusive). This list must have the
+     * same size as the 'start' list. Must not be <tt>null</tt>.
+     */
+    public List<LabelNode> end;
+
+    /**
+     * The local variable's index in each range. This list must have the same
+     * size as the 'start' list. Must not be <tt>null</tt>.
+     */
+    public List<Integer> index;
+
+    /**
+     * Constructs a new {@link LocalVariableAnnotationNode}. <i>Subclasses must
+     * not use this constructor</i>. Instead, they must use the
+     * {@link #LocalVariableAnnotationNode(int, TypePath, LabelNode[], LabelNode[], int[], String)}
+     * version.
+     *
+     * @param typeRef
+     *            a reference to the annotated type. See {@link TypeReference}.
+     * @param typePath
+     *            the path to the annotated type argument, wildcard bound, array
+     *            element type, or static inner type within 'typeRef'. May be
+     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
+     * @param start
+     *            the fist instructions corresponding to the continuous ranges
+     *            that make the scope of this local variable (inclusive).
+     * @param end
+     *            the last instructions corresponding to the continuous ranges
+     *            that make the scope of this local variable (exclusive). This
+     *            array must have the same size as the 'start' array.
+     * @param index
+     *            the local variable's index in each range. This array must have
+     *            the same size as the 'start' array.
+     * @param desc
+     *            the class descriptor of the annotation class.
+     */
+    public LocalVariableAnnotationNode(int typeRef, TypePath typePath,
+            LabelNode[] start, LabelNode[] end, int[] index, String desc) {
+        this(Opcodes.ASM5, typeRef, typePath, start, end, index, desc);
+    }
+
+    /**
+     * Constructs a new {@link LocalVariableAnnotationNode}.
+     *
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param typeRef
+     *            a reference to the annotated type. See {@link TypeReference}.
+     * @param start
+     *            the fist instructions corresponding to the continuous ranges
+     *            that make the scope of this local variable (inclusive).
+     * @param end
+     *            the last instructions corresponding to the continuous ranges
+     *            that make the scope of this local variable (exclusive). This
+     *            array must have the same size as the 'start' array.
+     * @param index
+     *            the local variable's index in each range. This array must have
+     *            the same size as the 'start' array.
+     * @param typePath
+     *            the path to the annotated type argument, wildcard bound, array
+     *            element type, or static inner type within 'typeRef'. May be
+     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
+     * @param desc
+     *            the class descriptor of the annotation class.
+     */
+    public LocalVariableAnnotationNode(int api, int typeRef, TypePath typePath,
+            LabelNode[] start, LabelNode[] end, int[] index, String desc) {
+        super(api, typeRef, typePath, desc);
+        this.start = new ArrayList<LabelNode>(start.length);
+        this.start.addAll(Arrays.asList(start));
+        this.end = new ArrayList<LabelNode>(end.length);
+        this.end.addAll(Arrays.asList(end));
+        this.index = new ArrayList<Integer>(index.length);
+        for (int i : index) {
+            this.index.add(i);
+        }
+    }
+
+    /**
+     * Makes the given visitor visit this type annotation.
+     *
+     * @param mv
+     *            the visitor that must visit this annotation.
+     * @param visible
+     *            <tt>true</tt> if the annotation is visible at runtime.
+     */
+    public void accept(final MethodVisitor mv, boolean visible) {
+        Label[] start = new Label[this.start.size()];
+        Label[] end = new Label[this.end.size()];
+        int[] index = new int[this.index.size()];
+        for (int i = 0; i < start.length; ++i) {
+            start[i] = this.start.get(i).getLabel();
+            end[i] = this.end.get(i).getLabel();
+            index[i] = this.index.get(i);
+        }
+        accept(mv.visitLocalVariableAnnotation(typeRef, typePath, start, end,
+                index, desc, true));
+    }
+}
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableNode.java
index 0d3272b..45ada56 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableNode.java
@@ -102,24 +102,24 @@
     /**
      * Constructs a new {@link LocalVariableNode}.
      *
-     * @param name the name of a local variable.
-     * @param desc the type descriptor of this local variable.
-     * @param signature the signature of this local variable. May be
-     *        <tt>null</tt>.
-     * @param start the first instruction corresponding to the scope of this
-     *        local variable (inclusive).
-     * @param end the last instruction corresponding to the scope of this local
-     *        variable (exclusive).
-     * @param index the local variable's index.
+     * @param name
+     *            the name of a local variable.
+     * @param desc
+     *            the type descriptor of this local variable.
+     * @param signature
+     *            the signature of this local variable. May be <tt>null</tt>.
+     * @param start
+     *            the first instruction corresponding to the scope of this local
+     *            variable (inclusive).
+     * @param end
+     *            the last instruction corresponding to the scope of this local
+     *            variable (exclusive).
+     * @param index
+     *            the local variable's index.
      */
-    public LocalVariableNode(
-        final String name,
-        final String desc,
-        final String signature,
-        final LabelNode start,
-        final LabelNode end,
-        final int index)
-    {
+    public LocalVariableNode(final String name, final String desc,
+            final String signature, final LabelNode start, final LabelNode end,
+            final int index) {
         this.name = name;
         this.desc = desc;
         this.signature = signature;
@@ -131,14 +131,11 @@
     /**
      * Makes the given visitor visit this local variable declaration.
      *
-     * @param mv a method visitor.
+     * @param mv
+     *            a method visitor.
      */
     public void accept(final MethodVisitor mv) {
-        mv.visitLocalVariable(name,
-                desc,
-                signature,
-                start.getLabel(),
-                end.getLabel(),
-                index);
+        mv.visitLocalVariable(name, desc, signature, start.getLabel(),
+                end.getLabel(), index);
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LookupSwitchInsnNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LookupSwitchInsnNode.java
index 8a801dd..b1daa38 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LookupSwitchInsnNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LookupSwitchInsnNode.java
@@ -93,20 +93,21 @@
     /**
      * Constructs a new {@link LookupSwitchInsnNode}.
      *
-     * @param dflt beginning of the default handler block.
-     * @param keys the values of the keys.
-     * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is
-     *        the beginning of the handler block for the <tt>keys[i]</tt> key.
+     * @param dflt
+     *            beginning of the default handler block.
+     * @param keys
+     *            the values of the keys.
+     * @param labels
+     *            beginnings of the handler blocks. <tt>labels[i]</tt> is the
+     *            beginning of the handler block for the <tt>keys[i]</tt> key.
      */
-    public LookupSwitchInsnNode(
-        final LabelNode dflt,
-        final int[] keys,
-        final LabelNode[] labels)
-    {
+    public LookupSwitchInsnNode(final LabelNode dflt, final int[] keys,
+            final LabelNode[] labels) {
         super(Opcodes.LOOKUPSWITCH);
         this.dflt = dflt;
         this.keys = new ArrayList<Integer>(keys == null ? 0 : keys.length);
-        this.labels = new ArrayList<LabelNode>(labels == null ? 0 : labels.length);
+        this.labels = new ArrayList<LabelNode>(labels == null ? 0
+                : labels.length);
         if (keys != null) {
             for (int i = 0; i < keys.length; ++i) {
                 this.keys.add(new Integer(keys[i]));
@@ -133,6 +134,7 @@
             labels[i] = this.labels.get(i).getLabel();
         }
         mv.visitLookupSwitchInsn(dflt.getLabel(), keys, labels);
+        acceptAnnotations(mv);
     }
 
     @Override
@@ -140,6 +142,6 @@
         LookupSwitchInsnNode clone = new LookupSwitchInsnNode(clone(dflt,
                 labels), null, clone(this.labels, labels));
         clone.keys.addAll(keys);
-        return clone;
+        return clone.cloneAnnotations(this);
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodInsnNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodInsnNode.java
index 16d554f..6f6d5dc 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodInsnNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodInsnNode.java
@@ -89,20 +89,21 @@
     /**
      * Constructs a new {@link MethodInsnNode}.
      *
-     * @param opcode the opcode of the type instruction to be constructed. This
-     *        opcode must be INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
-     *        INVOKEINTERFACE.
-     * @param owner the internal name of the method's owner class (see
-     *        {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}).
-     * @param name the method's name.
-     * @param desc the method's descriptor (see {@link jdk.internal.org.objectweb.asm.Type}).
+     * @param opcode
+     *            the opcode of the type instruction to be constructed. This
+     *            opcode must be INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
+     *            INVOKEINTERFACE.
+     * @param owner
+     *            the internal name of the method's owner class (see
+     *            {@link jdk.internal.org.objectweb.asm.Type#getInternalName()
+     *            getInternalName}).
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor (see {@link jdk.internal.org.objectweb.asm.Type}).
      */
-    public MethodInsnNode(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public MethodInsnNode(final int opcode, final String owner,
+            final String name, final String desc) {
         super(opcode);
         this.owner = owner;
         this.name = name;
@@ -112,8 +113,9 @@
     /**
      * Sets the opcode of this instruction.
      *
-     * @param opcode the new instruction opcode. This opcode must be
-     *        INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
+     * @param opcode
+     *            the new instruction opcode. This opcode must be INVOKEVIRTUAL,
+     *            INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
      */
     public void setOpcode(final int opcode) {
         this.opcode = opcode;
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java
index ab60cf2..072d549 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java
@@ -30,7 +30,6 @@
  *
  * ASM: a very small and fast Java bytecode manipulation framework
  * Copyright (c) 2000-2011 INRIA, France Telecom
- * Copyright (c) 2011 Google
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -71,6 +70,8 @@
 import jdk.internal.org.objectweb.asm.MethodVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.Type;
+import jdk.internal.org.objectweb.asm.TypePath;
+import jdk.internal.org.objectweb.asm.TypeReference;
 
 /**
  * A node that represents a method.
@@ -108,6 +109,11 @@
     public List<String> exceptions;
 
     /**
+     * The method parameter info (access flags and name)
+     */
+    public List<ParameterNode> parameters;
+
+    /**
      * The runtime visible annotations of this method. This list is a list of
      * {@link AnnotationNode} objects. May be <tt>null</tt>.
      *
@@ -126,6 +132,24 @@
     public List<AnnotationNode> invisibleAnnotations;
 
     /**
+     * The runtime visible type annotations of this method. This list is a list
+     * of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
+     *
+     * @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
+     * @label visible
+     */
+    public List<TypeAnnotationNode> visibleTypeAnnotations;
+
+    /**
+     * The runtime invisible type annotations of this method. This list is a
+     * list of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
+     *
+     * @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
+     * @label invisible
+     */
+    public List<TypeAnnotationNode> invisibleTypeAnnotations;
+
+    /**
      * The non standard attributes of this method. This list is a list of
      * {@link Attribute} objects. May be <tt>null</tt>.
      *
@@ -197,6 +221,22 @@
     public List<LocalVariableNode> localVariables;
 
     /**
+     * The visible local variable annotations of this method. This list is a
+     * list of {@link LocalVariableAnnotationNode} objects. May be <tt>null</tt>
+     *
+     * @associates jdk.internal.org.objectweb.asm.tree.LocalVariableAnnotationNode
+     */
+    public List<LocalVariableAnnotationNode> visibleLocalVariableAnnotations;
+
+    /**
+     * The invisible local variable annotations of this method. This list is a
+     * list of {@link LocalVariableAnnotationNode} objects. May be <tt>null</tt>
+     *
+     * @associates jdk.internal.org.objectweb.asm.tree.LocalVariableAnnotationNode
+     */
+    public List<LocalVariableAnnotationNode> invisibleLocalVariableAnnotations;
+
+    /**
      * If the accept method has been called on this object.
      */
     private boolean visited;
@@ -207,14 +247,15 @@
      * {@link #MethodNode(int)} version.
      */
     public MethodNode() {
-        this(Opcodes.ASM4);
+        this(Opcodes.ASM5);
     }
 
     /**
      * Constructs an uninitialized {@link MethodNode}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
      */
     public MethodNode(final int api) {
         super(api);
@@ -226,56 +267,55 @@
      * constructor</i>. Instead, they must use the
      * {@link #MethodNode(int, int, String, String, String, String[])} version.
      *
-     * @param access the method's access flags (see {@link Opcodes}). This
-     *        parameter also indicates if the method is synthetic and/or
-     *        deprecated.
-     * @param name the method's name.
-     * @param desc the method's descriptor (see {@link Type}).
-     * @param signature the method's signature. May be <tt>null</tt>.
-     * @param exceptions the internal names of the method's exception classes
-     *        (see {@link Type#getInternalName() getInternalName}). May be
-     *        <tt>null</tt>.
+     * @param access
+     *            the method's access flags (see {@link Opcodes}). This
+     *            parameter also indicates if the method is synthetic and/or
+     *            deprecated.
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor (see {@link Type}).
+     * @param signature
+     *            the method's signature. May be <tt>null</tt>.
+     * @param exceptions
+     *            the internal names of the method's exception classes (see
+     *            {@link Type#getInternalName() getInternalName}). May be
+     *            <tt>null</tt>.
      */
-    public MethodNode(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final String[] exceptions)
-    {
-        this(Opcodes.ASM4, access, name, desc, signature, exceptions);
+    public MethodNode(final int access, final String name, final String desc,
+            final String signature, final String[] exceptions) {
+        this(Opcodes.ASM5, access, name, desc, signature, exceptions);
     }
 
     /**
      * Constructs a new {@link MethodNode}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
-     * @param access the method's access flags (see {@link Opcodes}). This
-     *        parameter also indicates if the method is synthetic and/or
-     *        deprecated.
-     * @param name the method's name.
-     * @param desc the method's descriptor (see {@link Type}).
-     * @param signature the method's signature. May be <tt>null</tt>.
-     * @param exceptions the internal names of the method's exception classes
-     *        (see {@link Type#getInternalName() getInternalName}). May be
-     *        <tt>null</tt>.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param access
+     *            the method's access flags (see {@link Opcodes}). This
+     *            parameter also indicates if the method is synthetic and/or
+     *            deprecated.
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor (see {@link Type}).
+     * @param signature
+     *            the method's signature. May be <tt>null</tt>.
+     * @param exceptions
+     *            the internal names of the method's exception classes (see
+     *            {@link Type#getInternalName() getInternalName}). May be
+     *            <tt>null</tt>.
      */
-    public MethodNode(
-        final int api,
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final String[] exceptions)
-    {
+    public MethodNode(final int api, final int access, final String name,
+            final String desc, final String signature, final String[] exceptions) {
         super(api);
         this.access = access;
         this.name = name;
         this.desc = desc;
         this.signature = signature;
-        this.exceptions = new ArrayList<String>(exceptions == null
-                ? 0
+        this.exceptions = new ArrayList<String>(exceptions == null ? 0
                 : exceptions.length);
         boolean isAbstract = (access & Opcodes.ACC_ABSTRACT) != 0;
         if (!isAbstract) {
@@ -293,6 +333,14 @@
     // ------------------------------------------------------------------------
 
     @Override
+    public void visitParameter(String name, int access) {
+        if (parameters == null) {
+            parameters = new ArrayList<ParameterNode>(5);
+        }
+        parameters.add(new ParameterNode(name, access));
+    }
+
+    @Override
     public AnnotationVisitor visitAnnotationDefault() {
         return new AnnotationNode(new ArrayList<Object>(0) {
             @Override
@@ -304,10 +352,8 @@
     }
 
     @Override
-    public AnnotationVisitor visitAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public AnnotationVisitor visitAnnotation(final String desc,
+            final boolean visible) {
         AnnotationNode an = new AnnotationNode(desc);
         if (visible) {
             if (visibleAnnotations == null) {
@@ -324,28 +370,45 @@
     }
 
     @Override
-    public AnnotationVisitor visitParameterAnnotation(
-        final int parameter,
-        final String desc,
-        final boolean visible)
-    {
+    public AnnotationVisitor visitTypeAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
+        if (visible) {
+            if (visibleTypeAnnotations == null) {
+                visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
+            }
+            visibleTypeAnnotations.add(an);
+        } else {
+            if (invisibleTypeAnnotations == null) {
+                invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
+            }
+            invisibleTypeAnnotations.add(an);
+        }
+        return an;
+    }
+
+    @Override
+    public AnnotationVisitor visitParameterAnnotation(final int parameter,
+            final String desc, final boolean visible) {
         AnnotationNode an = new AnnotationNode(desc);
         if (visible) {
             if (visibleParameterAnnotations == null) {
                 int params = Type.getArgumentTypes(this.desc).length;
-                visibleParameterAnnotations = (List<AnnotationNode>[])new List<?>[params];
+                visibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params];
             }
             if (visibleParameterAnnotations[parameter] == null) {
-                visibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(1);
+                visibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(
+                        1);
             }
             visibleParameterAnnotations[parameter].add(an);
         } else {
             if (invisibleParameterAnnotations == null) {
                 int params = Type.getArgumentTypes(this.desc).length;
-                invisibleParameterAnnotations = (List<AnnotationNode>[])new List<?>[params];
+                invisibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params];
             }
             if (invisibleParameterAnnotations[parameter] == null) {
-                invisibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(1);
+                invisibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(
+                        1);
             }
             invisibleParameterAnnotations[parameter].add(an);
         }
@@ -365,17 +428,10 @@
     }
 
     @Override
-    public void visitFrame(
-        final int type,
-        final int nLocal,
-        final Object[] local,
-        final int nStack,
-        final Object[] stack)
-    {
-        instructions.add(new FrameNode(type, nLocal, local == null
-                ? null
-                : getLabelNodes(local), nStack, stack == null
-                ? null
+    public void visitFrame(final int type, final int nLocal,
+            final Object[] local, final int nStack, final Object[] stack) {
+        instructions.add(new FrameNode(type, nLocal, local == null ? null
+                : getLabelNodes(local), nStack, stack == null ? null
                 : getLabelNodes(stack)));
     }
 
@@ -400,32 +456,20 @@
     }
 
     @Override
-    public void visitFieldInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitFieldInsn(final int opcode, final String owner,
+            final String name, final String desc) {
         instructions.add(new FieldInsnNode(opcode, owner, name, desc));
     }
 
     @Override
-    public void visitMethodInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitMethodInsn(final int opcode, final String owner,
+            final String name, final String desc) {
         instructions.add(new MethodInsnNode(opcode, owner, name, desc));
     }
 
     @Override
-    public void visitInvokeDynamicInsn(
-        String name,
-        String desc,
-        Handle bsm,
-        Object... bsmArgs)
-    {
+    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+            Object... bsmArgs) {
         instructions.add(new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs));
     }
 
@@ -450,26 +494,16 @@
     }
 
     @Override
-    public void visitTableSwitchInsn(
-        final int min,
-        final int max,
-        final Label dflt,
-        final Label... labels)
-    {
-        instructions.add(new TableSwitchInsnNode(min,
-                max,
-                getLabelNode(dflt),
+    public void visitTableSwitchInsn(final int min, final int max,
+            final Label dflt, final Label... labels) {
+        instructions.add(new TableSwitchInsnNode(min, max, getLabelNode(dflt),
                 getLabelNodes(labels)));
     }
 
     @Override
-    public void visitLookupSwitchInsn(
-        final Label dflt,
-        final int[] keys,
-        final Label[] labels)
-    {
-        instructions.add(new LookupSwitchInsnNode(getLabelNode(dflt),
-                keys,
+    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+            final Label[] labels) {
+        instructions.add(new LookupSwitchInsnNode(getLabelNode(dflt), keys,
                 getLabelNodes(labels)));
     }
 
@@ -479,33 +513,89 @@
     }
 
     @Override
-    public void visitTryCatchBlock(
-        final Label start,
-        final Label end,
-        final Label handler,
-        final String type)
-    {
-        tryCatchBlocks.add(new TryCatchBlockNode(getLabelNode(start),
-                getLabelNode(end),
-                getLabelNode(handler),
-                type));
+    public AnnotationVisitor visitInsnAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        // Finds the last real instruction, i.e. the instruction targeted by
+        // this annotation.
+        AbstractInsnNode insn = instructions.getLast();
+        while (insn.getOpcode() == -1) {
+            insn = insn.getPrevious();
+        }
+        // Adds the annotation to this instruction.
+        TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
+        if (visible) {
+            if (insn.visibleTypeAnnotations == null) {
+                insn.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(
+                        1);
+            }
+            insn.visibleTypeAnnotations.add(an);
+        } else {
+            if (insn.invisibleTypeAnnotations == null) {
+                insn.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(
+                        1);
+            }
+            insn.invisibleTypeAnnotations.add(an);
+        }
+        return an;
     }
 
     @Override
-    public void visitLocalVariable(
-        final String name,
-        final String desc,
-        final String signature,
-        final Label start,
-        final Label end,
-        final int index)
-    {
-        localVariables.add(new LocalVariableNode(name,
-                desc,
-                signature,
-                getLabelNode(start),
-                getLabelNode(end),
-                index));
+    public void visitTryCatchBlock(final Label start, final Label end,
+            final Label handler, final String type) {
+        tryCatchBlocks.add(new TryCatchBlockNode(getLabelNode(start),
+                getLabelNode(end), getLabelNode(handler), type));
+    }
+
+    @Override
+    public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        TryCatchBlockNode tcb = tryCatchBlocks.get((typeRef & 0x00FFFF00) >> 8);
+        TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
+        if (visible) {
+            if (tcb.visibleTypeAnnotations == null) {
+                tcb.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(
+                        1);
+            }
+            tcb.visibleTypeAnnotations.add(an);
+        } else {
+            if (tcb.invisibleTypeAnnotations == null) {
+                tcb.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(
+                        1);
+            }
+            tcb.invisibleTypeAnnotations.add(an);
+        }
+        return an;
+    }
+
+    @Override
+    public void visitLocalVariable(final String name, final String desc,
+            final String signature, final Label start, final Label end,
+            final int index) {
+        localVariables.add(new LocalVariableNode(name, desc, signature,
+                getLabelNode(start), getLabelNode(end), index));
+    }
+
+    @Override
+    public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
+            TypePath typePath, Label[] start, Label[] end, int[] index,
+            String desc, boolean visible) {
+        LocalVariableAnnotationNode an = new LocalVariableAnnotationNode(
+                typeRef, typePath, getLabelNodes(start), getLabelNodes(end),
+                index, desc);
+        if (visible) {
+            if (visibleLocalVariableAnnotations == null) {
+                visibleLocalVariableAnnotations = new ArrayList<LocalVariableAnnotationNode>(
+                        1);
+            }
+            visibleLocalVariableAnnotations.add(an);
+        } else {
+            if (invisibleLocalVariableAnnotations == null) {
+                invisibleLocalVariableAnnotations = new ArrayList<LocalVariableAnnotationNode>(
+                        1);
+            }
+            invisibleLocalVariableAnnotations.add(an);
+        }
+        return an;
     }
 
     @Override
@@ -529,12 +619,13 @@
      * the {@link Label#info} field to store associations between labels and
      * label nodes.
      *
-     * @param l a Label.
+     * @param l
+     *            a Label.
      * @return the LabelNode corresponding to l.
      */
     protected LabelNode getLabelNode(final Label l) {
         if (!(l.info instanceof LabelNode)) {
-            l.info = new LabelNode(l);
+            l.info = new LabelNode();
         }
         return (LabelNode) l.info;
     }
@@ -569,24 +660,65 @@
      * recursively, do not contain elements that were introduced in more recent
      * versions of the ASM API than the given version.
      *
-     * @param api an ASM API version. Must be one of {@link Opcodes#ASM4}.
+     * @param api
+     *            an ASM API version. Must be one of {@link Opcodes#ASM4} or
+     *            {@link Opcodes#ASM5}.
      */
     public void check(final int api) {
-        // nothing to do
+        if (api == Opcodes.ASM4) {
+            if (visibleTypeAnnotations != null
+                    && visibleTypeAnnotations.size() > 0) {
+                throw new RuntimeException();
+            }
+            if (invisibleTypeAnnotations != null
+                    && invisibleTypeAnnotations.size() > 0) {
+                throw new RuntimeException();
+            }
+            int n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size();
+            for (int i = 0; i < n; ++i) {
+                TryCatchBlockNode tcb = tryCatchBlocks.get(i);
+                if (tcb.visibleTypeAnnotations != null
+                        && tcb.visibleTypeAnnotations.size() > 0) {
+                    throw new RuntimeException();
+                }
+                if (tcb.invisibleTypeAnnotations != null
+                        && tcb.invisibleTypeAnnotations.size() > 0) {
+                    throw new RuntimeException();
+                }
+            }
+            for (int i = 0; i < instructions.size(); ++i) {
+                AbstractInsnNode insn = instructions.get(i);
+                if (insn.visibleTypeAnnotations != null
+                        && insn.visibleTypeAnnotations.size() > 0) {
+                    throw new RuntimeException();
+                }
+                if (insn.invisibleTypeAnnotations != null
+                        && insn.invisibleTypeAnnotations.size() > 0) {
+                    throw new RuntimeException();
+                }
+            }
+            if (visibleLocalVariableAnnotations != null
+                    && visibleLocalVariableAnnotations.size() > 0) {
+                throw new RuntimeException();
+            }
+            if (invisibleLocalVariableAnnotations != null
+                    && invisibleLocalVariableAnnotations.size() > 0) {
+                throw new RuntimeException();
+            }
+
+        }
     }
 
     /**
      * Makes the given class visitor visit this method.
      *
-     * @param cv a class visitor.
+     * @param cv
+     *            a class visitor.
      */
     public void accept(final ClassVisitor cv) {
         String[] exceptions = new String[this.exceptions.size()];
         this.exceptions.toArray(exceptions);
-        MethodVisitor mv = cv.visitMethod(access,
-                name,
-                desc,
-                signature,
+        MethodVisitor mv = cv.visitMethod(access, name, desc, signature,
                 exceptions);
         if (mv != null) {
             accept(mv);
@@ -596,11 +728,18 @@
     /**
      * Makes the given method visitor visit this method.
      *
-     * @param mv a method visitor.
+     * @param mv
+     *            a method visitor.
      */
     public void accept(final MethodVisitor mv) {
-        // visits the method attributes
+        // visits the method parameters
         int i, j, n;
+        n = parameters == null ? 0 : parameters.size();
+        for (i = 0; i < n; i++) {
+            ParameterNode parameter = parameters.get(i);
+            mv.visitParameter(parameter.name, parameter.access);
+        }
+        // visits the method attributes
         if (annotationDefault != null) {
             AnnotationVisitor av = mv.visitAnnotationDefault();
             AnnotationNode.accept(av, null, annotationDefault);
@@ -618,8 +757,20 @@
             AnnotationNode an = invisibleAnnotations.get(i);
             an.accept(mv.visitAnnotation(an.desc, false));
         }
-        n = visibleParameterAnnotations == null
-                ? 0
+        n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size();
+        for (i = 0; i < n; ++i) {
+            TypeAnnotationNode an = visibleTypeAnnotations.get(i);
+            an.accept(mv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
+                    true));
+        }
+        n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
+                .size();
+        for (i = 0; i < n; ++i) {
+            TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
+            an.accept(mv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
+                    false));
+        }
+        n = visibleParameterAnnotations == null ? 0
                 : visibleParameterAnnotations.length;
         for (i = 0; i < n; ++i) {
             List<?> l = visibleParameterAnnotations[i];
@@ -631,8 +782,7 @@
                 an.accept(mv.visitParameterAnnotation(i, an.desc, true));
             }
         }
-        n = invisibleParameterAnnotations == null
-                ? 0
+        n = invisibleParameterAnnotations == null ? 0
                 : invisibleParameterAnnotations.length;
         for (i = 0; i < n; ++i) {
             List<?> l = invisibleParameterAnnotations[i];
@@ -657,6 +807,7 @@
             // visits try catch blocks
             n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size();
             for (i = 0; i < n; ++i) {
+                tryCatchBlocks.get(i).updateIndex(i);
                 tryCatchBlocks.get(i).accept(mv);
             }
             // visits instructions
@@ -666,6 +817,17 @@
             for (i = 0; i < n; ++i) {
                 localVariables.get(i).accept(mv);
             }
+            // visits local variable annotations
+            n = visibleLocalVariableAnnotations == null ? 0
+                    : visibleLocalVariableAnnotations.size();
+            for (i = 0; i < n; ++i) {
+                visibleLocalVariableAnnotations.get(i).accept(mv, true);
+            }
+            n = invisibleLocalVariableAnnotations == null ? 0
+                    : invisibleLocalVariableAnnotations.size();
+            for (i = 0; i < n; ++i) {
+                invisibleLocalVariableAnnotations.get(i).accept(mv, false);
+            }
             // visits maxs
             mv.visitMaxs(maxStack, maxLocals);
             visited = true;
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MultiANewArrayInsnNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MultiANewArrayInsnNode.java
index 70e5625..2f96989 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MultiANewArrayInsnNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MultiANewArrayInsnNode.java
@@ -83,8 +83,10 @@
     /**
      * Constructs a new {@link MultiANewArrayInsnNode}.
      *
-     * @param desc an array type descriptor (see {@link jdk.internal.org.objectweb.asm.Type}).
-     * @param dims number of dimensions of the array to allocate.
+     * @param desc
+     *            an array type descriptor (see {@link jdk.internal.org.objectweb.asm.Type}).
+     * @param dims
+     *            number of dimensions of the array to allocate.
      */
     public MultiANewArrayInsnNode(final String desc, final int dims) {
         super(Opcodes.MULTIANEWARRAY);
@@ -100,11 +102,12 @@
     @Override
     public void accept(final MethodVisitor mv) {
         mv.visitMultiANewArrayInsn(desc, dims);
+        acceptAnnotations(mv);
     }
 
     @Override
     public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
-        return new MultiANewArrayInsnNode(desc, dims);
+        return new MultiANewArrayInsnNode(desc, dims).cloneAnnotations(this);
     }
 
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/ParameterNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/ParameterNode.java
new file mode 100644
index 0000000..7487342
--- /dev/null
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/ParameterNode.java
@@ -0,0 +1,105 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+
+/**
+ * A node that represents a parameter access and name.
+ *
+ * @author Remi Forax
+ */
+public class ParameterNode {
+    /**
+     * The parameter's name.
+     */
+    public String name;
+
+    /**
+     * The parameter's access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
+     * Valid values are <tt>ACC_FINAL</tt>, <tt>ACC_SYNTHETIC</tt> and
+     * <tt>ACC_MANDATED</tt>.
+     */
+    public int access;
+
+    /**
+     * Constructs a new {@link ParameterNode}.
+     *
+     * @param access
+     *            The parameter's access flags. Valid values are
+     *            <tt>ACC_FINAL</tt>, <tt>ACC_SYNTHETIC</tt> or/and
+     *            <tt>ACC_MANDATED</tt> (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
+     * @param name
+     *            the parameter's name.
+     */
+    public ParameterNode(final String name, final int access) {
+        this.name = name;
+        this.access = access;
+    }
+
+    /**
+     * Makes the given visitor visit this parameter declaration.
+     *
+     * @param mv
+     *            a method visitor.
+     */
+    public void accept(final MethodVisitor mv) {
+        mv.visitParameter(name, access);
+    }
+}
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/TableSwitchInsnNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/TableSwitchInsnNode.java
index d1b80a8..89e219c 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/TableSwitchInsnNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/TableSwitchInsnNode.java
@@ -98,18 +98,18 @@
     /**
      * Constructs a new {@link TableSwitchInsnNode}.
      *
-     * @param min the minimum key value.
-     * @param max the maximum key value.
-     * @param dflt beginning of the default handler block.
-     * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is
-     *        the beginning of the handler block for the <tt>min + i</tt> key.
+     * @param min
+     *            the minimum key value.
+     * @param max
+     *            the maximum key value.
+     * @param dflt
+     *            beginning of the default handler block.
+     * @param labels
+     *            beginnings of the handler blocks. <tt>labels[i]</tt> is the
+     *            beginning of the handler block for the <tt>min + i</tt> key.
      */
-    public TableSwitchInsnNode(
-        final int min,
-        final int max,
-        final LabelNode dflt,
-        final LabelNode... labels)
-    {
+    public TableSwitchInsnNode(final int min, final int max,
+            final LabelNode dflt, final LabelNode... labels) {
         super(Opcodes.TABLESWITCH);
         this.min = min;
         this.max = max;
@@ -132,13 +132,12 @@
             labels[i] = this.labels.get(i).getLabel();
         }
         mv.visitTableSwitchInsn(min, max, dflt.getLabel(), labels);
+        acceptAnnotations(mv);
     }
 
     @Override
     public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
-        return new TableSwitchInsnNode(min,
-                max,
-                clone(dflt, labels),
-                clone(this.labels, labels));
+        return new TableSwitchInsnNode(min, max, clone(dflt, labels), clone(
+                this.labels, labels)).cloneAnnotations(this);
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/TryCatchBlockNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/TryCatchBlockNode.java
index 6d99611..8845756 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/TryCatchBlockNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/TryCatchBlockNode.java
@@ -58,6 +58,8 @@
  */
 package jdk.internal.org.objectweb.asm.tree;
 
+import java.util.List;
+
 import jdk.internal.org.objectweb.asm.MethodVisitor;
 
 /**
@@ -89,21 +91,41 @@
     public String type;
 
     /**
+     * The runtime visible type annotations on the exception handler type. This
+     * list is a list of {@link TypeAnnotationNode} objects. May be
+     * <tt>null</tt>.
+     *
+     * @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
+     * @label visible
+     */
+    public List<TypeAnnotationNode> visibleTypeAnnotations;
+
+    /**
+     * The runtime invisible type annotations on the exception handler type.
+     * This list is a list of {@link TypeAnnotationNode} objects. May be
+     * <tt>null</tt>.
+     *
+     * @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode
+     * @label invisible
+     */
+    public List<TypeAnnotationNode> invisibleTypeAnnotations;
+
+    /**
      * Constructs a new {@link TryCatchBlockNode}.
      *
-     * @param start beginning of the exception handler's scope (inclusive).
-     * @param end end of the exception handler's scope (exclusive).
-     * @param handler beginning of the exception handler's code.
-     * @param type internal name of the type of exceptions handled by the
-     *        handler, or <tt>null</tt> to catch any exceptions (for "finally"
-     *        blocks).
+     * @param start
+     *            beginning of the exception handler's scope (inclusive).
+     * @param end
+     *            end of the exception handler's scope (exclusive).
+     * @param handler
+     *            beginning of the exception handler's code.
+     * @param type
+     *            internal name of the type of exceptions handled by the
+     *            handler, or <tt>null</tt> to catch any exceptions (for
+     *            "finally" blocks).
      */
-    public TryCatchBlockNode(
-        final LabelNode start,
-        final LabelNode end,
-        final LabelNode handler,
-        final String type)
-    {
+    public TryCatchBlockNode(final LabelNode start, final LabelNode end,
+            final LabelNode handler, final String type) {
         this.start = start;
         this.end = end;
         this.handler = handler;
@@ -111,13 +133,50 @@
     }
 
     /**
+     * Updates the index of this try catch block in the method's list of try
+     * catch block nodes. This index maybe stored in the 'target' field of the
+     * type annotations of this block.
+     *
+     * @param index
+     *            the new index of this try catch block in the method's list of
+     *            try catch block nodes.
+     */
+    public void updateIndex(final int index) {
+        int newTypeRef = 0x42000000 | (index << 8);
+        if (visibleTypeAnnotations != null) {
+            for (TypeAnnotationNode tan : visibleTypeAnnotations) {
+                tan.typeRef = newTypeRef;
+            }
+        }
+        if (invisibleTypeAnnotations != null) {
+            for (TypeAnnotationNode tan : invisibleTypeAnnotations) {
+                tan.typeRef = newTypeRef;
+            }
+        }
+    }
+
+    /**
      * Makes the given visitor visit this try catch block.
      *
-     * @param mv a method visitor.
+     * @param mv
+     *            a method visitor.
      */
     public void accept(final MethodVisitor mv) {
-        mv.visitTryCatchBlock(start.getLabel(), end.getLabel(), handler == null
-                ? null
-                : handler.getLabel(), type);
+        mv.visitTryCatchBlock(start.getLabel(), end.getLabel(),
+                handler == null ? null : handler.getLabel(), type);
+        int n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations
+                .size();
+        for (int i = 0; i < n; ++i) {
+            TypeAnnotationNode an = visibleTypeAnnotations.get(i);
+            an.accept(mv.visitTryCatchAnnotation(an.typeRef, an.typePath,
+                    an.desc, true));
+        }
+        n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
+                .size();
+        for (int i = 0; i < n; ++i) {
+            TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
+            an.accept(mv.visitTryCatchAnnotation(an.typeRef, an.typePath,
+                    an.desc, false));
+        }
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/TypeAnnotationNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/TypeAnnotationNode.java
new file mode 100644
index 0000000..c9e21d8
--- /dev/null
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/TypeAnnotationNode.java
@@ -0,0 +1,124 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.TypePath;
+import jdk.internal.org.objectweb.asm.TypeReference;
+
+/**
+ * A node that represents a type annotationn.
+ *
+ * @author Eric Bruneton
+ */
+public class TypeAnnotationNode extends AnnotationNode {
+
+    /**
+     * A reference to the annotated type. See {@link TypeReference}.
+     */
+    public int typeRef;
+
+    /**
+     * The path to the annotated type argument, wildcard bound, array element
+     * type, or static outer type within the referenced type. May be
+     * <tt>null</tt> if the annotation targets 'typeRef' as a whole.
+     */
+    public TypePath typePath;
+
+    /**
+     * Constructs a new {@link AnnotationNode}. <i>Subclasses must not use this
+     * constructor</i>. Instead, they must use the
+     * {@link #TypeAnnotationNode(int, int, TypePath, String)} version.
+     *
+     * @param typeRef
+     *            a reference to the annotated type. See {@link TypeReference}.
+     * @param typePath
+     *            the path to the annotated type argument, wildcard bound, array
+     *            element type, or static inner type within 'typeRef'. May be
+     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
+     * @param desc
+     *            the class descriptor of the annotation class.
+     */
+    public TypeAnnotationNode(final int typeRef, final TypePath typePath,
+            final String desc) {
+        this(Opcodes.ASM5, typeRef, typePath, desc);
+    }
+
+    /**
+     * Constructs a new {@link AnnotationNode}.
+     *
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param typeRef
+     *            a reference to the annotated type. See {@link TypeReference}.
+     * @param typePath
+     *            the path to the annotated type argument, wildcard bound, array
+     *            element type, or static inner type within 'typeRef'. May be
+     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
+     * @param desc
+     *            the class descriptor of the annotation class.
+     */
+    public TypeAnnotationNode(final int api, final int typeRef,
+            final TypePath typePath, final String desc) {
+        super(api, desc);
+        this.typeRef = typeRef;
+        this.typePath = typePath;
+    }
+}
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/TypeInsnNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/TypeInsnNode.java
index 7eb13b4..5bda116 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/TypeInsnNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/TypeInsnNode.java
@@ -79,10 +79,12 @@
     /**
      * Constructs a new {@link TypeInsnNode}.
      *
-     * @param opcode the opcode of the type instruction to be constructed. This
-     *        opcode must be NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
-     * @param desc the operand of the instruction to be constructed. This
-     *        operand is an internal name (see {@link jdk.internal.org.objectweb.asm.Type}).
+     * @param opcode
+     *            the opcode of the type instruction to be constructed. This
+     *            opcode must be NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
+     * @param desc
+     *            the operand of the instruction to be constructed. This operand
+     *            is an internal name (see {@link jdk.internal.org.objectweb.asm.Type}).
      */
     public TypeInsnNode(final int opcode, final String desc) {
         super(opcode);
@@ -92,8 +94,9 @@
     /**
      * Sets the opcode of this instruction.
      *
-     * @param opcode the new instruction opcode. This opcode must be NEW,
-     *        ANEWARRAY, CHECKCAST or INSTANCEOF.
+     * @param opcode
+     *            the new instruction opcode. This opcode must be NEW,
+     *            ANEWARRAY, CHECKCAST or INSTANCEOF.
      */
     public void setOpcode(final int opcode) {
         this.opcode = opcode;
@@ -107,10 +110,11 @@
     @Override
     public void accept(final MethodVisitor mv) {
         mv.visitTypeInsn(opcode, desc);
+        acceptAnnotations(mv);
     }
 
     @Override
     public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
-        return new TypeInsnNode(opcode, desc);
+        return new TypeInsnNode(opcode, desc).cloneAnnotations(this);
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/VarInsnNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/VarInsnNode.java
index eaa2488..2ec8198 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/VarInsnNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/VarInsnNode.java
@@ -80,11 +80,13 @@
     /**
      * Constructs a new {@link VarInsnNode}.
      *
-     * @param opcode the opcode of the local variable instruction to be
-     *        constructed. This opcode must be ILOAD, LLOAD, FLOAD, DLOAD,
-     *        ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
-     * @param var the operand of the instruction to be constructed. This operand
-     *        is the index of a local variable.
+     * @param opcode
+     *            the opcode of the local variable instruction to be
+     *            constructed. This opcode must be ILOAD, LLOAD, FLOAD, DLOAD,
+     *            ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
+     * @param var
+     *            the operand of the instruction to be constructed. This operand
+     *            is the index of a local variable.
      */
     public VarInsnNode(final int opcode, final int var) {
         super(opcode);
@@ -94,9 +96,10 @@
     /**
      * Sets the opcode of this instruction.
      *
-     * @param opcode the new instruction opcode. This opcode must be ILOAD,
-     *        LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE
-     *        or RET.
+     * @param opcode
+     *            the new instruction opcode. This opcode must be ILOAD, LLOAD,
+     *            FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or
+     *            RET.
      */
     public void setOpcode(final int opcode) {
         this.opcode = opcode;
@@ -110,10 +113,11 @@
     @Override
     public void accept(final MethodVisitor mv) {
         mv.visitVarInsn(opcode, var);
+        acceptAnnotations(mv);
     }
 
     @Override
     public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
-        return new VarInsnNode(opcode, var);
+        return new VarInsnNode(opcode, var).cloneAnnotations(this);
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Analyzer.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Analyzer.java
index ff95c4d..8f98753 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Analyzer.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Analyzer.java
@@ -30,7 +30,6 @@
  *
  * ASM: a very small and fast Java bytecode manipulation framework
  * Copyright (c) 2000-2011 INRIA, France Telecom
- * Copyright (c) 2011 Google
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -81,9 +80,10 @@
  * A semantic bytecode analyzer. <i>This class does not fully check that JSR and
  * RET instructions are valid.</i>
  *
- * @param <V> type of the Value used for the analysis.
+ * @param <V>
+ *            type of the Value used for the analysis.
  *
- *  @author Eric Bruneton
+ * @author Eric Bruneton
  */
 public class Analyzer<V extends Value> implements Opcodes {
 
@@ -108,8 +108,9 @@
     /**
      * Constructs a new {@link Analyzer}.
      *
-     * @param interpreter the interpreter to be used to symbolically interpret
-     *        the bytecode instructions.
+     * @param interpreter
+     *            the interpreter to be used to symbolically interpret the
+     *            bytecode instructions.
      */
     public Analyzer(final Interpreter<V> interpreter) {
         this.interpreter = interpreter;
@@ -118,26 +119,28 @@
     /**
      * Analyzes the given method.
      *
-     * @param owner the internal name of the class to which the method belongs.
-     * @param m the method to be analyzed.
+     * @param owner
+     *            the internal name of the class to which the method belongs.
+     * @param m
+     *            the method to be analyzed.
      * @return the symbolic state of the execution stack frame at each bytecode
      *         instruction of the method. The size of the returned array is
      *         equal to the number of instructions (and labels) of the method. A
      *         given frame is <tt>null</tt> if and only if the corresponding
      *         instruction cannot be reached (dead code).
-     * @throws AnalyzerException if a problem occurs during the analysis.
+     * @throws AnalyzerException
+     *             if a problem occurs during the analysis.
      */
     public Frame<V>[] analyze(final String owner, final MethodNode m)
-            throws AnalyzerException
-    {
+            throws AnalyzerException {
         if ((m.access & (ACC_ABSTRACT | ACC_NATIVE)) != 0) {
-            frames = (Frame<V>[])new Frame<?>[0];
+            frames = (Frame<V>[]) new Frame<?>[0];
             return frames;
         }
         n = m.instructions.size();
         insns = m.instructions;
-        handlers = (List<TryCatchBlockNode>[])new List<?>[n];
-        frames = (Frame<V>[])new Frame<?>[n];
+        handlers = (List<TryCatchBlockNode>[]) new List<?>[n];
+        frames = (Frame<V>[]) new Frame<?>[n];
         subroutines = new Subroutine[n];
         queued = new boolean[n];
         queue = new int[n];
@@ -218,8 +221,7 @@
 
                 if (insnType == AbstractInsnNode.LABEL
                         || insnType == AbstractInsnNode.LINE
-                        || insnType == AbstractInsnNode.FRAME)
-                {
+                        || insnType == AbstractInsnNode.FRAME) {
                     merge(insn + 1, f, subroutine);
                     newControlFlowEdge(insn, insn + 1);
                 } else {
@@ -235,8 +237,7 @@
                         int jump = insns.indexOf(j.label);
                         if (insnOpcode == JSR) {
                             merge(jump, current, new Subroutine(j.label,
-                                    m.maxLocals,
-                                    j));
+                                    m.maxLocals, j));
                         } else {
                             merge(jump, current, subroutine);
                         }
@@ -265,31 +266,27 @@
                         }
                     } else if (insnOpcode == RET) {
                         if (subroutine == null) {
-                            throw new AnalyzerException(insnNode, "RET instruction outside of a sub routine");
+                            throw new AnalyzerException(insnNode,
+                                    "RET instruction outside of a sub routine");
                         }
                         for (int i = 0; i < subroutine.callers.size(); ++i) {
                             JumpInsnNode caller = subroutine.callers.get(i);
                             int call = insns.indexOf(caller);
                             if (frames[call] != null) {
-                                merge(call + 1,
-                                        frames[call],
-                                        current,
-                                        subroutines[call],
-                                        subroutine.access);
+                                merge(call + 1, frames[call], current,
+                                        subroutines[call], subroutine.access);
                                 newControlFlowEdge(insn, call + 1);
                             }
                         }
                     } else if (insnOpcode != ATHROW
-                            && (insnOpcode < IRETURN || insnOpcode > RETURN))
-                    {
+                            && (insnOpcode < IRETURN || insnOpcode > RETURN)) {
                         if (subroutine != null) {
                             if (insnNode instanceof VarInsnNode) {
                                 int var = ((VarInsnNode) insnNode).var;
                                 subroutine.access[var] = true;
                                 if (insnOpcode == LLOAD || insnOpcode == DLOAD
                                         || insnOpcode == LSTORE
-                                        || insnOpcode == DSTORE)
-                                {
+                                        || insnOpcode == DSTORE) {
                                     subroutine.access[var + 1] = true;
                                 }
                             } else if (insnNode instanceof IincInsnNode) {
@@ -322,23 +319,23 @@
                     }
                 }
             } catch (AnalyzerException e) {
-                throw new AnalyzerException(e.node, "Error at instruction " + insn
-                        + ": " + e.getMessage(), e);
+                throw new AnalyzerException(e.node, "Error at instruction "
+                        + insn + ": " + e.getMessage(), e);
             } catch (Exception e) {
-                throw new AnalyzerException(insnNode, "Error at instruction " + insn
-                        + ": " + e.getMessage(), e);
+                throw new AnalyzerException(insnNode, "Error at instruction "
+                        + insn + ": " + e.getMessage(), e);
             }
         }
 
         return frames;
     }
 
-    private void findSubroutine(int insn, final Subroutine sub, final List<AbstractInsnNode> calls)
-            throws AnalyzerException
-    {
+    private void findSubroutine(int insn, final Subroutine sub,
+            final List<AbstractInsnNode> calls) throws AnalyzerException {
         while (true) {
             if (insn < 0 || insn >= n) {
-                throw new AnalyzerException(null, "Execution can fall off end of the code");
+                throw new AnalyzerException(null,
+                        "Execution can fall off end of the code");
             }
             if (subroutines[insn] != null) {
                 return;
@@ -382,18 +379,18 @@
 
             // if insn does not falls through to the next instruction, return.
             switch (node.getOpcode()) {
-                case GOTO:
-                case RET:
-                case TABLESWITCH:
-                case LOOKUPSWITCH:
-                case IRETURN:
-                case LRETURN:
-                case FRETURN:
-                case DRETURN:
-                case ARETURN:
-                case RETURN:
-                case ATHROW:
-                    return;
+            case GOTO:
+            case RET:
+            case TABLESWITCH:
+            case LOOKUPSWITCH:
+            case IRETURN:
+            case LRETURN:
+            case FRETURN:
+            case DRETURN:
+            case ARETURN:
+            case RETURN:
+            case ATHROW:
+                return;
             }
             insn++;
         }
@@ -417,8 +414,9 @@
     /**
      * Returns the exception handlers for the given instruction.
      *
-     * @param insn the index of an instruction of the last recently analyzed
-     *        method.
+     * @param insn
+     *            the index of an instruction of the last recently analyzed
+     *            method.
      * @return a list of {@link TryCatchBlockNode} objects.
      */
     public List<TryCatchBlockNode> getHandlers(final int insn) {
@@ -430,9 +428,12 @@
      * execution of control flow analysis loop in #analyze. The default
      * implementation of this method does nothing.
      *
-     * @param owner the internal name of the class to which the method belongs.
-     * @param m the method to be analyzed.
-     * @throws AnalyzerException if a problem occurs.
+     * @param owner
+     *            the internal name of the class to which the method belongs.
+     * @param m
+     *            the method to be analyzed.
+     * @throws AnalyzerException
+     *             if a problem occurs.
      */
     protected void init(String owner, MethodNode m) throws AnalyzerException {
     }
@@ -440,8 +441,10 @@
     /**
      * Constructs a new frame with the given size.
      *
-     * @param nLocals the maximum number of local variables of the frame.
-     * @param nStack the maximum stack size of the frame.
+     * @param nLocals
+     *            the maximum number of local variables of the frame.
+     * @param nStack
+     *            the maximum stack size of the frame.
      * @return the created frame.
      */
     protected Frame<V> newFrame(final int nLocals, final int nStack) {
@@ -451,7 +454,8 @@
     /**
      * Constructs a new frame that is identical to the given frame.
      *
-     * @param src a frame.
+     * @param src
+     *            a frame.
      * @return the created frame.
      */
     protected Frame<V> newFrame(final Frame<? extends V> src) {
@@ -464,8 +468,10 @@
      * control flow graph of a method (this method is called by the
      * {@link #analyze analyze} method during its visit of the method's code).
      *
-     * @param insn an instruction index.
-     * @param successor index of a successor instruction.
+     * @param insn
+     *            an instruction index.
+     * @param successor
+     *            index of a successor instruction.
      */
     protected void newControlFlowEdge(final int insn, final int successor) {
     }
@@ -477,16 +483,16 @@
      * method is called by the {@link #analyze analyze} method during its visit
      * of the method's code).
      *
-     * @param insn an instruction index.
-     * @param successor index of a successor instruction.
+     * @param insn
+     *            an instruction index.
+     * @param successor
+     *            index of a successor instruction.
      * @return true if this edge must be considered in the data flow analysis
      *         performed by this analyzer, or false otherwise. The default
      *         implementation of this method always returns true.
      */
-    protected boolean newControlFlowExceptionEdge(
-        final int insn,
-        final int successor)
-    {
+    protected boolean newControlFlowExceptionEdge(final int insn,
+            final int successor) {
         return true;
     }
 
@@ -499,28 +505,25 @@
      * the {@link #analyze analyze} method during its visit of the method's
      * code).
      *
-     * @param insn an instruction index.
-     * @param tcb TryCatchBlockNode corresponding to this edge.
+     * @param insn
+     *            an instruction index.
+     * @param tcb
+     *            TryCatchBlockNode corresponding to this edge.
      * @return true if this edge must be considered in the data flow analysis
      *         performed by this analyzer, or false otherwise. The default
      *         implementation of this method delegates to
      *         {@link #newControlFlowExceptionEdge(int, int)
      *         newControlFlowExceptionEdge(int, int)}.
      */
-    protected boolean newControlFlowExceptionEdge(
-        final int insn,
-        final TryCatchBlockNode tcb)
-    {
+    protected boolean newControlFlowExceptionEdge(final int insn,
+            final TryCatchBlockNode tcb) {
         return newControlFlowExceptionEdge(insn, insns.indexOf(tcb.handler));
     }
 
     // -------------------------------------------------------------------------
 
-    private void merge(
-        final int insn,
-        final Frame<V> frame,
-        final Subroutine subroutine) throws AnalyzerException
-    {
+    private void merge(final int insn, final Frame<V> frame,
+            final Subroutine subroutine) throws AnalyzerException {
         Frame<V> oldFrame = frames[insn];
         Subroutine oldSubroutine = subroutines[insn];
         boolean changes;
@@ -548,13 +551,9 @@
         }
     }
 
-    private void merge(
-        final int insn,
-        final Frame<V> beforeJSR,
-        final Frame<V> afterRET,
-        final Subroutine subroutineBeforeJSR,
-        final boolean[] access) throws AnalyzerException
-    {
+    private void merge(final int insn, final Frame<V> beforeJSR,
+            final Frame<V> afterRET, final Subroutine subroutineBeforeJSR,
+            final boolean[] access) throws AnalyzerException {
         Frame<V> oldFrame = frames[insn];
         Subroutine oldSubroutine = subroutines[insn];
         boolean changes;
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/AnalyzerException.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/AnalyzerException.java
index a18f5d3..c3678c8 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/AnalyzerException.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/AnalyzerException.java
@@ -75,17 +75,14 @@
         this.node = node;
     }
 
-    public AnalyzerException(final AbstractInsnNode node, final String msg, final Throwable exception) {
+    public AnalyzerException(final AbstractInsnNode node, final String msg,
+            final Throwable exception) {
         super(msg, exception);
         this.node = node;
     }
 
-    public AnalyzerException(
-        final AbstractInsnNode node,
-        final String msg,
-        final Object expected,
-        final Value encountered)
-    {
+    public AnalyzerException(final AbstractInsnNode node, final String msg,
+            final Object expected, final Value encountered) {
         super((msg == null ? "Expected " : msg + ": expected ") + expected
                 + ", but found " + encountered);
         this.node = node;
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicInterpreter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicInterpreter.java
index 7df82f6..e450166 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicInterpreter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicInterpreter.java
@@ -79,11 +79,10 @@
  * @author Bing Ran
  */
 public class BasicInterpreter extends Interpreter<BasicValue> implements
-        Opcodes
-{
+        Opcodes {
 
     public BasicInterpreter() {
-        super(ASM4);
+        super(ASM5);
     }
 
     protected BasicInterpreter(final int api) {
@@ -96,292 +95,286 @@
             return BasicValue.UNINITIALIZED_VALUE;
         }
         switch (type.getSort()) {
-            case Type.VOID:
-                return null;
-            case Type.BOOLEAN:
-            case Type.CHAR:
-            case Type.BYTE:
-            case Type.SHORT:
-            case Type.INT:
-                return BasicValue.INT_VALUE;
-            case Type.FLOAT:
-                return BasicValue.FLOAT_VALUE;
-            case Type.LONG:
-                return BasicValue.LONG_VALUE;
-            case Type.DOUBLE:
-                return BasicValue.DOUBLE_VALUE;
-            case Type.ARRAY:
-            case Type.OBJECT:
-                return BasicValue.REFERENCE_VALUE;
-            default:
-                throw new Error("Internal error");
+        case Type.VOID:
+            return null;
+        case Type.BOOLEAN:
+        case Type.CHAR:
+        case Type.BYTE:
+        case Type.SHORT:
+        case Type.INT:
+            return BasicValue.INT_VALUE;
+        case Type.FLOAT:
+            return BasicValue.FLOAT_VALUE;
+        case Type.LONG:
+            return BasicValue.LONG_VALUE;
+        case Type.DOUBLE:
+            return BasicValue.DOUBLE_VALUE;
+        case Type.ARRAY:
+        case Type.OBJECT:
+            return BasicValue.REFERENCE_VALUE;
+        default:
+            throw new Error("Internal error");
         }
     }
 
     @Override
     public BasicValue newOperation(final AbstractInsnNode insn)
-            throws AnalyzerException
-    {
+            throws AnalyzerException {
         switch (insn.getOpcode()) {
-            case ACONST_NULL:
-                return newValue(Type.getObjectType("null"));
-            case ICONST_M1:
-            case ICONST_0:
-            case ICONST_1:
-            case ICONST_2:
-            case ICONST_3:
-            case ICONST_4:
-            case ICONST_5:
+        case ACONST_NULL:
+            return newValue(Type.getObjectType("null"));
+        case ICONST_M1:
+        case ICONST_0:
+        case ICONST_1:
+        case ICONST_2:
+        case ICONST_3:
+        case ICONST_4:
+        case ICONST_5:
+            return BasicValue.INT_VALUE;
+        case LCONST_0:
+        case LCONST_1:
+            return BasicValue.LONG_VALUE;
+        case FCONST_0:
+        case FCONST_1:
+        case FCONST_2:
+            return BasicValue.FLOAT_VALUE;
+        case DCONST_0:
+        case DCONST_1:
+            return BasicValue.DOUBLE_VALUE;
+        case BIPUSH:
+        case SIPUSH:
+            return BasicValue.INT_VALUE;
+        case LDC:
+            Object cst = ((LdcInsnNode) insn).cst;
+            if (cst instanceof Integer) {
                 return BasicValue.INT_VALUE;
-            case LCONST_0:
-            case LCONST_1:
-                return BasicValue.LONG_VALUE;
-            case FCONST_0:
-            case FCONST_1:
-            case FCONST_2:
+            } else if (cst instanceof Float) {
                 return BasicValue.FLOAT_VALUE;
-            case DCONST_0:
-            case DCONST_1:
+            } else if (cst instanceof Long) {
+                return BasicValue.LONG_VALUE;
+            } else if (cst instanceof Double) {
                 return BasicValue.DOUBLE_VALUE;
-            case BIPUSH:
-            case SIPUSH:
-                return BasicValue.INT_VALUE;
-            case LDC:
-                Object cst = ((LdcInsnNode) insn).cst;
-                if (cst instanceof Integer) {
-                    return BasicValue.INT_VALUE;
-                } else if (cst instanceof Float) {
-                    return BasicValue.FLOAT_VALUE;
-                } else if (cst instanceof Long) {
-                    return BasicValue.LONG_VALUE;
-                } else if (cst instanceof Double) {
-                    return BasicValue.DOUBLE_VALUE;
-                } else if (cst instanceof String) {
-                    return newValue(Type.getObjectType("java/lang/String"));
-                } else if (cst instanceof Type) {
-                    int sort = ((Type) cst).getSort();
-                    if (sort == Type.OBJECT || sort == Type.ARRAY) {
-                        return newValue(Type.getObjectType("java/lang/Class"));
-                    } else if (sort == Type.METHOD) {
-                        return newValue(Type.getObjectType("java/lang/invoke/MethodType"));
-                    } else {
-                        throw new IllegalArgumentException("Illegal LDC constant " + cst);
-                    }
-                } else if (cst instanceof Handle) {
-                    return newValue(Type.getObjectType("java/lang/invoke/MethodHandle"));
+            } else if (cst instanceof String) {
+                return newValue(Type.getObjectType("java/lang/String"));
+            } else if (cst instanceof Type) {
+                int sort = ((Type) cst).getSort();
+                if (sort == Type.OBJECT || sort == Type.ARRAY) {
+                    return newValue(Type.getObjectType("java/lang/Class"));
+                } else if (sort == Type.METHOD) {
+                    return newValue(Type
+                            .getObjectType("java/lang/invoke/MethodType"));
                 } else {
-                    throw new IllegalArgumentException("Illegal LDC constant " + cst);
+                    throw new IllegalArgumentException("Illegal LDC constant "
+                            + cst);
                 }
-            case JSR:
-                return BasicValue.RETURNADDRESS_VALUE;
-            case GETSTATIC:
-                return newValue(Type.getType(((FieldInsnNode) insn).desc));
-            case NEW:
-                return newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
-            default:
-                throw new Error("Internal error.");
+            } else if (cst instanceof Handle) {
+                return newValue(Type
+                        .getObjectType("java/lang/invoke/MethodHandle"));
+            } else {
+                throw new IllegalArgumentException("Illegal LDC constant "
+                        + cst);
+            }
+        case JSR:
+            return BasicValue.RETURNADDRESS_VALUE;
+        case GETSTATIC:
+            return newValue(Type.getType(((FieldInsnNode) insn).desc));
+        case NEW:
+            return newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
+        default:
+            throw new Error("Internal error.");
         }
     }
 
     @Override
-    public BasicValue copyOperation(final AbstractInsnNode insn, final BasicValue value)
-            throws AnalyzerException
-    {
+    public BasicValue copyOperation(final AbstractInsnNode insn,
+            final BasicValue value) throws AnalyzerException {
         return value;
     }
 
     @Override
-    public BasicValue unaryOperation(final AbstractInsnNode insn, final BasicValue value)
-            throws AnalyzerException
-    {
+    public BasicValue unaryOperation(final AbstractInsnNode insn,
+            final BasicValue value) throws AnalyzerException {
         switch (insn.getOpcode()) {
-            case INEG:
-            case IINC:
-            case L2I:
-            case F2I:
-            case D2I:
-            case I2B:
-            case I2C:
-            case I2S:
-                return BasicValue.INT_VALUE;
-            case FNEG:
-            case I2F:
-            case L2F:
-            case D2F:
-                return BasicValue.FLOAT_VALUE;
-            case LNEG:
-            case I2L:
-            case F2L:
-            case D2L:
-                return BasicValue.LONG_VALUE;
-            case DNEG:
-            case I2D:
-            case L2D:
-            case F2D:
-                return BasicValue.DOUBLE_VALUE;
-            case IFEQ:
-            case IFNE:
-            case IFLT:
-            case IFGE:
-            case IFGT:
-            case IFLE:
-            case TABLESWITCH:
-            case LOOKUPSWITCH:
-            case IRETURN:
-            case LRETURN:
-            case FRETURN:
-            case DRETURN:
-            case ARETURN:
-            case PUTSTATIC:
-                return null;
-            case GETFIELD:
-                return newValue(Type.getType(((FieldInsnNode) insn).desc));
-            case NEWARRAY:
-                switch (((IntInsnNode) insn).operand) {
-                    case T_BOOLEAN:
-                        return newValue(Type.getType("[Z"));
-                    case T_CHAR:
-                        return newValue(Type.getType("[C"));
-                    case T_BYTE:
-                        return newValue(Type.getType("[B"));
-                    case T_SHORT:
-                        return newValue(Type.getType("[S"));
-                    case T_INT:
-                        return newValue(Type.getType("[I"));
-                    case T_FLOAT:
-                        return newValue(Type.getType("[F"));
-                    case T_DOUBLE:
-                        return newValue(Type.getType("[D"));
-                    case T_LONG:
-                        return newValue(Type.getType("[J"));
-                    default:
-                        throw new AnalyzerException(insn, "Invalid array type");
-                }
-            case ANEWARRAY:
-                String desc = ((TypeInsnNode) insn).desc;
-                return newValue(Type.getType("[" + Type.getObjectType(desc)));
-            case ARRAYLENGTH:
-                return BasicValue.INT_VALUE;
-            case ATHROW:
-                return null;
-            case CHECKCAST:
-                desc = ((TypeInsnNode) insn).desc;
-                return newValue(Type.getObjectType(desc));
-            case INSTANCEOF:
-                return BasicValue.INT_VALUE;
-            case MONITORENTER:
-            case MONITOREXIT:
-            case IFNULL:
-            case IFNONNULL:
-                return null;
+        case INEG:
+        case IINC:
+        case L2I:
+        case F2I:
+        case D2I:
+        case I2B:
+        case I2C:
+        case I2S:
+            return BasicValue.INT_VALUE;
+        case FNEG:
+        case I2F:
+        case L2F:
+        case D2F:
+            return BasicValue.FLOAT_VALUE;
+        case LNEG:
+        case I2L:
+        case F2L:
+        case D2L:
+            return BasicValue.LONG_VALUE;
+        case DNEG:
+        case I2D:
+        case L2D:
+        case F2D:
+            return BasicValue.DOUBLE_VALUE;
+        case IFEQ:
+        case IFNE:
+        case IFLT:
+        case IFGE:
+        case IFGT:
+        case IFLE:
+        case TABLESWITCH:
+        case LOOKUPSWITCH:
+        case IRETURN:
+        case LRETURN:
+        case FRETURN:
+        case DRETURN:
+        case ARETURN:
+        case PUTSTATIC:
+            return null;
+        case GETFIELD:
+            return newValue(Type.getType(((FieldInsnNode) insn).desc));
+        case NEWARRAY:
+            switch (((IntInsnNode) insn).operand) {
+            case T_BOOLEAN:
+                return newValue(Type.getType("[Z"));
+            case T_CHAR:
+                return newValue(Type.getType("[C"));
+            case T_BYTE:
+                return newValue(Type.getType("[B"));
+            case T_SHORT:
+                return newValue(Type.getType("[S"));
+            case T_INT:
+                return newValue(Type.getType("[I"));
+            case T_FLOAT:
+                return newValue(Type.getType("[F"));
+            case T_DOUBLE:
+                return newValue(Type.getType("[D"));
+            case T_LONG:
+                return newValue(Type.getType("[J"));
             default:
-                throw new Error("Internal error.");
+                throw new AnalyzerException(insn, "Invalid array type");
+            }
+        case ANEWARRAY:
+            String desc = ((TypeInsnNode) insn).desc;
+            return newValue(Type.getType("[" + Type.getObjectType(desc)));
+        case ARRAYLENGTH:
+            return BasicValue.INT_VALUE;
+        case ATHROW:
+            return null;
+        case CHECKCAST:
+            desc = ((TypeInsnNode) insn).desc;
+            return newValue(Type.getObjectType(desc));
+        case INSTANCEOF:
+            return BasicValue.INT_VALUE;
+        case MONITORENTER:
+        case MONITOREXIT:
+        case IFNULL:
+        case IFNONNULL:
+            return null;
+        default:
+            throw new Error("Internal error.");
         }
     }
 
     @Override
-    public BasicValue binaryOperation(
-        final AbstractInsnNode insn,
-        final BasicValue value1,
-        final BasicValue value2) throws AnalyzerException
-    {
+    public BasicValue binaryOperation(final AbstractInsnNode insn,
+            final BasicValue value1, final BasicValue value2)
+            throws AnalyzerException {
         switch (insn.getOpcode()) {
-            case IALOAD:
-            case BALOAD:
-            case CALOAD:
-            case SALOAD:
-            case IADD:
-            case ISUB:
-            case IMUL:
-            case IDIV:
-            case IREM:
-            case ISHL:
-            case ISHR:
-            case IUSHR:
-            case IAND:
-            case IOR:
-            case IXOR:
-                return BasicValue.INT_VALUE;
-            case FALOAD:
-            case FADD:
-            case FSUB:
-            case FMUL:
-            case FDIV:
-            case FREM:
-                return BasicValue.FLOAT_VALUE;
-            case LALOAD:
-            case LADD:
-            case LSUB:
-            case LMUL:
-            case LDIV:
-            case LREM:
-            case LSHL:
-            case LSHR:
-            case LUSHR:
-            case LAND:
-            case LOR:
-            case LXOR:
-                return BasicValue.LONG_VALUE;
-            case DALOAD:
-            case DADD:
-            case DSUB:
-            case DMUL:
-            case DDIV:
-            case DREM:
-                return BasicValue.DOUBLE_VALUE;
-            case AALOAD:
-                return BasicValue.REFERENCE_VALUE;
-            case LCMP:
-            case FCMPL:
-            case FCMPG:
-            case DCMPL:
-            case DCMPG:
-                return BasicValue.INT_VALUE;
-            case IF_ICMPEQ:
-            case IF_ICMPNE:
-            case IF_ICMPLT:
-            case IF_ICMPGE:
-            case IF_ICMPGT:
-            case IF_ICMPLE:
-            case IF_ACMPEQ:
-            case IF_ACMPNE:
-            case PUTFIELD:
-                return null;
-            default:
-                throw new Error("Internal error.");
+        case IALOAD:
+        case BALOAD:
+        case CALOAD:
+        case SALOAD:
+        case IADD:
+        case ISUB:
+        case IMUL:
+        case IDIV:
+        case IREM:
+        case ISHL:
+        case ISHR:
+        case IUSHR:
+        case IAND:
+        case IOR:
+        case IXOR:
+            return BasicValue.INT_VALUE;
+        case FALOAD:
+        case FADD:
+        case FSUB:
+        case FMUL:
+        case FDIV:
+        case FREM:
+            return BasicValue.FLOAT_VALUE;
+        case LALOAD:
+        case LADD:
+        case LSUB:
+        case LMUL:
+        case LDIV:
+        case LREM:
+        case LSHL:
+        case LSHR:
+        case LUSHR:
+        case LAND:
+        case LOR:
+        case LXOR:
+            return BasicValue.LONG_VALUE;
+        case DALOAD:
+        case DADD:
+        case DSUB:
+        case DMUL:
+        case DDIV:
+        case DREM:
+            return BasicValue.DOUBLE_VALUE;
+        case AALOAD:
+            return BasicValue.REFERENCE_VALUE;
+        case LCMP:
+        case FCMPL:
+        case FCMPG:
+        case DCMPL:
+        case DCMPG:
+            return BasicValue.INT_VALUE;
+        case IF_ICMPEQ:
+        case IF_ICMPNE:
+        case IF_ICMPLT:
+        case IF_ICMPGE:
+        case IF_ICMPGT:
+        case IF_ICMPLE:
+        case IF_ACMPEQ:
+        case IF_ACMPNE:
+        case PUTFIELD:
+            return null;
+        default:
+            throw new Error("Internal error.");
         }
     }
 
     @Override
-    public BasicValue ternaryOperation(
-        final AbstractInsnNode insn,
-        final BasicValue value1,
-        final BasicValue value2,
-        final BasicValue value3) throws AnalyzerException
-    {
+    public BasicValue ternaryOperation(final AbstractInsnNode insn,
+            final BasicValue value1, final BasicValue value2,
+            final BasicValue value3) throws AnalyzerException {
         return null;
     }
 
     @Override
-    public BasicValue naryOperation(final AbstractInsnNode insn, final List<? extends BasicValue> values)
-            throws AnalyzerException
-    {
+    public BasicValue naryOperation(final AbstractInsnNode insn,
+            final List<? extends BasicValue> values) throws AnalyzerException {
         int opcode = insn.getOpcode();
         if (opcode == MULTIANEWARRAY) {
             return newValue(Type.getType(((MultiANewArrayInsnNode) insn).desc));
-        } else if (opcode == INVOKEDYNAMIC){
-            return newValue(Type.getReturnType(((InvokeDynamicInsnNode) insn).desc));
+        } else if (opcode == INVOKEDYNAMIC) {
+            return newValue(Type
+                    .getReturnType(((InvokeDynamicInsnNode) insn).desc));
         } else {
             return newValue(Type.getReturnType(((MethodInsnNode) insn).desc));
         }
     }
 
     @Override
-    public void returnOperation(
-        final AbstractInsnNode insn,
-        final BasicValue value,
-        final BasicValue expected) throws AnalyzerException
-    {
+    public void returnOperation(final AbstractInsnNode insn,
+            final BasicValue value, final BasicValue expected)
+            throws AnalyzerException {
     }
 
     @Override
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicValue.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicValue.java
index b92fd3d..ef51922 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicValue.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicValue.java
@@ -77,11 +77,14 @@
 
     public static final BasicValue LONG_VALUE = new BasicValue(Type.LONG_TYPE);
 
-    public static final BasicValue DOUBLE_VALUE = new BasicValue(Type.DOUBLE_TYPE);
+    public static final BasicValue DOUBLE_VALUE = new BasicValue(
+            Type.DOUBLE_TYPE);
 
-    public static final BasicValue REFERENCE_VALUE = new BasicValue(Type.getObjectType("java/lang/Object"));
+    public static final BasicValue REFERENCE_VALUE = new BasicValue(
+            Type.getObjectType("java/lang/Object"));
 
-    public static final BasicValue RETURNADDRESS_VALUE = new BasicValue(Type.VOID_TYPE);
+    public static final BasicValue RETURNADDRESS_VALUE = new BasicValue(
+            Type.VOID_TYPE);
 
     private final Type type;
 
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicVerifier.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicVerifier.java
index 8b51b4a..2ccf67d 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicVerifier.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicVerifier.java
@@ -76,7 +76,7 @@
 public class BasicVerifier extends BasicInterpreter {
 
     public BasicVerifier() {
-        super(ASM4);
+        super(ASM5);
     }
 
     protected BasicVerifier(final int api) {
@@ -84,47 +84,41 @@
     }
 
     @Override
-    public BasicValue copyOperation(final AbstractInsnNode insn, final BasicValue value)
-            throws AnalyzerException
-    {
+    public BasicValue copyOperation(final AbstractInsnNode insn,
+            final BasicValue value) throws AnalyzerException {
         Value expected;
         switch (insn.getOpcode()) {
-            case ILOAD:
-            case ISTORE:
-                expected = BasicValue.INT_VALUE;
-                break;
-            case FLOAD:
-            case FSTORE:
-                expected = BasicValue.FLOAT_VALUE;
-                break;
-            case LLOAD:
-            case LSTORE:
-                expected = BasicValue.LONG_VALUE;
-                break;
-            case DLOAD:
-            case DSTORE:
-                expected = BasicValue.DOUBLE_VALUE;
-                break;
-            case ALOAD:
-                if (!value.isReference()) {
-                    throw new AnalyzerException(insn,
-                            null,
-                            "an object reference",
-                            value);
-                }
-                return value;
-            case ASTORE:
-                if (!value.isReference()
-                        && !BasicValue.RETURNADDRESS_VALUE.equals(value))
-                {
-                    throw new AnalyzerException(insn,
-                            null,
-                            "an object reference or a return address",
-                            value);
-                }
-                return value;
-            default:
-                return value;
+        case ILOAD:
+        case ISTORE:
+            expected = BasicValue.INT_VALUE;
+            break;
+        case FLOAD:
+        case FSTORE:
+            expected = BasicValue.FLOAT_VALUE;
+            break;
+        case LLOAD:
+        case LSTORE:
+            expected = BasicValue.LONG_VALUE;
+            break;
+        case DLOAD:
+        case DSTORE:
+            expected = BasicValue.DOUBLE_VALUE;
+            break;
+        case ALOAD:
+            if (!value.isReference()) {
+                throw new AnalyzerException(insn, null, "an object reference",
+                        value);
+            }
+            return value;
+        case ASTORE:
+            if (!value.isReference()
+                    && !BasicValue.RETURNADDRESS_VALUE.equals(value)) {
+                throw new AnalyzerException(insn, null,
+                        "an object reference or a return address", value);
+            }
+            return value;
+        default:
+            return value;
         }
         if (!expected.equals(value)) {
             throw new AnalyzerException(insn, null, expected, value);
@@ -133,91 +127,85 @@
     }
 
     @Override
-    public BasicValue unaryOperation(final AbstractInsnNode insn, final BasicValue value)
-            throws AnalyzerException
-    {
+    public BasicValue unaryOperation(final AbstractInsnNode insn,
+            final BasicValue value) throws AnalyzerException {
         BasicValue expected;
         switch (insn.getOpcode()) {
-            case INEG:
-            case IINC:
-            case I2F:
-            case I2L:
-            case I2D:
-            case I2B:
-            case I2C:
-            case I2S:
-            case IFEQ:
-            case IFNE:
-            case IFLT:
-            case IFGE:
-            case IFGT:
-            case IFLE:
-            case TABLESWITCH:
-            case LOOKUPSWITCH:
-            case IRETURN:
-            case NEWARRAY:
-            case ANEWARRAY:
-                expected = BasicValue.INT_VALUE;
-                break;
-            case FNEG:
-            case F2I:
-            case F2L:
-            case F2D:
-            case FRETURN:
-                expected = BasicValue.FLOAT_VALUE;
-                break;
-            case LNEG:
-            case L2I:
-            case L2F:
-            case L2D:
-            case LRETURN:
-                expected = BasicValue.LONG_VALUE;
-                break;
-            case DNEG:
-            case D2I:
-            case D2F:
-            case D2L:
-            case DRETURN:
-                expected = BasicValue.DOUBLE_VALUE;
-                break;
-            case GETFIELD:
-                expected = newValue(Type.getObjectType(((FieldInsnNode) insn).owner));
-                break;
-            case CHECKCAST:
-                if (!value.isReference()) {
-                    throw new AnalyzerException(insn,
-                            null,
-                            "an object reference",
-                            value);
-                }
-                return super.unaryOperation(insn, value);
-            case ARRAYLENGTH:
-                if (!isArrayValue(value)) {
-                    throw new AnalyzerException(insn,
-                            null,
-                            "an array reference",
-                            value);
-                }
-                return super.unaryOperation(insn, value);
-            case ARETURN:
-            case ATHROW:
-            case INSTANCEOF:
-            case MONITORENTER:
-            case MONITOREXIT:
-            case IFNULL:
-            case IFNONNULL:
-                if (!value.isReference()) {
-                    throw new AnalyzerException(insn,
-                            null,
-                            "an object reference",
-                            value);
-                }
-                return super.unaryOperation(insn, value);
-            case PUTSTATIC:
-                expected = newValue(Type.getType(((FieldInsnNode) insn).desc));
-                break;
-            default:
-                throw new Error("Internal error.");
+        case INEG:
+        case IINC:
+        case I2F:
+        case I2L:
+        case I2D:
+        case I2B:
+        case I2C:
+        case I2S:
+        case IFEQ:
+        case IFNE:
+        case IFLT:
+        case IFGE:
+        case IFGT:
+        case IFLE:
+        case TABLESWITCH:
+        case LOOKUPSWITCH:
+        case IRETURN:
+        case NEWARRAY:
+        case ANEWARRAY:
+            expected = BasicValue.INT_VALUE;
+            break;
+        case FNEG:
+        case F2I:
+        case F2L:
+        case F2D:
+        case FRETURN:
+            expected = BasicValue.FLOAT_VALUE;
+            break;
+        case LNEG:
+        case L2I:
+        case L2F:
+        case L2D:
+        case LRETURN:
+            expected = BasicValue.LONG_VALUE;
+            break;
+        case DNEG:
+        case D2I:
+        case D2F:
+        case D2L:
+        case DRETURN:
+            expected = BasicValue.DOUBLE_VALUE;
+            break;
+        case GETFIELD:
+            expected = newValue(Type
+                    .getObjectType(((FieldInsnNode) insn).owner));
+            break;
+        case CHECKCAST:
+            if (!value.isReference()) {
+                throw new AnalyzerException(insn, null, "an object reference",
+                        value);
+            }
+            return super.unaryOperation(insn, value);
+        case ARRAYLENGTH:
+            if (!isArrayValue(value)) {
+                throw new AnalyzerException(insn, null, "an array reference",
+                        value);
+            }
+            return super.unaryOperation(insn, value);
+        case ARETURN:
+        case ATHROW:
+        case INSTANCEOF:
+        case MONITORENTER:
+        case MONITOREXIT:
+        case IFNULL:
+        case IFNONNULL:
+            if (!value.isReference()) {
+                throw new AnalyzerException(insn, null, "an object reference",
+                        value);
+            }
+            return super.unaryOperation(insn, value);
+        case PUTSTATIC:
+            expected = newValue(Type.getType(((FieldInsnNode) insn).desc));
+            break;
+        default:
+            throw new Error("Internal error.");
         }
         if (!isSubTypeOf(value, expected)) {
             throw new AnalyzerException(insn, null, expected, value);
@@ -226,125 +214,125 @@
     }
 
     @Override
-    public BasicValue binaryOperation(
-        final AbstractInsnNode insn,
-        final BasicValue value1,
-        final BasicValue value2) throws AnalyzerException
-    {
+    public BasicValue binaryOperation(final AbstractInsnNode insn,
+            final BasicValue value1, final BasicValue value2)
+            throws AnalyzerException {
         BasicValue expected1;
         BasicValue expected2;
         switch (insn.getOpcode()) {
-            case IALOAD:
-                expected1 = newValue(Type.getType("[I"));
-                expected2 = BasicValue.INT_VALUE;
-                break;
-            case BALOAD:
-                if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
-                    expected1 = newValue(Type.getType("[Z"));
-                } else {
-                    expected1 = newValue(Type.getType("[B"));
-                }
-                expected2 = BasicValue.INT_VALUE;
-                break;
-            case CALOAD:
-                expected1 = newValue(Type.getType("[C"));
-                expected2 = BasicValue.INT_VALUE;
-                break;
-            case SALOAD:
-                expected1 = newValue(Type.getType("[S"));
-                expected2 = BasicValue.INT_VALUE;
-                break;
-            case LALOAD:
-                expected1 = newValue(Type.getType("[J"));
-                expected2 = BasicValue.INT_VALUE;
-                break;
-            case FALOAD:
-                expected1 = newValue(Type.getType("[F"));
-                expected2 = BasicValue.INT_VALUE;
-                break;
-            case DALOAD:
-                expected1 = newValue(Type.getType("[D"));
-                expected2 = BasicValue.INT_VALUE;
-                break;
-            case AALOAD:
-                expected1 = newValue(Type.getType("[Ljava/lang/Object;"));
-                expected2 = BasicValue.INT_VALUE;
-                break;
-            case IADD:
-            case ISUB:
-            case IMUL:
-            case IDIV:
-            case IREM:
-            case ISHL:
-            case ISHR:
-            case IUSHR:
-            case IAND:
-            case IOR:
-            case IXOR:
-            case IF_ICMPEQ:
-            case IF_ICMPNE:
-            case IF_ICMPLT:
-            case IF_ICMPGE:
-            case IF_ICMPGT:
-            case IF_ICMPLE:
-                expected1 = BasicValue.INT_VALUE;
-                expected2 = BasicValue.INT_VALUE;
-                break;
-            case FADD:
-            case FSUB:
-            case FMUL:
-            case FDIV:
-            case FREM:
-            case FCMPL:
-            case FCMPG:
-                expected1 = BasicValue.FLOAT_VALUE;
-                expected2 = BasicValue.FLOAT_VALUE;
-                break;
-            case LADD:
-            case LSUB:
-            case LMUL:
-            case LDIV:
-            case LREM:
-            case LAND:
-            case LOR:
-            case LXOR:
-            case LCMP:
-                expected1 = BasicValue.LONG_VALUE;
-                expected2 = BasicValue.LONG_VALUE;
-                break;
-            case LSHL:
-            case LSHR:
-            case LUSHR:
-                expected1 = BasicValue.LONG_VALUE;
-                expected2 = BasicValue.INT_VALUE;
-                break;
-            case DADD:
-            case DSUB:
-            case DMUL:
-            case DDIV:
-            case DREM:
-            case DCMPL:
-            case DCMPG:
-                expected1 = BasicValue.DOUBLE_VALUE;
-                expected2 = BasicValue.DOUBLE_VALUE;
-                break;
-            case IF_ACMPEQ:
-            case IF_ACMPNE:
-                expected1 = BasicValue.REFERENCE_VALUE;
-                expected2 = BasicValue.REFERENCE_VALUE;
-                break;
-            case PUTFIELD:
-                FieldInsnNode fin = (FieldInsnNode) insn;
-                expected1 = newValue(Type.getObjectType(fin.owner));
-                expected2 = newValue(Type.getType(fin.desc));
-                break;
-            default:
-                throw new Error("Internal error.");
+        case IALOAD:
+            expected1 = newValue(Type.getType("[I"));
+            expected2 = BasicValue.INT_VALUE;
+            break;
+        case BALOAD:
+            if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
+                expected1 = newValue(Type.getType("[Z"));
+            } else {
+                expected1 = newValue(Type.getType("[B"));
+            }
+            expected2 = BasicValue.INT_VALUE;
+            break;
+        case CALOAD:
+            expected1 = newValue(Type.getType("[C"));
+            expected2 = BasicValue.INT_VALUE;
+            break;
+        case SALOAD:
+            expected1 = newValue(Type.getType("[S"));
+            expected2 = BasicValue.INT_VALUE;
+            break;
+        case LALOAD:
+            expected1 = newValue(Type.getType("[J"));
+            expected2 = BasicValue.INT_VALUE;
+            break;
+        case FALOAD:
+            expected1 = newValue(Type.getType("[F"));
+            expected2 = BasicValue.INT_VALUE;
+            break;
+        case DALOAD:
+            expected1 = newValue(Type.getType("[D"));
+            expected2 = BasicValue.INT_VALUE;
+            break;
+        case AALOAD:
+            expected1 = newValue(Type.getType("[Ljava/lang/Object;"));
+            expected2 = BasicValue.INT_VALUE;
+            break;
+        case IADD:
+        case ISUB:
+        case IMUL:
+        case IDIV:
+        case IREM:
+        case ISHL:
+        case ISHR:
+        case IUSHR:
+        case IAND:
+        case IOR:
+        case IXOR:
+        case IF_ICMPEQ:
+        case IF_ICMPNE:
+        case IF_ICMPLT:
+        case IF_ICMPGE:
+        case IF_ICMPGT:
+        case IF_ICMPLE:
+            expected1 = BasicValue.INT_VALUE;
+            expected2 = BasicValue.INT_VALUE;
+            break;
+        case FADD:
+        case FSUB:
+        case FMUL:
+        case FDIV:
+        case FREM:
+        case FCMPL:
+        case FCMPG:
+            expected1 = BasicValue.FLOAT_VALUE;
+            expected2 = BasicValue.FLOAT_VALUE;
+            break;
+        case LADD:
+        case LSUB:
+        case LMUL:
+        case LDIV:
+        case LREM:
+        case LAND:
+        case LOR:
+        case LXOR:
+        case LCMP:
+            expected1 = BasicValue.LONG_VALUE;
+            expected2 = BasicValue.LONG_VALUE;
+            break;
+        case LSHL:
+        case LSHR:
+        case LUSHR:
+            expected1 = BasicValue.LONG_VALUE;
+            expected2 = BasicValue.INT_VALUE;
+            break;
+        case DADD:
+        case DSUB:
+        case DMUL:
+        case DDIV:
+        case DREM:
+        case DCMPL:
+        case DCMPG:
+            expected1 = BasicValue.DOUBLE_VALUE;
+            expected2 = BasicValue.DOUBLE_VALUE;
+            break;
+        case IF_ACMPEQ:
+        case IF_ACMPNE:
+            expected1 = BasicValue.REFERENCE_VALUE;
+            expected2 = BasicValue.REFERENCE_VALUE;
+            break;
+        case PUTFIELD:
+            FieldInsnNode fin = (FieldInsnNode) insn;
+            expected1 = newValue(Type.getObjectType(fin.owner));
+            expected2 = newValue(Type.getType(fin.desc));
+            break;
+        default:
+            throw new Error("Internal error.");
         }
         if (!isSubTypeOf(value1, expected1)) {
-            throw new AnalyzerException(insn, "First argument", expected1, value1);
+            throw new AnalyzerException(insn, "First argument", expected1,
+                    value1);
         } else if (!isSubTypeOf(value2, expected2)) {
-            throw new AnalyzerException(insn, "Second argument", expected2, value2);
+            throw new AnalyzerException(insn, "Second argument", expected2,
+                    value2);
         }
         if (insn.getOpcode() == AALOAD) {
             return getElementValue(value1);
@@ -354,79 +342,73 @@
     }
 
     @Override
-    public BasicValue ternaryOperation(
-        final AbstractInsnNode insn,
-        final BasicValue value1,
-        final BasicValue value2,
-        final BasicValue value3) throws AnalyzerException
-    {
+    public BasicValue ternaryOperation(final AbstractInsnNode insn,
+            final BasicValue value1, final BasicValue value2,
+            final BasicValue value3) throws AnalyzerException {
         BasicValue expected1;
         BasicValue expected3;
         switch (insn.getOpcode()) {
-            case IASTORE:
-                expected1 = newValue(Type.getType("[I"));
-                expected3 = BasicValue.INT_VALUE;
-                break;
-            case BASTORE:
-                if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
-                    expected1 = newValue(Type.getType("[Z"));
-                } else {
-                    expected1 = newValue(Type.getType("[B"));
-                }
-                expected3 = BasicValue.INT_VALUE;
-                break;
-            case CASTORE:
-                expected1 = newValue(Type.getType("[C"));
-                expected3 = BasicValue.INT_VALUE;
-                break;
-            case SASTORE:
-                expected1 = newValue(Type.getType("[S"));
-                expected3 = BasicValue.INT_VALUE;
-                break;
-            case LASTORE:
-                expected1 = newValue(Type.getType("[J"));
-                expected3 = BasicValue.LONG_VALUE;
-                break;
-            case FASTORE:
-                expected1 = newValue(Type.getType("[F"));
-                expected3 = BasicValue.FLOAT_VALUE;
-                break;
-            case DASTORE:
-                expected1 = newValue(Type.getType("[D"));
-                expected3 = BasicValue.DOUBLE_VALUE;
-                break;
-            case AASTORE:
-                expected1 = value1;
-                expected3 = BasicValue.REFERENCE_VALUE;
-                break;
-            default:
-                throw new Error("Internal error.");
+        case IASTORE:
+            expected1 = newValue(Type.getType("[I"));
+            expected3 = BasicValue.INT_VALUE;
+            break;
+        case BASTORE:
+            if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
+                expected1 = newValue(Type.getType("[Z"));
+            } else {
+                expected1 = newValue(Type.getType("[B"));
+            }
+            expected3 = BasicValue.INT_VALUE;
+            break;
+        case CASTORE:
+            expected1 = newValue(Type.getType("[C"));
+            expected3 = BasicValue.INT_VALUE;
+            break;
+        case SASTORE:
+            expected1 = newValue(Type.getType("[S"));
+            expected3 = BasicValue.INT_VALUE;
+            break;
+        case LASTORE:
+            expected1 = newValue(Type.getType("[J"));
+            expected3 = BasicValue.LONG_VALUE;
+            break;
+        case FASTORE:
+            expected1 = newValue(Type.getType("[F"));
+            expected3 = BasicValue.FLOAT_VALUE;
+            break;
+        case DASTORE:
+            expected1 = newValue(Type.getType("[D"));
+            expected3 = BasicValue.DOUBLE_VALUE;
+            break;
+        case AASTORE:
+            expected1 = value1;
+            expected3 = BasicValue.REFERENCE_VALUE;
+            break;
+        default:
+            throw new Error("Internal error.");
         }
         if (!isSubTypeOf(value1, expected1)) {
-            throw new AnalyzerException(insn, "First argument", "a " + expected1
-                    + " array reference", value1);
+            throw new AnalyzerException(insn, "First argument", "a "
+                    + expected1 + " array reference", value1);
         } else if (!BasicValue.INT_VALUE.equals(value2)) {
             throw new AnalyzerException(insn, "Second argument",
-                    BasicValue.INT_VALUE,
-                    value2);
+                    BasicValue.INT_VALUE, value2);
         } else if (!isSubTypeOf(value3, expected3)) {
-            throw new AnalyzerException(insn, "Third argument", expected3, value3);
+            throw new AnalyzerException(insn, "Third argument", expected3,
+                    value3);
         }
         return null;
     }
 
     @Override
-    public BasicValue naryOperation(final AbstractInsnNode insn, final List<? extends BasicValue> values)
-            throws AnalyzerException
-    {
+    public BasicValue naryOperation(final AbstractInsnNode insn,
+            final List<? extends BasicValue> values) throws AnalyzerException {
         int opcode = insn.getOpcode();
         if (opcode == MULTIANEWARRAY) {
             for (int i = 0; i < values.size(); ++i) {
                 if (!BasicValue.INT_VALUE.equals(values.get(i))) {
-                    throw new AnalyzerException(insn,
-                            null,
-                            BasicValue.INT_VALUE,
-                            values.get(i));
+                    throw new AnalyzerException(insn, null,
+                            BasicValue.INT_VALUE, values.get(i));
                 }
             }
         } else {
@@ -436,22 +418,18 @@
                 Type owner = Type.getObjectType(((MethodInsnNode) insn).owner);
                 if (!isSubTypeOf(values.get(i++), newValue(owner))) {
                     throw new AnalyzerException(insn, "Method owner",
-                            newValue(owner),
-                            values.get(0));
+                            newValue(owner), values.get(0));
                 }
             }
-            String desc = (opcode == INVOKEDYNAMIC)?
-                    ((InvokeDynamicInsnNode) insn).desc:
-                        ((MethodInsnNode) insn).desc;
+            String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc
+                    : ((MethodInsnNode) insn).desc;
             Type[] args = Type.getArgumentTypes(desc);
             while (i < values.size()) {
                 BasicValue expected = newValue(args[j++]);
                 BasicValue encountered = values.get(i++);
                 if (!isSubTypeOf(encountered, expected)) {
-                    throw new AnalyzerException(insn,
-                            "Argument " + j,
-                            expected,
-                            encountered);
+                    throw new AnalyzerException(insn, "Argument " + j,
+                            expected, encountered);
                 }
             }
         }
@@ -459,16 +437,12 @@
     }
 
     @Override
-    public void returnOperation(
-        final AbstractInsnNode insn,
-        final BasicValue value,
-        final BasicValue expected) throws AnalyzerException
-    {
+    public void returnOperation(final AbstractInsnNode insn,
+            final BasicValue value, final BasicValue expected)
+            throws AnalyzerException {
         if (!isSubTypeOf(value, expected)) {
-            throw new AnalyzerException(insn,
-                    "Incompatible return type",
-                    expected,
-                    value);
+            throw new AnalyzerException(insn, "Incompatible return type",
+                    expected, value);
         }
     }
 
@@ -477,12 +451,12 @@
     }
 
     protected BasicValue getElementValue(final BasicValue objectArrayValue)
-            throws AnalyzerException
-    {
+            throws AnalyzerException {
         return BasicValue.REFERENCE_VALUE;
     }
 
-    protected boolean isSubTypeOf(final BasicValue value, final BasicValue expected) {
+    protected boolean isSubTypeOf(final BasicValue value,
+            final BasicValue expected) {
         return value.equals(expected);
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Frame.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Frame.java
index b25d4d8..2d9434f 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Frame.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Frame.java
@@ -73,10 +73,11 @@
 /**
  * A symbolic execution stack frame. A stack frame contains a set of local
  * variable slots, and an operand stack. Warning: long and double values are
- * represented by <i>two</i> slots in local variables, and by <i>one</i> slot
- * in the operand stack.
+ * represented by <i>two</i> slots in local variables, and by <i>one</i> slot in
+ * the operand stack.
  *
- * @param <V> type of the Value used for the analysis.
+ * @param <V>
+ *            type of the Value used for the analysis.
  *
  * @author Eric Bruneton
  */
@@ -106,8 +107,10 @@
     /**
      * Constructs a new frame with the given size.
      *
-     * @param nLocals the maximum number of local variables of the frame.
-     * @param nStack the maximum stack size of the frame.
+     * @param nLocals
+     *            the maximum number of local variables of the frame.
+     * @param nStack
+     *            the maximum stack size of the frame.
      */
     public Frame(final int nLocals, final int nStack) {
         this.values = (V[]) new Value[nLocals + nStack];
@@ -117,7 +120,8 @@
     /**
      * Constructs a new frame that is identical to the given frame.
      *
-     * @param src a frame.
+     * @param src
+     *            a frame.
      */
     public Frame(final Frame<? extends V> src) {
         this(src.locals, src.values.length - src.locals);
@@ -127,7 +131,8 @@
     /**
      * Copies the state of the given frame into this frame.
      *
-     * @param src a frame.
+     * @param src
+     *            a frame.
      * @return this frame.
      */
     public Frame<V> init(final Frame<? extends V> src) {
@@ -140,8 +145,9 @@
     /**
      * Sets the expected return type of the analyzed method.
      *
-     * @param v the expected return type of the analyzed method, or
-     *        <tt>null</tt> if the method returns void.
+     * @param v
+     *            the expected return type of the analyzed method, or
+     *            <tt>null</tt> if the method returns void.
      */
     public void setReturn(final V v) {
         returnValue = v;
@@ -159,13 +165,16 @@
     /**
      * Returns the value of the given local variable.
      *
-     * @param i a local variable index.
+     * @param i
+     *            a local variable index.
      * @return the value of the given local variable.
-     * @throws IndexOutOfBoundsException if the variable does not exist.
+     * @throws IndexOutOfBoundsException
+     *             if the variable does not exist.
      */
     public V getLocal(final int i) throws IndexOutOfBoundsException {
         if (i >= locals) {
-            throw new IndexOutOfBoundsException("Trying to access an inexistant local variable");
+            throw new IndexOutOfBoundsException(
+                    "Trying to access an inexistant local variable");
         }
         return values[i];
     }
@@ -173,15 +182,18 @@
     /**
      * Sets the value of the given local variable.
      *
-     * @param i a local variable index.
-     * @param value the new value of this local variable.
-     * @throws IndexOutOfBoundsException if the variable does not exist.
+     * @param i
+     *            a local variable index.
+     * @param value
+     *            the new value of this local variable.
+     * @throws IndexOutOfBoundsException
+     *             if the variable does not exist.
      */
     public void setLocal(final int i, final V value)
-            throws IndexOutOfBoundsException
-    {
+            throws IndexOutOfBoundsException {
         if (i >= locals) {
-            throw new IndexOutOfBoundsException("Trying to access an inexistant local variable "+i);
+            throw new IndexOutOfBoundsException(
+                    "Trying to access an inexistant local variable " + i);
         }
         values[i] = value;
     }
@@ -199,10 +211,11 @@
     /**
      * Returns the value of the given operand stack slot.
      *
-     * @param i the index of an operand stack slot.
+     * @param i
+     *            the index of an operand stack slot.
      * @return the value of the given operand stack slot.
-     * @throws IndexOutOfBoundsException if the operand stack slot does not
-     *         exist.
+     * @throws IndexOutOfBoundsException
+     *             if the operand stack slot does not exist.
      */
     public V getStack(final int i) throws IndexOutOfBoundsException {
         return values[i + locals];
@@ -219,11 +232,13 @@
      * Pops a value from the operand stack of this frame.
      *
      * @return the value that has been popped from the stack.
-     * @throws IndexOutOfBoundsException if the operand stack is empty.
+     * @throws IndexOutOfBoundsException
+     *             if the operand stack is empty.
      */
     public V pop() throws IndexOutOfBoundsException {
         if (top == 0) {
-            throw new IndexOutOfBoundsException("Cannot pop operand off an empty stack.");
+            throw new IndexOutOfBoundsException(
+                    "Cannot pop operand off an empty stack.");
         }
         return values[--top + locals];
     }
@@ -231,468 +246,471 @@
     /**
      * Pushes a value into the operand stack of this frame.
      *
-     * @param value the value that must be pushed into the stack.
-     * @throws IndexOutOfBoundsException if the operand stack is full.
+     * @param value
+     *            the value that must be pushed into the stack.
+     * @throws IndexOutOfBoundsException
+     *             if the operand stack is full.
      */
     public void push(final V value) throws IndexOutOfBoundsException {
         if (top + locals >= values.length) {
-            throw new IndexOutOfBoundsException("Insufficient maximum stack size.");
+            throw new IndexOutOfBoundsException(
+                    "Insufficient maximum stack size.");
         }
         values[top++ + locals] = value;
     }
 
-    public void execute(
-        final AbstractInsnNode insn,
-        final Interpreter<V> interpreter) throws AnalyzerException
-    {
+    public void execute(final AbstractInsnNode insn,
+            final Interpreter<V> interpreter) throws AnalyzerException {
         V value1, value2, value3, value4;
         List<V> values;
         int var;
 
         switch (insn.getOpcode()) {
-            case Opcodes.NOP:
-                break;
-            case Opcodes.ACONST_NULL:
-            case Opcodes.ICONST_M1:
-            case Opcodes.ICONST_0:
-            case Opcodes.ICONST_1:
-            case Opcodes.ICONST_2:
-            case Opcodes.ICONST_3:
-            case Opcodes.ICONST_4:
-            case Opcodes.ICONST_5:
-            case Opcodes.LCONST_0:
-            case Opcodes.LCONST_1:
-            case Opcodes.FCONST_0:
-            case Opcodes.FCONST_1:
-            case Opcodes.FCONST_2:
-            case Opcodes.DCONST_0:
-            case Opcodes.DCONST_1:
-            case Opcodes.BIPUSH:
-            case Opcodes.SIPUSH:
-            case Opcodes.LDC:
-                push(interpreter.newOperation(insn));
-                break;
-            case Opcodes.ILOAD:
-            case Opcodes.LLOAD:
-            case Opcodes.FLOAD:
-            case Opcodes.DLOAD:
-            case Opcodes.ALOAD:
-                push(interpreter.copyOperation(insn,
-                        getLocal(((VarInsnNode) insn).var)));
-                break;
-            case Opcodes.IALOAD:
-            case Opcodes.LALOAD:
-            case Opcodes.FALOAD:
-            case Opcodes.DALOAD:
-            case Opcodes.AALOAD:
-            case Opcodes.BALOAD:
-            case Opcodes.CALOAD:
-            case Opcodes.SALOAD:
+        case Opcodes.NOP:
+            break;
+        case Opcodes.ACONST_NULL:
+        case Opcodes.ICONST_M1:
+        case Opcodes.ICONST_0:
+        case Opcodes.ICONST_1:
+        case Opcodes.ICONST_2:
+        case Opcodes.ICONST_3:
+        case Opcodes.ICONST_4:
+        case Opcodes.ICONST_5:
+        case Opcodes.LCONST_0:
+        case Opcodes.LCONST_1:
+        case Opcodes.FCONST_0:
+        case Opcodes.FCONST_1:
+        case Opcodes.FCONST_2:
+        case Opcodes.DCONST_0:
+        case Opcodes.DCONST_1:
+        case Opcodes.BIPUSH:
+        case Opcodes.SIPUSH:
+        case Opcodes.LDC:
+            push(interpreter.newOperation(insn));
+            break;
+        case Opcodes.ILOAD:
+        case Opcodes.LLOAD:
+        case Opcodes.FLOAD:
+        case Opcodes.DLOAD:
+        case Opcodes.ALOAD:
+            push(interpreter.copyOperation(insn,
+                    getLocal(((VarInsnNode) insn).var)));
+            break;
+        case Opcodes.IALOAD:
+        case Opcodes.LALOAD:
+        case Opcodes.FALOAD:
+        case Opcodes.DALOAD:
+        case Opcodes.AALOAD:
+        case Opcodes.BALOAD:
+        case Opcodes.CALOAD:
+        case Opcodes.SALOAD:
+            value2 = pop();
+            value1 = pop();
+            push(interpreter.binaryOperation(insn, value1, value2));
+            break;
+        case Opcodes.ISTORE:
+        case Opcodes.LSTORE:
+        case Opcodes.FSTORE:
+        case Opcodes.DSTORE:
+        case Opcodes.ASTORE:
+            value1 = interpreter.copyOperation(insn, pop());
+            var = ((VarInsnNode) insn).var;
+            setLocal(var, value1);
+            if (value1.getSize() == 2) {
+                setLocal(var + 1, interpreter.newValue(null));
+            }
+            if (var > 0) {
+                Value local = getLocal(var - 1);
+                if (local != null && local.getSize() == 2) {
+                    setLocal(var - 1, interpreter.newValue(null));
+                }
+            }
+            break;
+        case Opcodes.IASTORE:
+        case Opcodes.LASTORE:
+        case Opcodes.FASTORE:
+        case Opcodes.DASTORE:
+        case Opcodes.AASTORE:
+        case Opcodes.BASTORE:
+        case Opcodes.CASTORE:
+        case Opcodes.SASTORE:
+            value3 = pop();
+            value2 = pop();
+            value1 = pop();
+            interpreter.ternaryOperation(insn, value1, value2, value3);
+            break;
+        case Opcodes.POP:
+            if (pop().getSize() == 2) {
+                throw new AnalyzerException(insn, "Illegal use of POP");
+            }
+            break;
+        case Opcodes.POP2:
+            if (pop().getSize() == 1) {
+                if (pop().getSize() != 1) {
+                    throw new AnalyzerException(insn, "Illegal use of POP2");
+                }
+            }
+            break;
+        case Opcodes.DUP:
+            value1 = pop();
+            if (value1.getSize() != 1) {
+                throw new AnalyzerException(insn, "Illegal use of DUP");
+            }
+            push(value1);
+            push(interpreter.copyOperation(insn, value1));
+            break;
+        case Opcodes.DUP_X1:
+            value1 = pop();
+            value2 = pop();
+            if (value1.getSize() != 1 || value2.getSize() != 1) {
+                throw new AnalyzerException(insn, "Illegal use of DUP_X1");
+            }
+            push(interpreter.copyOperation(insn, value1));
+            push(value2);
+            push(value1);
+            break;
+        case Opcodes.DUP_X2:
+            value1 = pop();
+            if (value1.getSize() == 1) {
                 value2 = pop();
-                value1 = pop();
-                push(interpreter.binaryOperation(insn, value1, value2));
-                break;
-            case Opcodes.ISTORE:
-            case Opcodes.LSTORE:
-            case Opcodes.FSTORE:
-            case Opcodes.DSTORE:
-            case Opcodes.ASTORE:
-                value1 = interpreter.copyOperation(insn, pop());
-                var = ((VarInsnNode) insn).var;
-                setLocal(var, value1);
-                if (value1.getSize() == 2) {
-                    setLocal(var + 1, interpreter.newValue(null));
-                }
-                if (var > 0) {
-                    Value local = getLocal(var - 1);
-                    if (local != null && local.getSize() == 2) {
-                        setLocal(var - 1, interpreter.newValue(null));
-                    }
-                }
-                break;
-            case Opcodes.IASTORE:
-            case Opcodes.LASTORE:
-            case Opcodes.FASTORE:
-            case Opcodes.DASTORE:
-            case Opcodes.AASTORE:
-            case Opcodes.BASTORE:
-            case Opcodes.CASTORE:
-            case Opcodes.SASTORE:
-                value3 = pop();
-                value2 = pop();
-                value1 = pop();
-                interpreter.ternaryOperation(insn, value1, value2, value3);
-                break;
-            case Opcodes.POP:
-                if (pop().getSize() == 2) {
-                    throw new AnalyzerException(insn, "Illegal use of POP");
-                }
-                break;
-            case Opcodes.POP2:
-                if (pop().getSize() == 1) {
-                    if (pop().getSize() != 1) {
-                        throw new AnalyzerException(insn, "Illegal use of POP2");
-                    }
-                }
-                break;
-            case Opcodes.DUP:
-                value1 = pop();
-                if (value1.getSize() != 1) {
-                    throw new AnalyzerException(insn, "Illegal use of DUP");
-                }
-                push(value1);
-                push(interpreter.copyOperation(insn, value1));
-                break;
-            case Opcodes.DUP_X1:
-                value1 = pop();
-                value2 = pop();
-                if (value1.getSize() != 1 || value2.getSize() != 1) {
-                    throw new AnalyzerException(insn, "Illegal use of DUP_X1");
-                }
-                push(interpreter.copyOperation(insn, value1));
-                push(value2);
-                push(value1);
-                break;
-            case Opcodes.DUP_X2:
-                value1 = pop();
-                if (value1.getSize() == 1) {
-                    value2 = pop();
-                    if (value2.getSize() == 1) {
-                        value3 = pop();
-                        if (value3.getSize() == 1) {
-                            push(interpreter.copyOperation(insn, value1));
-                            push(value3);
-                            push(value2);
-                            push(value1);
-                            break;
-                        }
-                    } else {
+                if (value2.getSize() == 1) {
+                    value3 = pop();
+                    if (value3.getSize() == 1) {
                         push(interpreter.copyOperation(insn, value1));
+                        push(value3);
                         push(value2);
                         push(value1);
                         break;
                     }
-                }
-                throw new AnalyzerException(insn, "Illegal use of DUP_X2");
-            case Opcodes.DUP2:
-                value1 = pop();
-                if (value1.getSize() == 1) {
-                    value2 = pop();
-                    if (value2.getSize() == 1) {
-                        push(value2);
-                        push(value1);
-                        push(interpreter.copyOperation(insn, value2));
-                        push(interpreter.copyOperation(insn, value1));
-                        break;
-                    }
                 } else {
+                    push(interpreter.copyOperation(insn, value1));
+                    push(value2);
                     push(value1);
+                    break;
+                }
+            }
+            throw new AnalyzerException(insn, "Illegal use of DUP_X2");
+        case Opcodes.DUP2:
+            value1 = pop();
+            if (value1.getSize() == 1) {
+                value2 = pop();
+                if (value2.getSize() == 1) {
+                    push(value2);
+                    push(value1);
+                    push(interpreter.copyOperation(insn, value2));
                     push(interpreter.copyOperation(insn, value1));
                     break;
                 }
-                throw new AnalyzerException(insn, "Illegal use of DUP2");
-            case Opcodes.DUP2_X1:
-                value1 = pop();
-                if (value1.getSize() == 1) {
-                    value2 = pop();
-                    if (value2.getSize() == 1) {
-                        value3 = pop();
-                        if (value3.getSize() == 1) {
-                            push(interpreter.copyOperation(insn, value2));
-                            push(interpreter.copyOperation(insn, value1));
-                            push(value3);
-                            push(value2);
-                            push(value1);
-                            break;
-                        }
-                    }
-                } else {
-                    value2 = pop();
-                    if (value2.getSize() == 1) {
+            } else {
+                push(value1);
+                push(interpreter.copyOperation(insn, value1));
+                break;
+            }
+            throw new AnalyzerException(insn, "Illegal use of DUP2");
+        case Opcodes.DUP2_X1:
+            value1 = pop();
+            if (value1.getSize() == 1) {
+                value2 = pop();
+                if (value2.getSize() == 1) {
+                    value3 = pop();
+                    if (value3.getSize() == 1) {
+                        push(interpreter.copyOperation(insn, value2));
                         push(interpreter.copyOperation(insn, value1));
+                        push(value3);
                         push(value2);
                         push(value1);
                         break;
                     }
                 }
-                throw new AnalyzerException(insn, "Illegal use of DUP2_X1");
-            case Opcodes.DUP2_X2:
-                value1 = pop();
-                if (value1.getSize() == 1) {
-                    value2 = pop();
-                    if (value2.getSize() == 1) {
-                        value3 = pop();
-                        if (value3.getSize() == 1) {
-                            value4 = pop();
-                            if (value4.getSize() == 1) {
-                                push(interpreter.copyOperation(insn, value2));
-                                push(interpreter.copyOperation(insn, value1));
-                                push(value4);
-                                push(value3);
-                                push(value2);
-                                push(value1);
-                                break;
-                            }
-                        } else {
+            } else {
+                value2 = pop();
+                if (value2.getSize() == 1) {
+                    push(interpreter.copyOperation(insn, value1));
+                    push(value2);
+                    push(value1);
+                    break;
+                }
+            }
+            throw new AnalyzerException(insn, "Illegal use of DUP2_X1");
+        case Opcodes.DUP2_X2:
+            value1 = pop();
+            if (value1.getSize() == 1) {
+                value2 = pop();
+                if (value2.getSize() == 1) {
+                    value3 = pop();
+                    if (value3.getSize() == 1) {
+                        value4 = pop();
+                        if (value4.getSize() == 1) {
                             push(interpreter.copyOperation(insn, value2));
                             push(interpreter.copyOperation(insn, value1));
-                            push(value3);
-                            push(value2);
-                            push(value1);
-                            break;
-                        }
-                    }
-                } else {
-                    value2 = pop();
-                    if (value2.getSize() == 1) {
-                        value3 = pop();
-                        if (value3.getSize() == 1) {
-                            push(interpreter.copyOperation(insn, value1));
+                            push(value4);
                             push(value3);
                             push(value2);
                             push(value1);
                             break;
                         }
                     } else {
+                        push(interpreter.copyOperation(insn, value2));
                         push(interpreter.copyOperation(insn, value1));
+                        push(value3);
                         push(value2);
                         push(value1);
                         break;
                     }
                 }
-                throw new AnalyzerException(insn, "Illegal use of DUP2_X2");
-            case Opcodes.SWAP:
+            } else {
                 value2 = pop();
-                value1 = pop();
-                if (value1.getSize() != 1 || value2.getSize() != 1) {
-                    throw new AnalyzerException(insn, "Illegal use of SWAP");
-                }
-                push(interpreter.copyOperation(insn, value2));
-                push(interpreter.copyOperation(insn, value1));
-                break;
-            case Opcodes.IADD:
-            case Opcodes.LADD:
-            case Opcodes.FADD:
-            case Opcodes.DADD:
-            case Opcodes.ISUB:
-            case Opcodes.LSUB:
-            case Opcodes.FSUB:
-            case Opcodes.DSUB:
-            case Opcodes.IMUL:
-            case Opcodes.LMUL:
-            case Opcodes.FMUL:
-            case Opcodes.DMUL:
-            case Opcodes.IDIV:
-            case Opcodes.LDIV:
-            case Opcodes.FDIV:
-            case Opcodes.DDIV:
-            case Opcodes.IREM:
-            case Opcodes.LREM:
-            case Opcodes.FREM:
-            case Opcodes.DREM:
-                value2 = pop();
-                value1 = pop();
-                push(interpreter.binaryOperation(insn, value1, value2));
-                break;
-            case Opcodes.INEG:
-            case Opcodes.LNEG:
-            case Opcodes.FNEG:
-            case Opcodes.DNEG:
-                push(interpreter.unaryOperation(insn, pop()));
-                break;
-            case Opcodes.ISHL:
-            case Opcodes.LSHL:
-            case Opcodes.ISHR:
-            case Opcodes.LSHR:
-            case Opcodes.IUSHR:
-            case Opcodes.LUSHR:
-            case Opcodes.IAND:
-            case Opcodes.LAND:
-            case Opcodes.IOR:
-            case Opcodes.LOR:
-            case Opcodes.IXOR:
-            case Opcodes.LXOR:
-                value2 = pop();
-                value1 = pop();
-                push(interpreter.binaryOperation(insn, value1, value2));
-                break;
-            case Opcodes.IINC:
-                var = ((IincInsnNode) insn).var;
-                setLocal(var, interpreter.unaryOperation(insn, getLocal(var)));
-                break;
-            case Opcodes.I2L:
-            case Opcodes.I2F:
-            case Opcodes.I2D:
-            case Opcodes.L2I:
-            case Opcodes.L2F:
-            case Opcodes.L2D:
-            case Opcodes.F2I:
-            case Opcodes.F2L:
-            case Opcodes.F2D:
-            case Opcodes.D2I:
-            case Opcodes.D2L:
-            case Opcodes.D2F:
-            case Opcodes.I2B:
-            case Opcodes.I2C:
-            case Opcodes.I2S:
-                push(interpreter.unaryOperation(insn, pop()));
-                break;
-            case Opcodes.LCMP:
-            case Opcodes.FCMPL:
-            case Opcodes.FCMPG:
-            case Opcodes.DCMPL:
-            case Opcodes.DCMPG:
-                value2 = pop();
-                value1 = pop();
-                push(interpreter.binaryOperation(insn, value1, value2));
-                break;
-            case Opcodes.IFEQ:
-            case Opcodes.IFNE:
-            case Opcodes.IFLT:
-            case Opcodes.IFGE:
-            case Opcodes.IFGT:
-            case Opcodes.IFLE:
-                interpreter.unaryOperation(insn, pop());
-                break;
-            case Opcodes.IF_ICMPEQ:
-            case Opcodes.IF_ICMPNE:
-            case Opcodes.IF_ICMPLT:
-            case Opcodes.IF_ICMPGE:
-            case Opcodes.IF_ICMPGT:
-            case Opcodes.IF_ICMPLE:
-            case Opcodes.IF_ACMPEQ:
-            case Opcodes.IF_ACMPNE:
-                value2 = pop();
-                value1 = pop();
-                interpreter.binaryOperation(insn, value1, value2);
-                break;
-            case Opcodes.GOTO:
-                break;
-            case Opcodes.JSR:
-                push(interpreter.newOperation(insn));
-                break;
-            case Opcodes.RET:
-                break;
-            case Opcodes.TABLESWITCH:
-            case Opcodes.LOOKUPSWITCH:
-                interpreter.unaryOperation(insn, pop());
-                break;
-            case Opcodes.IRETURN:
-            case Opcodes.LRETURN:
-            case Opcodes.FRETURN:
-            case Opcodes.DRETURN:
-            case Opcodes.ARETURN:
-                value1 = pop();
-                interpreter.unaryOperation(insn, value1);
-                interpreter.returnOperation(insn, value1, returnValue);
-                break;
-            case Opcodes.RETURN:
-                if (returnValue != null) {
-                    throw new AnalyzerException(insn, "Incompatible return type");
-                }
-                break;
-            case Opcodes.GETSTATIC:
-                push(interpreter.newOperation(insn));
-                break;
-            case Opcodes.PUTSTATIC:
-                interpreter.unaryOperation(insn, pop());
-                break;
-            case Opcodes.GETFIELD:
-                push(interpreter.unaryOperation(insn, pop()));
-                break;
-            case Opcodes.PUTFIELD:
-                value2 = pop();
-                value1 = pop();
-                interpreter.binaryOperation(insn, value1, value2);
-                break;
-            case Opcodes.INVOKEVIRTUAL:
-            case Opcodes.INVOKESPECIAL:
-            case Opcodes.INVOKESTATIC:
-            case Opcodes.INVOKEINTERFACE: {
-                values = new ArrayList<V>();
-                String desc = ((MethodInsnNode) insn).desc;
-                for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) {
-                    values.add(0, pop());
-                }
-                if (insn.getOpcode() != Opcodes.INVOKESTATIC) {
-                    values.add(0, pop());
-                }
-                if (Type.getReturnType(desc) == Type.VOID_TYPE) {
-                    interpreter.naryOperation(insn, values);
+                if (value2.getSize() == 1) {
+                    value3 = pop();
+                    if (value3.getSize() == 1) {
+                        push(interpreter.copyOperation(insn, value1));
+                        push(value3);
+                        push(value2);
+                        push(value1);
+                        break;
+                    }
                 } else {
-                    push(interpreter.naryOperation(insn, values));
+                    push(interpreter.copyOperation(insn, value1));
+                    push(value2);
+                    push(value1);
+                    break;
                 }
-                break;
             }
-            case Opcodes.INVOKEDYNAMIC: {
-                values = new ArrayList<V>();
-                String desc = ((InvokeDynamicInsnNode) insn).desc;
-                for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) {
-                    values.add(0, pop());
-                }
-                if (Type.getReturnType(desc) == Type.VOID_TYPE) {
-                    interpreter.naryOperation(insn, values);
-                } else {
-                    push(interpreter.naryOperation(insn, values));
-                }
-                break;
+            throw new AnalyzerException(insn, "Illegal use of DUP2_X2");
+        case Opcodes.SWAP:
+            value2 = pop();
+            value1 = pop();
+            if (value1.getSize() != 1 || value2.getSize() != 1) {
+                throw new AnalyzerException(insn, "Illegal use of SWAP");
             }
-            case Opcodes.NEW:
-                push(interpreter.newOperation(insn));
-                break;
-            case Opcodes.NEWARRAY:
-            case Opcodes.ANEWARRAY:
-            case Opcodes.ARRAYLENGTH:
-                push(interpreter.unaryOperation(insn, pop()));
-                break;
-            case Opcodes.ATHROW:
-                interpreter.unaryOperation(insn, pop());
-                break;
-            case Opcodes.CHECKCAST:
-            case Opcodes.INSTANCEOF:
-                push(interpreter.unaryOperation(insn, pop()));
-                break;
-            case Opcodes.MONITORENTER:
-            case Opcodes.MONITOREXIT:
-                interpreter.unaryOperation(insn, pop());
-                break;
-            case Opcodes.MULTIANEWARRAY:
-                values = new ArrayList<V>();
-                for (int i = ((MultiANewArrayInsnNode) insn).dims; i > 0; --i) {
-                    values.add(0, pop());
-                }
+            push(interpreter.copyOperation(insn, value2));
+            push(interpreter.copyOperation(insn, value1));
+            break;
+        case Opcodes.IADD:
+        case Opcodes.LADD:
+        case Opcodes.FADD:
+        case Opcodes.DADD:
+        case Opcodes.ISUB:
+        case Opcodes.LSUB:
+        case Opcodes.FSUB:
+        case Opcodes.DSUB:
+        case Opcodes.IMUL:
+        case Opcodes.LMUL:
+        case Opcodes.FMUL:
+        case Opcodes.DMUL:
+        case Opcodes.IDIV:
+        case Opcodes.LDIV:
+        case Opcodes.FDIV:
+        case Opcodes.DDIV:
+        case Opcodes.IREM:
+        case Opcodes.LREM:
+        case Opcodes.FREM:
+        case Opcodes.DREM:
+            value2 = pop();
+            value1 = pop();
+            push(interpreter.binaryOperation(insn, value1, value2));
+            break;
+        case Opcodes.INEG:
+        case Opcodes.LNEG:
+        case Opcodes.FNEG:
+        case Opcodes.DNEG:
+            push(interpreter.unaryOperation(insn, pop()));
+            break;
+        case Opcodes.ISHL:
+        case Opcodes.LSHL:
+        case Opcodes.ISHR:
+        case Opcodes.LSHR:
+        case Opcodes.IUSHR:
+        case Opcodes.LUSHR:
+        case Opcodes.IAND:
+        case Opcodes.LAND:
+        case Opcodes.IOR:
+        case Opcodes.LOR:
+        case Opcodes.IXOR:
+        case Opcodes.LXOR:
+            value2 = pop();
+            value1 = pop();
+            push(interpreter.binaryOperation(insn, value1, value2));
+            break;
+        case Opcodes.IINC:
+            var = ((IincInsnNode) insn).var;
+            setLocal(var, interpreter.unaryOperation(insn, getLocal(var)));
+            break;
+        case Opcodes.I2L:
+        case Opcodes.I2F:
+        case Opcodes.I2D:
+        case Opcodes.L2I:
+        case Opcodes.L2F:
+        case Opcodes.L2D:
+        case Opcodes.F2I:
+        case Opcodes.F2L:
+        case Opcodes.F2D:
+        case Opcodes.D2I:
+        case Opcodes.D2L:
+        case Opcodes.D2F:
+        case Opcodes.I2B:
+        case Opcodes.I2C:
+        case Opcodes.I2S:
+            push(interpreter.unaryOperation(insn, pop()));
+            break;
+        case Opcodes.LCMP:
+        case Opcodes.FCMPL:
+        case Opcodes.FCMPG:
+        case Opcodes.DCMPL:
+        case Opcodes.DCMPG:
+            value2 = pop();
+            value1 = pop();
+            push(interpreter.binaryOperation(insn, value1, value2));
+            break;
+        case Opcodes.IFEQ:
+        case Opcodes.IFNE:
+        case Opcodes.IFLT:
+        case Opcodes.IFGE:
+        case Opcodes.IFGT:
+        case Opcodes.IFLE:
+            interpreter.unaryOperation(insn, pop());
+            break;
+        case Opcodes.IF_ICMPEQ:
+        case Opcodes.IF_ICMPNE:
+        case Opcodes.IF_ICMPLT:
+        case Opcodes.IF_ICMPGE:
+        case Opcodes.IF_ICMPGT:
+        case Opcodes.IF_ICMPLE:
+        case Opcodes.IF_ACMPEQ:
+        case Opcodes.IF_ACMPNE:
+            value2 = pop();
+            value1 = pop();
+            interpreter.binaryOperation(insn, value1, value2);
+            break;
+        case Opcodes.GOTO:
+            break;
+        case Opcodes.JSR:
+            push(interpreter.newOperation(insn));
+            break;
+        case Opcodes.RET:
+            break;
+        case Opcodes.TABLESWITCH:
+        case Opcodes.LOOKUPSWITCH:
+            interpreter.unaryOperation(insn, pop());
+            break;
+        case Opcodes.IRETURN:
+        case Opcodes.LRETURN:
+        case Opcodes.FRETURN:
+        case Opcodes.DRETURN:
+        case Opcodes.ARETURN:
+            value1 = pop();
+            interpreter.unaryOperation(insn, value1);
+            interpreter.returnOperation(insn, value1, returnValue);
+            break;
+        case Opcodes.RETURN:
+            if (returnValue != null) {
+                throw new AnalyzerException(insn, "Incompatible return type");
+            }
+            break;
+        case Opcodes.GETSTATIC:
+            push(interpreter.newOperation(insn));
+            break;
+        case Opcodes.PUTSTATIC:
+            interpreter.unaryOperation(insn, pop());
+            break;
+        case Opcodes.GETFIELD:
+            push(interpreter.unaryOperation(insn, pop()));
+            break;
+        case Opcodes.PUTFIELD:
+            value2 = pop();
+            value1 = pop();
+            interpreter.binaryOperation(insn, value1, value2);
+            break;
+        case Opcodes.INVOKEVIRTUAL:
+        case Opcodes.INVOKESPECIAL:
+        case Opcodes.INVOKESTATIC:
+        case Opcodes.INVOKEINTERFACE: {
+            values = new ArrayList<V>();
+            String desc = ((MethodInsnNode) insn).desc;
+            for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) {
+                values.add(0, pop());
+            }
+            if (insn.getOpcode() != Opcodes.INVOKESTATIC) {
+                values.add(0, pop());
+            }
+            if (Type.getReturnType(desc) == Type.VOID_TYPE) {
+                interpreter.naryOperation(insn, values);
+            } else {
                 push(interpreter.naryOperation(insn, values));
-                break;
-            case Opcodes.IFNULL:
-            case Opcodes.IFNONNULL:
-                interpreter.unaryOperation(insn, pop());
-                break;
-            default:
-                throw new RuntimeException("Illegal opcode "+insn.getOpcode());
+            }
+            break;
+        }
+        case Opcodes.INVOKEDYNAMIC: {
+            values = new ArrayList<V>();
+            String desc = ((InvokeDynamicInsnNode) insn).desc;
+            for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) {
+                values.add(0, pop());
+            }
+            if (Type.getReturnType(desc) == Type.VOID_TYPE) {
+                interpreter.naryOperation(insn, values);
+            } else {
+                push(interpreter.naryOperation(insn, values));
+            }
+            break;
+        }
+        case Opcodes.NEW:
+            push(interpreter.newOperation(insn));
+            break;
+        case Opcodes.NEWARRAY:
+        case Opcodes.ANEWARRAY:
+        case Opcodes.ARRAYLENGTH:
+            push(interpreter.unaryOperation(insn, pop()));
+            break;
+        case Opcodes.ATHROW:
+            interpreter.unaryOperation(insn, pop());
+            break;
+        case Opcodes.CHECKCAST:
+        case Opcodes.INSTANCEOF:
+            push(interpreter.unaryOperation(insn, pop()));
+            break;
+        case Opcodes.MONITORENTER:
+        case Opcodes.MONITOREXIT:
+            interpreter.unaryOperation(insn, pop());
+            break;
+        case Opcodes.MULTIANEWARRAY:
+            values = new ArrayList<V>();
+            for (int i = ((MultiANewArrayInsnNode) insn).dims; i > 0; --i) {
+                values.add(0, pop());
+            }
+            push(interpreter.naryOperation(insn, values));
+            break;
+        case Opcodes.IFNULL:
+        case Opcodes.IFNONNULL:
+            interpreter.unaryOperation(insn, pop());
+            break;
+        default:
+            throw new RuntimeException("Illegal opcode " + insn.getOpcode());
         }
     }
 
     /**
      * Merges this frame with the given frame.
      *
-     * @param frame a frame.
-     * @param interpreter the interpreter used to merge values.
+     * @param frame
+     *            a frame.
+     * @param interpreter
+     *            the interpreter used to merge values.
      * @return <tt>true</tt> if this frame has been changed as a result of the
      *         merge operation, or <tt>false</tt> otherwise.
-     * @throws AnalyzerException if the frames have incompatible sizes.
+     * @throws AnalyzerException
+     *             if the frames have incompatible sizes.
      */
-    public boolean merge(final Frame<? extends V> frame, final Interpreter<V> interpreter)
-            throws AnalyzerException
-    {
+    public boolean merge(final Frame<? extends V> frame,
+            final Interpreter<V> interpreter) throws AnalyzerException {
         if (top != frame.top) {
             throw new AnalyzerException(null, "Incompatible stack heights");
         }
         boolean changes = false;
         for (int i = 0; i < locals + top; ++i) {
             V v = interpreter.merge(values[i], frame.values[i]);
-            if (v != values[i]) {
+            if (!v.equals(values[i])) {
                 values[i] = v;
-                changes |= true;
+                changes = true;
             }
         }
         return changes;
@@ -701,9 +719,11 @@
     /**
      * Merges this frame with the given frame (case of a RET instruction).
      *
-     * @param frame a frame
-     * @param access the local variables that have been accessed by the
-     *        subroutine to which the RET instruction corresponds.
+     * @param frame
+     *            a frame
+     * @param access
+     *            the local variables that have been accessed by the subroutine
+     *            to which the RET instruction corresponds.
      * @return <tt>true</tt> if this frame has been changed as a result of the
      *         merge operation, or <tt>false</tt> otherwise.
      */
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Interpreter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Interpreter.java
index fd8735f..649d5a4 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Interpreter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Interpreter.java
@@ -71,7 +71,8 @@
  * various semantic interpreters, without needing to duplicate the code to
  * simulate the transfer of values.
  *
- * @param <V> type of the Value used for the analysis.
+ * @param <V>
+ *            type of the Value used for the analysis.
  *
  * @author Eric Bruneton
  */
@@ -86,12 +87,13 @@
     /**
      * Creates a new value that represents the given type.
      *
-     * Called for method parameters (including <code>this</code>),
-     * exception handler variable and with <code>null</code> type
-     * for variables reserved by long and double types.
+     * Called for method parameters (including <code>this</code>), exception
+     * handler variable and with <code>null</code> type for variables reserved
+     * by long and double types.
      *
-     * @param type a primitive or reference type, or <tt>null</tt> to
-     *        represent an uninitialized value.
+     * @param type
+     *            a primitive or reference type, or <tt>null</tt> to represent
+     *            an uninitialized value.
      * @return a value that represents the given type. The size of the returned
      *         value must be equal to the size of the given type.
      */
@@ -105,9 +107,11 @@
      * ICONST_5, LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0,
      * DCONST_1, BIPUSH, SIPUSH, LDC, JSR, GETSTATIC, NEW
      *
-     * @param insn the bytecode instruction to be interpreted.
+     * @param insn
+     *            the bytecode instruction to be interpreted.
      * @return the result of the interpretation of the given instruction.
-     * @throws AnalyzerException if an error occured during the interpretation.
+     * @throws AnalyzerException
+     *             if an error occured during the interpretation.
      */
     public abstract V newOperation(AbstractInsnNode insn)
             throws AnalyzerException;
@@ -119,11 +123,14 @@
      * ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE,
      * ASTORE, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP
      *
-     * @param insn the bytecode instruction to be interpreted.
-     * @param value the value that must be moved by the instruction.
+     * @param insn
+     *            the bytecode instruction to be interpreted.
+     * @param value
+     *            the value that must be moved by the instruction.
      * @return the result of the interpretation of the given instruction. The
      *         returned value must be <tt>equal</tt> to the given value.
-     * @throws AnalyzerException if an error occured during the interpretation.
+     * @throws AnalyzerException
+     *             if an error occured during the interpretation.
      */
     public abstract V copyOperation(AbstractInsnNode insn, V value)
             throws AnalyzerException;
@@ -138,10 +145,13 @@
      * PUTSTATIC, GETFIELD, NEWARRAY, ANEWARRAY, ARRAYLENGTH, ATHROW, CHECKCAST,
      * INSTANCEOF, MONITORENTER, MONITOREXIT, IFNULL, IFNONNULL
      *
-     * @param insn the bytecode instruction to be interpreted.
-     * @param value the argument of the instruction to be interpreted.
+     * @param insn
+     *            the bytecode instruction to be interpreted.
+     * @param value
+     *            the argument of the instruction to be interpreted.
      * @return the result of the interpretation of the given instruction.
-     * @throws AnalyzerException if an error occured during the interpretation.
+     * @throws AnalyzerException
+     *             if an error occured during the interpretation.
      */
     public abstract V unaryOperation(AbstractInsnNode insn, V value)
             throws AnalyzerException;
@@ -157,11 +167,15 @@
      * DCMPG, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
      * IF_ACMPEQ, IF_ACMPNE, PUTFIELD
      *
-     * @param insn the bytecode instruction to be interpreted.
-     * @param value1 the first argument of the instruction to be interpreted.
-     * @param value2 the second argument of the instruction to be interpreted.
+     * @param insn
+     *            the bytecode instruction to be interpreted.
+     * @param value1
+     *            the first argument of the instruction to be interpreted.
+     * @param value2
+     *            the second argument of the instruction to be interpreted.
      * @return the result of the interpretation of the given instruction.
-     * @throws AnalyzerException if an error occured during the interpretation.
+     * @throws AnalyzerException
+     *             if an error occured during the interpretation.
      */
     public abstract V binaryOperation(AbstractInsnNode insn, V value1, V value2)
             throws AnalyzerException;
@@ -172,18 +186,20 @@
      *
      * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE
      *
-     * @param insn the bytecode instruction to be interpreted.
-     * @param value1 the first argument of the instruction to be interpreted.
-     * @param value2 the second argument of the instruction to be interpreted.
-     * @param value3 the third argument of the instruction to be interpreted.
+     * @param insn
+     *            the bytecode instruction to be interpreted.
+     * @param value1
+     *            the first argument of the instruction to be interpreted.
+     * @param value2
+     *            the second argument of the instruction to be interpreted.
+     * @param value3
+     *            the third argument of the instruction to be interpreted.
      * @return the result of the interpretation of the given instruction.
-     * @throws AnalyzerException if an error occured during the interpretation.
+     * @throws AnalyzerException
+     *             if an error occured during the interpretation.
      */
-    public abstract V ternaryOperation(
-        AbstractInsnNode insn,
-        V value1,
-        V value2,
-        V value3) throws AnalyzerException;
+    public abstract V ternaryOperation(AbstractInsnNode insn, V value1,
+            V value2, V value3) throws AnalyzerException;
 
     /**
      * Interprets a bytecode instruction with a variable number of arguments.
@@ -192,14 +208,16 @@
      * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE,
      * MULTIANEWARRAY and INVOKEDYNAMIC
      *
-     * @param insn the bytecode instruction to be interpreted.
-     * @param values the arguments of the instruction to be interpreted.
+     * @param insn
+     *            the bytecode instruction to be interpreted.
+     * @param values
+     *            the arguments of the instruction to be interpreted.
      * @return the result of the interpretation of the given instruction.
-     * @throws AnalyzerException if an error occured during the interpretation.
+     * @throws AnalyzerException
+     *             if an error occured during the interpretation.
      */
-    public abstract V naryOperation(
-        AbstractInsnNode insn,
-        List< ? extends V> values) throws AnalyzerException;
+    public abstract V naryOperation(AbstractInsnNode insn,
+            List<? extends V> values) throws AnalyzerException;
 
     /**
      * Interprets a bytecode return instruction. This method is called for the
@@ -207,15 +225,17 @@
      *
      * IRETURN, LRETURN, FRETURN, DRETURN, ARETURN
      *
-     * @param insn the bytecode instruction to be interpreted.
-     * @param value the argument of the instruction to be interpreted.
-     * @param expected the expected return type of the analyzed method.
-     * @throws AnalyzerException if an error occured during the interpretation.
+     * @param insn
+     *            the bytecode instruction to be interpreted.
+     * @param value
+     *            the argument of the instruction to be interpreted.
+     * @param expected
+     *            the expected return type of the analyzed method.
+     * @throws AnalyzerException
+     *             if an error occured during the interpretation.
      */
-    public abstract void returnOperation(
-        AbstractInsnNode insn,
-        V value,
-        V expected) throws AnalyzerException;
+    public abstract void returnOperation(AbstractInsnNode insn, V value,
+            V expected) throws AnalyzerException;
 
     /**
      * Merges two values. The merge operation must return a value that
@@ -224,8 +244,10 @@
      * values are integer intervals, the merged value must be an interval that
      * contains the previous ones. Likewise for other types of values).
      *
-     * @param v a value.
-     * @param w another value.
+     * @param v
+     *            a value.
+     * @param w
+     *            another value.
      * @return the merged value. If the merged value is equal to <tt>v</tt>,
      *         this method <i>must</i> return <tt>v</tt>.
      */
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SimpleVerifier.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SimpleVerifier.java
index 29275c7..a93c5f2 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SimpleVerifier.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SimpleVerifier.java
@@ -108,15 +108,15 @@
      * Constructs a new {@link SimpleVerifier} to verify a specific class. This
      * class will not be loaded into the JVM since it may be incorrect.
      *
-     * @param currentClass the class that is verified.
-     * @param currentSuperClass the super class of the class that is verified.
-     * @param isInterface if the class that is verified is an interface.
+     * @param currentClass
+     *            the class that is verified.
+     * @param currentSuperClass
+     *            the super class of the class that is verified.
+     * @param isInterface
+     *            if the class that is verified is an interface.
      */
-    public SimpleVerifier(
-        final Type currentClass,
-        final Type currentSuperClass,
-        final boolean isInterface)
-    {
+    public SimpleVerifier(final Type currentClass,
+            final Type currentSuperClass, final boolean isInterface) {
         this(currentClass, currentSuperClass, null, isInterface);
     }
 
@@ -124,32 +124,25 @@
      * Constructs a new {@link SimpleVerifier} to verify a specific class. This
      * class will not be loaded into the JVM since it may be incorrect.
      *
-     * @param currentClass the class that is verified.
-     * @param currentSuperClass the super class of the class that is verified.
-     * @param currentClassInterfaces the interfaces implemented by the class
-     *        that is verified.
-     * @param isInterface if the class that is verified is an interface.
+     * @param currentClass
+     *            the class that is verified.
+     * @param currentSuperClass
+     *            the super class of the class that is verified.
+     * @param currentClassInterfaces
+     *            the interfaces implemented by the class that is verified.
+     * @param isInterface
+     *            if the class that is verified is an interface.
      */
-    public SimpleVerifier(
-        final Type currentClass,
-        final Type currentSuperClass,
-        final List<Type> currentClassInterfaces,
-        final boolean isInterface)
-    {
-        this(ASM4,
-                currentClass,
-                currentSuperClass,
-                currentClassInterfaces,
+    public SimpleVerifier(final Type currentClass,
+            final Type currentSuperClass,
+            final List<Type> currentClassInterfaces, final boolean isInterface) {
+        this(ASM5, currentClass, currentSuperClass, currentClassInterfaces,
                 isInterface);
     }
 
-    protected SimpleVerifier(
-        final int api,
-        final Type currentClass,
-        final Type currentSuperClass,
-        final List<Type> currentClassInterfaces,
-        final boolean isInterface)
-    {
+    protected SimpleVerifier(final int api, final Type currentClass,
+            final Type currentSuperClass,
+            final List<Type> currentClassInterfaces, final boolean isInterface) {
         super(api);
         this.currentClass = currentClass;
         this.currentSuperClass = currentSuperClass;
@@ -162,7 +155,8 @@
      * classes. This is useful if you are verifying multiple interdependent
      * classes.
      *
-     * @param loader a <code>ClassLoader</code> to use
+     * @param loader
+     *            a <code>ClassLoader</code> to use
      */
     public void setClassLoader(final ClassLoader loader) {
         this.loader = loader;
@@ -177,11 +171,11 @@
         boolean isArray = type.getSort() == Type.ARRAY;
         if (isArray) {
             switch (type.getElementType().getSort()) {
-                case Type.BOOLEAN:
-                case Type.CHAR:
-                case Type.BYTE:
-                case Type.SHORT:
-                    return new BasicValue(type);
+            case Type.BOOLEAN:
+            case Type.CHAR:
+            case Type.BYTE:
+            case Type.SHORT:
+                return new BasicValue(type);
             }
         }
 
@@ -210,8 +204,7 @@
 
     @Override
     protected BasicValue getElementValue(final BasicValue objectArrayValue)
-            throws AnalyzerException
-    {
+            throws AnalyzerException {
         Type arrayType = objectArrayValue.getType();
         if (arrayType != null) {
             if (arrayType.getSort() == Type.ARRAY) {
@@ -225,28 +218,28 @@
     }
 
     @Override
-    protected boolean isSubTypeOf(final BasicValue value, final BasicValue expected) {
+    protected boolean isSubTypeOf(final BasicValue value,
+            final BasicValue expected) {
         Type expectedType = expected.getType();
         Type type = value.getType();
         switch (expectedType.getSort()) {
-            case Type.INT:
-            case Type.FLOAT:
-            case Type.LONG:
-            case Type.DOUBLE:
-                return type.equals(expectedType);
-            case Type.ARRAY:
-            case Type.OBJECT:
-                if ("Lnull;".equals(type.getDescriptor())) {
-                    return true;
-                } else if (type.getSort() == Type.OBJECT
-                        || type.getSort() == Type.ARRAY)
-                {
-                    return isAssignableFrom(expectedType, type);
-                } else {
-                    return false;
-                }
-            default:
-                throw new Error("Internal error");
+        case Type.INT:
+        case Type.FLOAT:
+        case Type.LONG:
+        case Type.DOUBLE:
+            return type.equals(expectedType);
+        case Type.ARRAY:
+        case Type.OBJECT:
+            if ("Lnull;".equals(type.getDescriptor())) {
+                return true;
+            } else if (type.getSort() == Type.OBJECT
+                    || type.getSort() == Type.ARRAY) {
+                return isAssignableFrom(expectedType, type);
+            } else {
+                return false;
+            }
+        default:
+            throw new Error("Internal error");
         }
     }
 
@@ -256,11 +249,9 @@
             Type t = v.getType();
             Type u = w.getType();
             if (t != null
-                    && (t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY))
-            {
+                    && (t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)) {
                 if (u != null
-                        && (u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY))
-                {
+                        && (u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY)) {
                     if ("Lnull;".equals(t.getDescriptor())) {
                         return w;
                     }
@@ -317,7 +308,8 @@
                 return false;
             } else {
                 if (isInterface) {
-                    return u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY;
+                    return u.getSort() == Type.OBJECT
+                            || u.getSort() == Type.ARRAY;
                 }
                 return isAssignableFrom(t, getSuperClass(u));
             }
@@ -347,8 +339,7 @@
         try {
             if (t.getSort() == Type.ARRAY) {
                 return Class.forName(t.getDescriptor().replace('/', '.'),
-                        false,
-                        loader);
+                        false, loader);
             }
             return Class.forName(t.getClassName(), false, loader);
         } catch (ClassNotFoundException e) {
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceInterpreter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceInterpreter.java
index 131f656..e37cecc 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceInterpreter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceInterpreter.java
@@ -76,11 +76,10 @@
  * @author Eric Bruneton
  */
 public class SourceInterpreter extends Interpreter<SourceValue> implements
-        Opcodes
-{
+        Opcodes {
 
     public SourceInterpreter() {
-        super(ASM4);
+        super(ASM5);
     }
 
     protected SourceInterpreter(final int api) {
@@ -99,125 +98,118 @@
     public SourceValue newOperation(final AbstractInsnNode insn) {
         int size;
         switch (insn.getOpcode()) {
-            case LCONST_0:
-            case LCONST_1:
-            case DCONST_0:
-            case DCONST_1:
-                size = 2;
-                break;
-            case LDC:
-                Object cst = ((LdcInsnNode) insn).cst;
-                size = cst instanceof Long || cst instanceof Double ? 2 : 1;
-                break;
-            case GETSTATIC:
-                size = Type.getType(((FieldInsnNode) insn).desc).getSize();
-                break;
-            default:
-                size = 1;
+        case LCONST_0:
+        case LCONST_1:
+        case DCONST_0:
+        case DCONST_1:
+            size = 2;
+            break;
+        case LDC:
+            Object cst = ((LdcInsnNode) insn).cst;
+            size = cst instanceof Long || cst instanceof Double ? 2 : 1;
+            break;
+        case GETSTATIC:
+            size = Type.getType(((FieldInsnNode) insn).desc).getSize();
+            break;
+        default:
+            size = 1;
         }
         return new SourceValue(size, insn);
     }
 
     @Override
-    public SourceValue copyOperation(final AbstractInsnNode insn, final SourceValue value) {
+    public SourceValue copyOperation(final AbstractInsnNode insn,
+            final SourceValue value) {
         return new SourceValue(value.getSize(), insn);
     }
 
     @Override
-    public SourceValue unaryOperation(final AbstractInsnNode insn, final SourceValue value)
-    {
+    public SourceValue unaryOperation(final AbstractInsnNode insn,
+            final SourceValue value) {
         int size;
         switch (insn.getOpcode()) {
-            case LNEG:
-            case DNEG:
-            case I2L:
-            case I2D:
-            case L2D:
-            case F2L:
-            case F2D:
-            case D2L:
-                size = 2;
-                break;
-            case GETFIELD:
-                size = Type.getType(((FieldInsnNode) insn).desc).getSize();
-                break;
-            default:
-                size = 1;
+        case LNEG:
+        case DNEG:
+        case I2L:
+        case I2D:
+        case L2D:
+        case F2L:
+        case F2D:
+        case D2L:
+            size = 2;
+            break;
+        case GETFIELD:
+            size = Type.getType(((FieldInsnNode) insn).desc).getSize();
+            break;
+        default:
+            size = 1;
         }
         return new SourceValue(size, insn);
     }
 
     @Override
-    public SourceValue binaryOperation(
-        final AbstractInsnNode insn,
-        final SourceValue value1,
-        final SourceValue value2)
-    {
+    public SourceValue binaryOperation(final AbstractInsnNode insn,
+            final SourceValue value1, final SourceValue value2) {
         int size;
         switch (insn.getOpcode()) {
-            case LALOAD:
-            case DALOAD:
-            case LADD:
-            case DADD:
-            case LSUB:
-            case DSUB:
-            case LMUL:
-            case DMUL:
-            case LDIV:
-            case DDIV:
-            case LREM:
-            case DREM:
-            case LSHL:
-            case LSHR:
-            case LUSHR:
-            case LAND:
-            case LOR:
-            case LXOR:
-                size = 2;
-                break;
-            default:
-                size = 1;
+        case LALOAD:
+        case DALOAD:
+        case LADD:
+        case DADD:
+        case LSUB:
+        case DSUB:
+        case LMUL:
+        case DMUL:
+        case LDIV:
+        case DDIV:
+        case LREM:
+        case DREM:
+        case LSHL:
+        case LSHR:
+        case LUSHR:
+        case LAND:
+        case LOR:
+        case LXOR:
+            size = 2;
+            break;
+        default:
+            size = 1;
         }
         return new SourceValue(size, insn);
     }
 
     @Override
-    public SourceValue ternaryOperation(
-        final AbstractInsnNode insn,
-        final SourceValue value1,
-        final SourceValue value2,
-        final SourceValue value3)
-    {
+    public SourceValue ternaryOperation(final AbstractInsnNode insn,
+            final SourceValue value1, final SourceValue value2,
+            final SourceValue value3) {
         return new SourceValue(1, insn);
     }
 
     @Override
-    public SourceValue naryOperation(final AbstractInsnNode insn, final List<? extends SourceValue> values) {
+    public SourceValue naryOperation(final AbstractInsnNode insn,
+            final List<? extends SourceValue> values) {
         int size;
         int opcode = insn.getOpcode();
         if (opcode == MULTIANEWARRAY) {
             size = 1;
         } else {
-            String desc = (opcode == INVOKEDYNAMIC)?
-                    ((InvokeDynamicInsnNode) insn).desc:
-                    ((MethodInsnNode) insn).desc;
+            String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc
+                    : ((MethodInsnNode) insn).desc;
             size = Type.getReturnType(desc).getSize();
         }
         return new SourceValue(size, insn);
     }
 
     @Override
-    public void returnOperation(
-        final AbstractInsnNode insn,
-        final SourceValue value,
-        final SourceValue expected)
-    {
+    public void returnOperation(final AbstractInsnNode insn,
+            final SourceValue value, final SourceValue expected) {
     }
 
     @Override
     public SourceValue merge(final SourceValue d, final SourceValue w) {
         if (d.insns instanceof SmallSet && w.insns instanceof SmallSet) {
-            Set<AbstractInsnNode> s = ((SmallSet<AbstractInsnNode>) d.insns).union((SmallSet<AbstractInsnNode>) w.insns);
+            Set<AbstractInsnNode> s = ((SmallSet<AbstractInsnNode>) d.insns)
+                    .union((SmallSet<AbstractInsnNode>) w.insns);
             if (s == d.insns && d.size == w.size) {
                 return d;
             } else {
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceValue.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceValue.java
index 344a329..bb0e891 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceValue.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceValue.java
@@ -77,8 +77,8 @@
 
     /**
      * The instructions that can produce this value. For example, for the Java
-     * code below, the instructions that can produce the value of <tt>i</tt>
-     * at line 5 are the txo ISTORE instructions at line 1 and 3:
+     * code below, the instructions that can produce the value of <tt>i</tt> at
+     * line 5 are the txo ISTORE instructions at line 1 and 3:
      *
      * <pre>
      * 1: i = 0;
@@ -93,7 +93,7 @@
     public final Set<AbstractInsnNode> insns;
 
     public SourceValue(final int size) {
-        this(size, SmallSet.<AbstractInsnNode>emptySet());
+        this(size, SmallSet.<AbstractInsnNode> emptySet());
     }
 
     public SourceValue(final int size, final AbstractInsnNode insn) {
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Subroutine.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Subroutine.java
index 670e232..1bf517f 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Subroutine.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Subroutine.java
@@ -80,11 +80,8 @@
     private Subroutine() {
     }
 
-    Subroutine(
-        final LabelNode start,
-        final int maxLocals,
-        final JumpInsnNode caller)
-    {
+    Subroutine(final LabelNode start, final int maxLocals,
+            final JumpInsnNode caller) {
         this.start = start;
         this.access = new boolean[maxLocals];
         this.callers = new ArrayList<JumpInsnNode>();
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/ASMifiable.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/ASMifiable.java
index 86f7a61..b7fbb89 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/ASMifiable.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/ASMifiable.java
@@ -22,7 +22,7 @@
  * questions.
  */
 
-/*
+/**
  * This file is available under and governed by the GNU General Public
  * License version 2 only, as published by the Free Software Foundation.
  * However, the following notice accompanied the original version of this
@@ -73,10 +73,13 @@
     /**
      * Prints the ASM code to create an attribute equal to this attribute.
      *
-     * @param buf a buffer used for printing Java code.
-     * @param varName name of the variable in a printed code used to store
-     *        attribute instance.
-     * @param labelNames map of label instances to their names.
+     * @param buf
+     *            a buffer used for printing Java code.
+     * @param varName
+     *            name of the variable in a printed code used to store attribute
+     *            instance.
+     * @param labelNames
+     *            map of label instances to their names.
      */
     void asmify(StringBuffer buf, String varName, Map<Label, String> labelNames);
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java
index 86cbedd..6b6bd4d 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java
@@ -30,7 +30,6 @@
  *
  * ASM: a very small and fast Java bytecode manipulation framework
  * Copyright (c) 2000-2011 INRIA, France Telecom
- * Copyright (c) 2011 Google
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -70,6 +69,7 @@
 import jdk.internal.org.objectweb.asm.Label;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.Type;
+import jdk.internal.org.objectweb.asm.TypePath;
 
 /**
  * A {@link Printer} that prints the ASM code to generate the classes if visits.
@@ -115,17 +115,20 @@
      * {@link #ASMifier(int, String, int)} version.
      */
     public ASMifier() {
-        this(Opcodes.ASM4, "cw", 0);
+        this(Opcodes.ASM5, "cw", 0);
     }
 
     /**
      * Constructs a new {@link ASMifier}.
      *
-     * @param api the ASM API version implemented by this class. Must be one of
-     *        {@link Opcodes#ASM4}.
-     * @param name the name of the visitor variable in the produced code.
-     * @param id identifier of the annotation visitor variable in the produced
-     *        code.
+     * @param api
+     *            the ASM API version implemented by this class. Must be one of
+     *            {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param name
+     *            the name of the visitor variable in the produced code.
+     * @param id
+     *            identifier of the annotation visitor variable in the produced
+     *            code.
      */
     protected ASMifier(final int api, final String name, final int id) {
         super(api);
@@ -135,13 +138,15 @@
 
     /**
      * Prints the ASM source code to generate the given class to the standard
-     * output. <p> Usage: ASMifier [-debug] &lt;binary
-     * class name or class file name&gt;
+     * output.
+     * <p>
+     * Usage: ASMifier [-debug] &lt;binary class name or class file name&gt;
      *
-     * @param args the command line arguments.
+     * @param args
+     *            the command line arguments.
      *
-     * @throws Exception if the class cannot be found, or if an IO exception
-     *         occurs.
+     * @throws Exception
+     *             if the class cannot be found, or if an IO exception occurs.
      */
     public static void main(final String[] args) throws Exception {
         int i = 0;
@@ -159,22 +164,21 @@
             }
         }
         if (!ok) {
-            System.err.println("Prints the ASM code to generate the given class.");
+            System.err
+                    .println("Prints the ASM code to generate the given class.");
             System.err.println("Usage: ASMifier [-debug] "
                     + "<fully qualified class name or class file name>");
             return;
         }
         ClassReader cr;
         if (args[i].endsWith(".class") || args[i].indexOf('\\') > -1
-                || args[i].indexOf('/') > -1)
-        {
+                || args[i].indexOf('/') > -1) {
             cr = new ClassReader(new FileInputStream(args[i]));
         } else {
             cr = new ClassReader(args[i]);
         }
-        cr.accept(new TraceClassVisitor(null,
-                new ASMifier(),
-                new PrintWriter(System.out)), flags);
+        cr.accept(new TraceClassVisitor(null, new ASMifier(), new PrintWriter(
+                System.out)), flags);
     }
 
     // ------------------------------------------------------------------------
@@ -182,14 +186,9 @@
     // ------------------------------------------------------------------------
 
     @Override
-    public void visit(
-        final int version,
-        final int access,
-        final String name,
-        final String signature,
-        final String superName,
-        final String[] interfaces)
-    {
+    public void visit(final int version, final int access, final String name,
+            final String signature, final String superName,
+            final String[] interfaces) {
         String simpleName;
         int n = name.lastIndexOf('/');
         if (n == -1) {
@@ -212,30 +211,30 @@
         buf.setLength(0);
         buf.append("cw.visit(");
         switch (version) {
-            case Opcodes.V1_1:
-                buf.append("V1_1");
-                break;
-            case Opcodes.V1_2:
-                buf.append("V1_2");
-                break;
-            case Opcodes.V1_3:
-                buf.append("V1_3");
-                break;
-            case Opcodes.V1_4:
-                buf.append("V1_4");
-                break;
-            case Opcodes.V1_5:
-                buf.append("V1_5");
-                break;
-            case Opcodes.V1_6:
-                buf.append("V1_6");
-                break;
-            case Opcodes.V1_7:
-                buf.append("V1_7");
-                break;
-            default:
-                buf.append(version);
-                break;
+        case Opcodes.V1_1:
+            buf.append("V1_1");
+            break;
+        case Opcodes.V1_2:
+            buf.append("V1_2");
+            break;
+        case Opcodes.V1_3:
+            buf.append("V1_3");
+            break;
+        case Opcodes.V1_4:
+            buf.append("V1_4");
+            break;
+        case Opcodes.V1_5:
+            buf.append("V1_5");
+            break;
+        case Opcodes.V1_6:
+            buf.append("V1_6");
+            break;
+        case Opcodes.V1_7:
+            buf.append("V1_7");
+            break;
+        default:
+            buf.append(version);
+            break;
         }
         buf.append(", ");
         appendAccess(access | ACCESS_CLASS);
@@ -272,11 +271,8 @@
     }
 
     @Override
-    public void visitOuterClass(
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitOuterClass(final String owner, final String name,
+            final String desc) {
         buf.setLength(0);
         buf.append("cw.visitOuterClass(");
         appendConstant(owner);
@@ -289,25 +285,25 @@
     }
 
     @Override
-    public ASMifier visitClassAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public ASMifier visitClassAnnotation(final String desc,
+            final boolean visible) {
         return visitAnnotation(desc, visible);
     }
 
     @Override
+    public ASMifier visitClassTypeAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        return visitTypeAnnotation(typeRef, typePath, desc, visible);
+    }
+
+    @Override
     public void visitClassAttribute(final Attribute attr) {
         visitAttribute(attr);
     }
 
     @Override
-    public void visitInnerClass(
-        final String name,
-        final String outerName,
-        final String innerName,
-        final int access)
-    {
+    public void visitInnerClass(final String name, final String outerName,
+            final String innerName, final int access) {
         buf.setLength(0);
         buf.append("cw.visitInnerClass(");
         appendConstant(name);
@@ -322,13 +318,8 @@
     }
 
     @Override
-    public ASMifier visitField(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final Object value)
-    {
+    public ASMifier visitField(final int access, final String name,
+            final String desc, final String signature, final Object value) {
         buf.setLength(0);
         buf.append("{\n");
         buf.append("fv = cw.visitField(");
@@ -350,13 +341,8 @@
     }
 
     @Override
-    public ASMifier visitMethod(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final String[] exceptions)
-    {
+    public ASMifier visitMethod(final int access, final String name,
+            final String desc, final String signature, final String[] exceptions) {
         buf.setLength(0);
         buf.append("{\n");
         buf.append("mv = cw.visitMethod(");
@@ -410,11 +396,8 @@
     }
 
     @Override
-    public void visitEnum(
-        final String name,
-        final String desc,
-        final String value)
-    {
+    public void visitEnum(final String name, final String desc,
+            final String value) {
         buf.setLength(0);
         buf.append("av").append(id).append(".visitEnum(");
         appendConstant(buf, name);
@@ -427,10 +410,7 @@
     }
 
     @Override
-    public ASMifier visitAnnotation(
-        final String name,
-        final String desc)
-    {
+    public ASMifier visitAnnotation(final String name, final String desc) {
         buf.setLength(0);
         buf.append("{\n");
         buf.append("AnnotationVisitor av").append(id + 1).append(" = av");
@@ -473,14 +453,18 @@
     // ------------------------------------------------------------------------
 
     @Override
-    public ASMifier visitFieldAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public ASMifier visitFieldAnnotation(final String desc,
+            final boolean visible) {
         return visitAnnotation(desc, visible);
     }
 
     @Override
+    public ASMifier visitFieldTypeAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        return visitTypeAnnotation(typeRef, typePath, desc, visible);
+    }
+
+    @Override
     public void visitFieldAttribute(final Attribute attr) {
         visitAttribute(attr);
     }
@@ -497,11 +481,18 @@
     // ------------------------------------------------------------------------
 
     @Override
+    public void visitParameter(String parameterName, int access) {
+        buf.setLength(0);
+        buf.append(name).append(".visitParameter(").append(parameterName)
+                .append(", ");
+        appendAccess(access);
+        text.add(buf.append(");\n").toString());
+    }
+
+    @Override
     public ASMifier visitAnnotationDefault() {
         buf.setLength(0);
-        buf.append("{\n")
-                .append("av0 = ")
-                .append(name)
+        buf.append("{\n").append("av0 = ").append(name)
                 .append(".visitAnnotationDefault();\n");
         text.add(buf.toString());
         ASMifier a = createASMifier("av", 0);
@@ -511,23 +502,23 @@
     }
 
     @Override
-    public ASMifier visitMethodAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public ASMifier visitMethodAnnotation(final String desc,
+            final boolean visible) {
         return visitAnnotation(desc, visible);
     }
 
     @Override
-    public ASMifier visitParameterAnnotation(
-        final int parameter,
-        final String desc,
-        final boolean visible)
-    {
+    public ASMifier visitMethodTypeAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        return visitTypeAnnotation(typeRef, typePath, desc, visible);
+    }
+
+    @Override
+    public ASMifier visitParameterAnnotation(final int parameter,
+            final String desc, final boolean visible) {
         buf.setLength(0);
-        buf.append("{\n")
-                .append("av0 = ").append(name).append(".visitParameterAnnotation(")
-                .append(parameter)
+        buf.append("{\n").append("av0 = ").append(name)
+                .append(".visitParameterAnnotation(").append(parameter)
                 .append(", ");
         appendConstant(desc);
         buf.append(", ").append(visible).append(");\n");
@@ -549,52 +540,47 @@
     }
 
     @Override
-    public void visitFrame(
-        final int type,
-        final int nLocal,
-        final Object[] local,
-        final int nStack,
-        final Object[] stack)
-    {
+    public void visitFrame(final int type, final int nLocal,
+            final Object[] local, final int nStack, final Object[] stack) {
         buf.setLength(0);
         switch (type) {
-            case Opcodes.F_NEW:
-            case Opcodes.F_FULL:
-                declareFrameTypes(nLocal, local);
-                declareFrameTypes(nStack, stack);
-                if (type == Opcodes.F_NEW) {
-                    buf.append(name).append(".visitFrame(Opcodes.F_NEW, ");
-                } else {
-                    buf.append(name).append(".visitFrame(Opcodes.F_FULL, ");
-                }
-                buf.append(nLocal).append(", new Object[] {");
-                appendFrameTypes(nLocal, local);
-                buf.append("}, ").append(nStack).append(", new Object[] {");
-                appendFrameTypes(nStack, stack);
-                buf.append('}');
-                break;
-            case Opcodes.F_APPEND:
-                declareFrameTypes(nLocal, local);
-                buf.append(name).append(".visitFrame(Opcodes.F_APPEND,")
-                        .append(nLocal)
-                        .append(", new Object[] {");
-                appendFrameTypes(nLocal, local);
-                buf.append("}, 0, null");
-                break;
-            case Opcodes.F_CHOP:
-                buf.append(name).append(".visitFrame(Opcodes.F_CHOP,")
-                        .append(nLocal)
-                        .append(", null, 0, null");
-                break;
-            case Opcodes.F_SAME:
-                buf.append(name).append(".visitFrame(Opcodes.F_SAME, 0, null, 0, null");
-                break;
-            case Opcodes.F_SAME1:
-                declareFrameTypes(1, stack);
-                buf.append(name).append(".visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {");
-                appendFrameTypes(1, stack);
-                buf.append('}');
-                break;
+        case Opcodes.F_NEW:
+        case Opcodes.F_FULL:
+            declareFrameTypes(nLocal, local);
+            declareFrameTypes(nStack, stack);
+            if (type == Opcodes.F_NEW) {
+                buf.append(name).append(".visitFrame(Opcodes.F_NEW, ");
+            } else {
+                buf.append(name).append(".visitFrame(Opcodes.F_FULL, ");
+            }
+            buf.append(nLocal).append(", new Object[] {");
+            appendFrameTypes(nLocal, local);
+            buf.append("}, ").append(nStack).append(", new Object[] {");
+            appendFrameTypes(nStack, stack);
+            buf.append('}');
+            break;
+        case Opcodes.F_APPEND:
+            declareFrameTypes(nLocal, local);
+            buf.append(name).append(".visitFrame(Opcodes.F_APPEND,")
+                    .append(nLocal).append(", new Object[] {");
+            appendFrameTypes(nLocal, local);
+            buf.append("}, 0, null");
+            break;
+        case Opcodes.F_CHOP:
+            buf.append(name).append(".visitFrame(Opcodes.F_CHOP,")
+                    .append(nLocal).append(", null, 0, null");
+            break;
+        case Opcodes.F_SAME:
+            buf.append(name).append(
+                    ".visitFrame(Opcodes.F_SAME, 0, null, 0, null");
+            break;
+        case Opcodes.F_SAME1:
+            declareFrameTypes(1, stack);
+            buf.append(name).append(
+                    ".visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {");
+            appendFrameTypes(1, stack);
+            buf.append('}');
+            break;
         }
         buf.append(");\n");
         text.add(buf.toString());
@@ -603,7 +589,8 @@
     @Override
     public void visitInsn(final int opcode) {
         buf.setLength(0);
-        buf.append(name).append(".visitInsn(").append(OPCODES[opcode]).append(");\n");
+        buf.append(name).append(".visitInsn(").append(OPCODES[opcode])
+                .append(");\n");
         text.add(buf.toString());
     }
 
@@ -614,43 +601,35 @@
                 .append(".visitIntInsn(")
                 .append(OPCODES[opcode])
                 .append(", ")
-                .append(opcode == Opcodes.NEWARRAY
-                        ? TYPES[operand]
-                        : Integer.toString(operand))
-                .append(");\n");
+                .append(opcode == Opcodes.NEWARRAY ? TYPES[operand] : Integer
+                        .toString(operand)).append(");\n");
         text.add(buf.toString());
     }
 
     @Override
     public void visitVarInsn(final int opcode, final int var) {
         buf.setLength(0);
-        buf.append(name)
-                .append(".visitVarInsn(")
-                .append(OPCODES[opcode])
-                .append(", ")
-                .append(var)
-                .append(");\n");
+        buf.append(name).append(".visitVarInsn(").append(OPCODES[opcode])
+                .append(", ").append(var).append(");\n");
         text.add(buf.toString());
     }
 
     @Override
     public void visitTypeInsn(final int opcode, final String type) {
         buf.setLength(0);
-        buf.append(name).append(".visitTypeInsn(").append(OPCODES[opcode]).append(", ");
+        buf.append(name).append(".visitTypeInsn(").append(OPCODES[opcode])
+                .append(", ");
         appendConstant(type);
         buf.append(");\n");
         text.add(buf.toString());
     }
 
     @Override
-    public void visitFieldInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitFieldInsn(final int opcode, final String owner,
+            final String name, final String desc) {
         buf.setLength(0);
-        buf.append(this.name).append(".visitFieldInsn(").append(OPCODES[opcode]).append(", ");
+        buf.append(this.name).append(".visitFieldInsn(")
+                .append(OPCODES[opcode]).append(", ");
         appendConstant(owner);
         buf.append(", ");
         appendConstant(name);
@@ -661,14 +640,11 @@
     }
 
     @Override
-    public void visitMethodInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitMethodInsn(final int opcode, final String owner,
+            final String name, final String desc) {
         buf.setLength(0);
-        buf.append(this.name).append(".visitMethodInsn(").append(OPCODES[opcode]).append(", ");
+        buf.append(this.name).append(".visitMethodInsn(")
+                .append(OPCODES[opcode]).append(", ");
         appendConstant(owner);
         buf.append(", ");
         appendConstant(name);
@@ -679,12 +655,8 @@
     }
 
     @Override
-    public void visitInvokeDynamicInsn(
-        String name,
-        String desc,
-        Handle bsm,
-        Object... bsmArgs)
-    {
+    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+            Object... bsmArgs) {
         buf.setLength(0);
         buf.append(this.name).append(".visitInvokeDynamicInsn(");
         appendConstant(name);
@@ -707,7 +679,8 @@
     public void visitJumpInsn(final int opcode, final Label label) {
         buf.setLength(0);
         declareLabel(label);
-        buf.append(name).append(".visitJumpInsn(").append(OPCODES[opcode]).append(", ");
+        buf.append(name).append(".visitJumpInsn(").append(OPCODES[opcode])
+                .append(", ");
         appendLabel(label);
         buf.append(");\n");
         text.add(buf.toString());
@@ -735,34 +708,22 @@
     @Override
     public void visitIincInsn(final int var, final int increment) {
         buf.setLength(0);
-        buf.append(name)
-                .append(".visitIincInsn(")
-                .append(var)
-                .append(", ")
-                .append(increment)
-                .append(");\n");
+        buf.append(name).append(".visitIincInsn(").append(var).append(", ")
+                .append(increment).append(");\n");
         text.add(buf.toString());
     }
 
     @Override
-    public void visitTableSwitchInsn(
-        final int min,
-        final int max,
-        final Label dflt,
-        final Label... labels)
-    {
+    public void visitTableSwitchInsn(final int min, final int max,
+            final Label dflt, final Label... labels) {
         buf.setLength(0);
         for (int i = 0; i < labels.length; ++i) {
             declareLabel(labels[i]);
         }
         declareLabel(dflt);
 
-        buf.append(name)
-                .append(".visitTableSwitchInsn(")
-                .append(min)
-                .append(", ")
-                .append(max)
-                .append(", ");
+        buf.append(name).append(".visitTableSwitchInsn(").append(min)
+                .append(", ").append(max).append(", ");
         appendLabel(dflt);
         buf.append(", new Label[] {");
         for (int i = 0; i < labels.length; ++i) {
@@ -774,11 +735,8 @@
     }
 
     @Override
-    public void visitLookupSwitchInsn(
-        final Label dflt,
-        final int[] keys,
-        final Label[] labels)
-    {
+    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+            final Label[] labels) {
         buf.setLength(0);
         for (int i = 0; i < labels.length; ++i) {
             declareLabel(labels[i]);
@@ -810,12 +768,15 @@
     }
 
     @Override
-    public void visitTryCatchBlock(
-        final Label start,
-        final Label end,
-        final Label handler,
-        final String type)
-    {
+    public ASMifier visitInsnAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        return visitTypeAnnotation("visitInsnAnnotation", typeRef, typePath,
+                desc, visible);
+    }
+
+    @Override
+    public void visitTryCatchBlock(final Label start, final Label end,
+            final Label handler, final String type) {
         buf.setLength(0);
         declareLabel(start);
         declareLabel(end);
@@ -833,14 +794,16 @@
     }
 
     @Override
-    public void visitLocalVariable(
-        final String name,
-        final String desc,
-        final String signature,
-        final Label start,
-        final Label end,
-        final int index)
-    {
+    public ASMifier visitTryCatchAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        return visitTypeAnnotation("visitTryCatchAnnotation", typeRef,
+                typePath, desc, visible);
+    }
+
+    @Override
+    public void visitLocalVariable(final String name, final String desc,
+            final String signature, final Label start, final Label end,
+            final int index) {
         buf.setLength(0);
         buf.append(this.name).append(".visitLocalVariable(");
         appendConstant(name);
@@ -857,6 +820,39 @@
     }
 
     @Override
+    public Printer visitLocalVariableAnnotation(int typeRef, TypePath typePath,
+            Label[] start, Label[] end, int[] index, String desc,
+            boolean visible) {
+        buf.setLength(0);
+        buf.append("{\n").append("av0 = ").append(name)
+                .append(".visitLocalVariableAnnotation(");
+        buf.append(typeRef);
+        buf.append(", TypePath.fromString(\"").append(typePath).append("\"), ");
+        buf.append("new Label[] {");
+        for (int i = 0; i < start.length; ++i) {
+            buf.append(i == 0 ? " " : ", ");
+            appendLabel(start[i]);
+        }
+        buf.append(" }, new Label[] {");
+        for (int i = 0; i < end.length; ++i) {
+            buf.append(i == 0 ? " " : ", ");
+            appendLabel(end[i]);
+        }
+        buf.append(" }, new int[] {");
+        for (int i = 0; i < index.length; ++i) {
+            buf.append(i == 0 ? " " : ", ").append(index[i]);
+        }
+        buf.append(" }, ");
+        appendConstant(desc);
+        buf.append(", ").append(visible).append(");\n");
+        text.add(buf.toString());
+        ASMifier a = createASMifier("av", 0);
+        text.add(a.getText());
+        text.add("}\n");
+        return a;
+    }
+
+    @Override
     public void visitLineNumber(final int line, final Label start) {
         buf.setLength(0);
         buf.append(name).append(".visitLineNumber(").append(line).append(", ");
@@ -868,12 +864,8 @@
     @Override
     public void visitMaxs(final int maxStack, final int maxLocals) {
         buf.setLength(0);
-        buf.append(name)
-                .append(".visitMaxs(")
-                .append(maxStack)
-                .append(", ")
-                .append(maxLocals)
-                .append(");\n");
+        buf.append(name).append(".visitMaxs(").append(maxStack).append(", ")
+                .append(maxLocals).append(");\n");
         text.add(buf.toString());
     }
 
@@ -888,14 +880,9 @@
     // Common methods
     // ------------------------------------------------------------------------
 
-    public ASMifier visitAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public ASMifier visitAnnotation(final String desc, final boolean visible) {
         buf.setLength(0);
-        buf.append("{\n")
-                .append("av0 = ")
-                .append(name)
+        buf.append("{\n").append("av0 = ").append(name)
                 .append(".visitAnnotation(");
         appendConstant(desc);
         buf.append(", ").append(visible).append(");\n");
@@ -906,6 +893,28 @@
         return a;
     }
 
+    public ASMifier visitTypeAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        return visitTypeAnnotation("visitTypeAnnotation", typeRef, typePath,
+                desc, visible);
+    }
+
+    public ASMifier visitTypeAnnotation(final String method, final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        buf.setLength(0);
+        buf.append("{\n").append("av0 = ").append(name).append(".")
+                .append(method).append("(");
+        buf.append(typeRef);
+        buf.append(", TypePath.fromString(\"").append(typePath).append("\"), ");
+        appendConstant(desc);
+        buf.append(", ").append(visible).append(");\n");
+        text.add(buf.toString());
+        ASMifier a = createASMifier("av", 0);
+        text.add(a.getText());
+        text.add("}\n");
+        return a;
+    }
+
     public void visitAttribute(final Attribute attr) {
         buf.setLength(0);
         buf.append("// ATTRIBUTE ").append(attr.type).append('\n');
@@ -925,15 +934,16 @@
     // Utility methods
     // ------------------------------------------------------------------------
 
-    protected ASMifier createASMifier(final String name, final int id)    {
-        return new ASMifier(Opcodes.ASM4, name, id);
+    protected ASMifier createASMifier(final String name, final int id) {
+        return new ASMifier(Opcodes.ASM5, name, id);
     }
 
     /**
-     * Appends a string representation of the given access modifiers to {@link
-     * #buf buf}.
+     * Appends a string representation of the given access modifiers to
+     * {@link #buf buf}.
      *
-     * @param access some access modifiers.
+     * @param access
+     *            some access modifiers.
      */
     void appendAccess(final int access) {
         boolean first = true;
@@ -975,8 +985,7 @@
             first = false;
         }
         if ((access & Opcodes.ACC_VOLATILE) != 0
-                && (access & ACCESS_FIELD) != 0)
-        {
+                && (access & ACCESS_FIELD) != 0) {
             if (!first) {
                 buf.append(" + ");
             }
@@ -984,8 +993,7 @@
             first = false;
         }
         if ((access & Opcodes.ACC_BRIDGE) != 0 && (access & ACCESS_CLASS) == 0
-                && (access & ACCESS_FIELD) == 0)
-        {
+                && (access & ACCESS_FIELD) == 0) {
             if (!first) {
                 buf.append(" + ");
             }
@@ -993,8 +1001,7 @@
             first = false;
         }
         if ((access & Opcodes.ACC_VARARGS) != 0 && (access & ACCESS_CLASS) == 0
-                && (access & ACCESS_FIELD) == 0)
-        {
+                && (access & ACCESS_FIELD) == 0) {
             if (!first) {
                 buf.append(" + ");
             }
@@ -1002,8 +1009,7 @@
             first = false;
         }
         if ((access & Opcodes.ACC_TRANSIENT) != 0
-                && (access & ACCESS_FIELD) != 0)
-        {
+                && (access & ACCESS_FIELD) != 0) {
             if (!first) {
                 buf.append(" + ");
             }
@@ -1011,8 +1017,7 @@
             first = false;
         }
         if ((access & Opcodes.ACC_NATIVE) != 0 && (access & ACCESS_CLASS) == 0
-                && (access & ACCESS_FIELD) == 0)
-        {
+                && (access & ACCESS_FIELD) == 0) {
             if (!first) {
                 buf.append(" + ");
             }
@@ -1021,8 +1026,7 @@
         }
         if ((access & Opcodes.ACC_ENUM) != 0
                 && ((access & ACCESS_CLASS) != 0
-                        || (access & ACCESS_FIELD) != 0 || (access & ACCESS_INNER) != 0))
-        {
+                        || (access & ACCESS_FIELD) != 0 || (access & ACCESS_INNER) != 0)) {
             if (!first) {
                 buf.append(" + ");
             }
@@ -1030,8 +1034,7 @@
             first = false;
         }
         if ((access & Opcodes.ACC_ANNOTATION) != 0
-                && ((access & ACCESS_CLASS) != 0 || (access & ACCESS_INNER) != 0))
-        {
+                && ((access & ACCESS_CLASS) != 0 || (access & ACCESS_INNER) != 0)) {
             if (!first) {
                 buf.append(" + ");
             }
@@ -1082,8 +1085,9 @@
      * Appends a string representation of the given constant to the given
      * buffer.
      *
-     * @param cst an {@link Integer}, {@link Float}, {@link Long},
-     *        {@link Double} or {@link String} object. May be <tt>null</tt>.
+     * @param cst
+     *            an {@link Integer}, {@link Float}, {@link Long},
+     *            {@link Double} or {@link String} object. May be <tt>null</tt>.
      */
     protected void appendConstant(final Object cst) {
         appendConstant(buf, cst);
@@ -1093,9 +1097,11 @@
      * Appends a string representation of the given constant to the given
      * buffer.
      *
-     * @param buf a string buffer.
-     * @param cst an {@link Integer}, {@link Float}, {@link Long},
-     *        {@link Double} or {@link String} object. May be <tt>null</tt>.
+     * @param buf
+     *            a string buffer.
+     * @param cst
+     *            an {@link Integer}, {@link Float}, {@link Long},
+     *            {@link Double} or {@link String} object. May be <tt>null</tt>.
      */
     static void appendConstant(final StringBuffer buf, final Object cst) {
         if (cst == null) {
@@ -1109,14 +1115,16 @@
         } else if (cst instanceof Handle) {
             buf.append("new Handle(");
             Handle h = (Handle) cst;
-            buf.append("Opcodes.").append(HANDLE_TAG[h.getTag()]).append(", \"");
+            buf.append("Opcodes.").append(HANDLE_TAG[h.getTag()])
+                    .append(", \"");
             buf.append(h.getOwner()).append("\", \"");
             buf.append(h.getName()).append("\", \"");
             buf.append(h.getDesc()).append("\")");
         } else if (cst instanceof Byte) {
             buf.append("new Byte((byte)").append(cst).append(')');
         } else if (cst instanceof Boolean) {
-            buf.append(((Boolean) cst).booleanValue() ? "Boolean.TRUE" : "Boolean.FALSE");
+            buf.append(((Boolean) cst).booleanValue() ? "Boolean.TRUE"
+                    : "Boolean.FALSE");
         } else if (cst instanceof Short) {
             buf.append("new Short((short)").append(cst).append(')');
         } else if (cst instanceof Character) {
@@ -1155,8 +1163,7 @@
             char[] v = (char[]) cst;
             buf.append("new char[] {");
             for (int i = 0; i < v.length; i++) {
-                buf.append(i == 0 ? "" : ",")
-                        .append("(char)")
+                buf.append(i == 0 ? "" : ",").append("(char)")
                         .append((int) v[i]);
             }
             buf.append('}');
@@ -1208,27 +1215,27 @@
                 appendConstant(o[i]);
             } else if (o[i] instanceof Integer) {
                 switch (((Integer) o[i]).intValue()) {
-                    case 0:
-                        buf.append("Opcodes.TOP");
-                        break;
-                    case 1:
-                        buf.append("Opcodes.INTEGER");
-                        break;
-                    case 2:
-                        buf.append("Opcodes.FLOAT");
-                        break;
-                    case 3:
-                        buf.append("Opcodes.DOUBLE");
-                        break;
-                    case 4:
-                        buf.append("Opcodes.LONG");
-                        break;
-                    case 5:
-                        buf.append("Opcodes.NULL");
-                        break;
-                    case 6:
-                        buf.append("Opcodes.UNINITIALIZED_THIS");
-                        break;
+                case 0:
+                    buf.append("Opcodes.TOP");
+                    break;
+                case 1:
+                    buf.append("Opcodes.INTEGER");
+                    break;
+                case 2:
+                    buf.append("Opcodes.FLOAT");
+                    break;
+                case 3:
+                    buf.append("Opcodes.DOUBLE");
+                    break;
+                case 4:
+                    buf.append("Opcodes.LONG");
+                    break;
+                case 5:
+                    buf.append("Opcodes.NULL");
+                    break;
+                case 6:
+                    buf.append("Opcodes.UNINITIALIZED_THIS");
+                    break;
                 }
             } else {
                 appendLabel((Label) o[i]);
@@ -1241,7 +1248,8 @@
      * declaration is of the form "Label lXXX = new Label();". Does nothing if
      * the given label has already been declared.
      *
-     * @param l a label.
+     * @param l
+     *            a label.
      */
     protected void declareLabel(final Label l) {
         if (labelNames == null) {
@@ -1257,10 +1265,11 @@
 
     /**
      * Appends the name of the given label to {@link #buf buf}. The given label
-     * <i>must</i> already have a name. One way to ensure this is to always
-     * call {@link #declareLabel declared} before calling this method.
+     * <i>must</i> already have a name. One way to ensure this is to always call
+     * {@link #declareLabel declared} before calling this method.
      *
-     * @param l a label.
+     * @param l
+     *            a label.
      */
     protected void appendLabel(final Label l) {
         buf.append(labelNames.get(l));
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckAnnotationAdapter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckAnnotationAdapter.java
index eacb35d..3650e37 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckAnnotationAdapter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckAnnotationAdapter.java
@@ -78,7 +78,7 @@
     }
 
     CheckAnnotationAdapter(final AnnotationVisitor av, final boolean named) {
-        super(Opcodes.ASM4, av);
+        super(Opcodes.ASM5, av);
         this.named = named;
     }
 
@@ -94,8 +94,7 @@
                 || value instanceof byte[] || value instanceof boolean[]
                 || value instanceof char[] || value instanceof short[]
                 || value instanceof int[] || value instanceof long[]
-                || value instanceof float[] || value instanceof double[]))
-        {
+                || value instanceof float[] || value instanceof double[])) {
             throw new IllegalArgumentException("Invalid annotation value");
         }
         if (value instanceof Type) {
@@ -110,11 +109,8 @@
     }
 
     @Override
-    public void visitEnum(
-        final String name,
-        final String desc,
-        final String value)
-    {
+    public void visitEnum(final String name, final String desc,
+            final String value) {
         checkEnd();
         checkName(name);
         CheckMethodAdapter.checkDesc(desc, false);
@@ -127,15 +123,12 @@
     }
 
     @Override
-    public AnnotationVisitor visitAnnotation(
-        final String name,
-        final String desc)
-    {
+    public AnnotationVisitor visitAnnotation(final String name,
+            final String desc) {
         checkEnd();
         checkName(name);
         CheckMethodAdapter.checkDesc(desc, false);
-        return new CheckAnnotationAdapter(av == null
-                ? null
+        return new CheckAnnotationAdapter(av == null ? null
                 : av.visitAnnotation(name, desc));
     }
 
@@ -143,8 +136,7 @@
     public AnnotationVisitor visitArray(final String name) {
         checkEnd();
         checkName(name);
-        return new CheckAnnotationAdapter(av == null
-                ? null
+        return new CheckAnnotationAdapter(av == null ? null
                 : av.visitArray(name), false);
     }
 
@@ -159,13 +151,15 @@
 
     private void checkEnd() {
         if (end) {
-            throw new IllegalStateException("Cannot call a visit method after visitEnd has been called");
+            throw new IllegalStateException(
+                    "Cannot call a visit method after visitEnd has been called");
         }
     }
 
     private void checkName(final String name) {
         if (named && name == null) {
-            throw new IllegalArgumentException("Annotation value name must not be null");
+            throw new IllegalArgumentException(
+                    "Annotation value name must not be null");
         }
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java
index 59fb514..ad29ab9 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java
@@ -75,6 +75,8 @@
 import jdk.internal.org.objectweb.asm.MethodVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.Type;
+import jdk.internal.org.objectweb.asm.TypePath;
+import jdk.internal.org.objectweb.asm.TypeReference;
 import jdk.internal.org.objectweb.asm.tree.ClassNode;
 import jdk.internal.org.objectweb.asm.tree.MethodNode;
 import jdk.internal.org.objectweb.asm.tree.analysis.Analyzer;
@@ -88,10 +90,10 @@
  * <i>only</i> on its arguments, but does <i>not</i> check the <i>sequence</i>
  * of method calls. For example, the invalid sequence
  * <tt>visitField(ACC_PUBLIC, "i", "I", null)</tt> <tt>visitField(ACC_PUBLIC,
- * "i", "D", null)</tt>
- * will <i>not</i> be detected by this class adapter.
+ * "i", "D", null)</tt> will <i>not</i> be detected by this class adapter.
  *
- * <p><code>CheckClassAdapter</code> can be also used to verify bytecode
+ * <p>
+ * <code>CheckClassAdapter</code> can be also used to verify bytecode
  * transformations in order to make sure transformed bytecode is sane. For
  * example:
  *
@@ -109,11 +111,12 @@
  * </pre>
  *
  * Above code runs transformed bytecode trough the
- * <code>CheckClassAdapter</code>. It won't be exactly the same verification
- * as JVM does, but it run data flow analysis for the code of each method and
+ * <code>CheckClassAdapter</code>. It won't be exactly the same verification as
+ * JVM does, but it run data flow analysis for the code of each method and
  * checks that expectations are met for each method instruction.
  *
- * <p>If method bytecode has errors, assertion text will show the erroneous
+ * <p>
+ * If method bytecode has errors, assertion text will show the erroneous
  * instruction number and dump of the failed method with information about
  * locals and stack slot for each instruction. For example (format is -
  * insnNumber locals : stack):
@@ -134,7 +137,7 @@
  * 00071 LinkedBlockingQueue$Itr <b>.</b> I . . . . . .  :
  *   ILOAD 1
  * 00072 <b>?</b>
- *   INVOKESPECIAL java/lang/Integer.<init> (I)V
+ *   INVOKESPECIAL java/lang/Integer.&lt;init&gt; (I)V
  * ...
  * </pre>
  *
@@ -143,8 +146,9 @@
  * initialized. You can also see that at the beginning of the method (code
  * inserted by the transformation) variable 2 is initialized.
  *
- * <p>Note that when used like that, <code>CheckClassAdapter.verify()</code>
- * can trigger additional class loading, because it is using
+ * <p>
+ * Note that when used like that, <code>CheckClassAdapter.verify()</code> can
+ * trigger additional class loading, because it is using
  * <code>SimpleVerifier</code>.
  *
  * @author Eric Bruneton
@@ -188,13 +192,15 @@
     private boolean checkDataFlow;
 
     /**
-     * Checks a given class. <p> Usage: CheckClassAdapter &lt;binary
-     * class name or class file name&gt;
+     * Checks a given class.
+     * <p>
+     * Usage: CheckClassAdapter &lt;binary class name or class file name&gt;
      *
-     * @param args the command line arguments.
+     * @param args
+     *            the command line arguments.
      *
-     * @throws Exception if the class cannot be found, or if an IO exception
-     *         occurs.
+     * @throws Exception
+     *             if the class cannot be found, or if an IO exception occurs.
      */
     public static void main(final String[] args) throws Exception {
         if (args.length != 1) {
@@ -216,27 +222,26 @@
     /**
      * Checks a given class.
      *
-     * @param cr a <code>ClassReader</code> that contains bytecode for the
-     *        analysis.
-     * @param loader a <code>ClassLoader</code> which will be used to load
-     *        referenced classes. This is useful if you are verifiying multiple
-     *        interdependent classes.
-     * @param dump true if bytecode should be printed out not only when errors
-     *        are found.
-     * @param pw write where results going to be printed
+     * @param cr
+     *            a <code>ClassReader</code> that contains bytecode for the
+     *            analysis.
+     * @param loader
+     *            a <code>ClassLoader</code> which will be used to load
+     *            referenced classes. This is useful if you are verifiying
+     *            multiple interdependent classes.
+     * @param dump
+     *            true if bytecode should be printed out not only when errors
+     *            are found.
+     * @param pw
+     *            write where results going to be printed
      */
-    public static void verify(
-        final ClassReader cr,
-        final ClassLoader loader,
-        final boolean dump,
-        final PrintWriter pw)
-    {
+    public static void verify(final ClassReader cr, final ClassLoader loader,
+            final boolean dump, final PrintWriter pw) {
         ClassNode cn = new ClassNode();
         cr.accept(new CheckClassAdapter(cn, false), ClassReader.SKIP_DEBUG);
 
-        Type syperType = cn.superName == null
-                ? null
-                : Type.getObjectType(cn.superName);
+        Type syperType = cn.superName == null ? null : Type
+                .getObjectType(cn.superName);
         List<MethodNode> methods = cn.methods;
 
         List<Type> interfaces = new ArrayList<Type>();
@@ -246,9 +251,8 @@
 
         for (int i = 0; i < methods.size(); ++i) {
             MethodNode method = methods.get(i);
-            SimpleVerifier verifier = new SimpleVerifier(Type.getObjectType(cn.name),
-                    syperType,
-                    interfaces,
+            SimpleVerifier verifier = new SimpleVerifier(
+                    Type.getObjectType(cn.name), syperType, interfaces,
                     (cn.access & Opcodes.ACC_INTERFACE) != 0);
             Analyzer<BasicValue> a = new Analyzer<BasicValue>(verifier);
             if (loader != null) {
@@ -270,25 +274,22 @@
     /**
      * Checks a given class
      *
-     * @param cr a <code>ClassReader</code> that contains bytecode for the
-     *        analysis.
-     * @param dump true if bytecode should be printed out not only when errors
-     *        are found.
-     * @param pw write where results going to be printed
+     * @param cr
+     *            a <code>ClassReader</code> that contains bytecode for the
+     *            analysis.
+     * @param dump
+     *            true if bytecode should be printed out not only when errors
+     *            are found.
+     * @param pw
+     *            write where results going to be printed
      */
-    public static void verify(
-        final ClassReader cr,
-        final boolean dump,
-        final PrintWriter pw)
-    {
+    public static void verify(final ClassReader cr, final boolean dump,
+            final PrintWriter pw) {
         verify(cr, null, dump, pw);
     }
 
-    static void printAnalyzerResult(
-        MethodNode method,
-        Analyzer<BasicValue> a,
-        final PrintWriter pw)
-    {
+    static void printAnalyzerResult(MethodNode method, Analyzer<BasicValue> a,
+            final PrintWriter pw) {
         Frame<BasicValue>[] frames = a.getFrames();
         Textifier t = new Textifier();
         TraceMethodVisitor mv = new TraceMethodVisitor(t);
@@ -339,7 +340,8 @@
      * this constructor</i>. Instead, they must use the
      * {@link #CheckClassAdapter(int, ClassVisitor, boolean)} version.
      *
-     * @param cv the class visitor to which this adapter must delegate calls.
+     * @param cv
+     *            the class visitor to which this adapter must delegate calls.
      */
     public CheckClassAdapter(final ClassVisitor cv) {
         this(cv, true);
@@ -350,33 +352,34 @@
      * this constructor</i>. Instead, they must use the
      * {@link #CheckClassAdapter(int, ClassVisitor, boolean)} version.
      *
-     * @param cv the class visitor to which this adapter must delegate calls.
-     * @param checkDataFlow <tt>true</tt> to perform basic data flow checks, or
-     *        <tt>false</tt> to not perform any data flow check (see
-     *        {@link CheckMethodAdapter}). This option requires valid maxLocals
-     *        and maxStack values.
+     * @param cv
+     *            the class visitor to which this adapter must delegate calls.
+     * @param checkDataFlow
+     *            <tt>true</tt> to perform basic data flow checks, or
+     *            <tt>false</tt> to not perform any data flow check (see
+     *            {@link CheckMethodAdapter}). This option requires valid
+     *            maxLocals and maxStack values.
      */
-    public CheckClassAdapter(final ClassVisitor cv, final boolean checkDataFlow)
-    {
-        this(Opcodes.ASM4, cv, checkDataFlow);
+    public CheckClassAdapter(final ClassVisitor cv, final boolean checkDataFlow) {
+        this(Opcodes.ASM5, cv, checkDataFlow);
     }
 
     /**
      * Constructs a new {@link CheckClassAdapter}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
-     * @param cv the class visitor to which this adapter must delegate calls.
-     * @param checkDataFlow <tt>true</tt> to perform basic data flow checks, or
-     *        <tt>false</tt> to not perform any data flow check (see
-     *        {@link CheckMethodAdapter}). This option requires valid maxLocals
-     *        and maxStack values.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param cv
+     *            the class visitor to which this adapter must delegate calls.
+     * @param checkDataFlow
+     *            <tt>true</tt> to perform basic data flow checks, or
+     *            <tt>false</tt> to not perform any data flow check (see
+     *            {@link CheckMethodAdapter}). This option requires valid
+     *            maxLocals and maxStack values.
      */
-    protected CheckClassAdapter(
-        final int api,
-        final ClassVisitor cv,
-        final boolean checkDataFlow)
-    {
+    protected CheckClassAdapter(final int api, final ClassVisitor cv,
+            final boolean checkDataFlow) {
         super(api, cv);
         this.labels = new HashMap<Label, Integer>();
         this.checkDataFlow = checkDataFlow;
@@ -387,14 +390,9 @@
     // ------------------------------------------------------------------------
 
     @Override
-    public void visit(
-        final int version,
-        final int access,
-        final String name,
-        final String signature,
-        final String superName,
-        final String[] interfaces)
-    {
+    public void visit(final int version, final int access, final String name,
+            final String signature, final String superName,
+            final String[] interfaces) {
         if (start) {
             throw new IllegalStateException("visit must be called only once");
         }
@@ -404,24 +402,25 @@
                 + Opcodes.ACC_SUPER + Opcodes.ACC_INTERFACE
                 + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC
                 + Opcodes.ACC_ANNOTATION + Opcodes.ACC_ENUM
-                + Opcodes.ACC_DEPRECATED
-                + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
+                + Opcodes.ACC_DEPRECATED + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
         if (name == null || !name.endsWith("package-info")) {
             CheckMethodAdapter.checkInternalName(name, "class name");
         }
         if ("java/lang/Object".equals(name)) {
             if (superName != null) {
-                throw new IllegalArgumentException("The super class name of the Object class must be 'null'");
+                throw new IllegalArgumentException(
+                        "The super class name of the Object class must be 'null'");
             }
         } else {
             CheckMethodAdapter.checkInternalName(superName, "super class name");
         }
         if (signature != null) {
-            CheckMethodAdapter.checkClassSignature(signature);
+            checkClassSignature(signature);
         }
         if ((access & Opcodes.ACC_INTERFACE) != 0) {
             if (!"java/lang/Object".equals(superName)) {
-                throw new IllegalArgumentException("The super class name of interfaces must be 'java/lang/Object'");
+                throw new IllegalArgumentException(
+                        "The super class name of interfaces must be 'java/lang/Object'");
             }
         }
         if (interfaces != null) {
@@ -438,21 +437,20 @@
     public void visitSource(final String file, final String debug) {
         checkState();
         if (source) {
-            throw new IllegalStateException("visitSource can be called only once.");
+            throw new IllegalStateException(
+                    "visitSource can be called only once.");
         }
         source = true;
         super.visitSource(file, debug);
     }
 
     @Override
-    public void visitOuterClass(
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitOuterClass(final String owner, final String name,
+            final String desc) {
         checkState();
         if (outer) {
-            throw new IllegalStateException("visitOuterClass can be called only once.");
+            throw new IllegalStateException(
+                    "visitOuterClass can be called only once.");
         }
         outer = true;
         if (owner == null) {
@@ -465,12 +463,8 @@
     }
 
     @Override
-    public void visitInnerClass(
-        final String name,
-        final String outerName,
-        final String innerName,
-        final int access)
-    {
+    public void visitInnerClass(final String name, final String outerName,
+            final String innerName, final int access) {
         checkState();
         CheckMethodAdapter.checkInternalName(name, "class name");
         if (outerName != null) {
@@ -488,52 +482,44 @@
     }
 
     @Override
-    public FieldVisitor visitField(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final Object value)
-    {
+    public FieldVisitor visitField(final int access, final String name,
+            final String desc, final String signature, final Object value) {
         checkState();
         checkAccess(access, Opcodes.ACC_PUBLIC + Opcodes.ACC_PRIVATE
                 + Opcodes.ACC_PROTECTED + Opcodes.ACC_STATIC
                 + Opcodes.ACC_FINAL + Opcodes.ACC_VOLATILE
                 + Opcodes.ACC_TRANSIENT + Opcodes.ACC_SYNTHETIC
-                + Opcodes.ACC_ENUM + Opcodes.ACC_DEPRECATED
-                + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
+                + Opcodes.ACC_ENUM + Opcodes.ACC_DEPRECATED + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
         CheckMethodAdapter.checkUnqualifiedName(version, name, "field name");
         CheckMethodAdapter.checkDesc(desc, false);
         if (signature != null) {
-            CheckMethodAdapter.checkFieldSignature(signature);
+            checkFieldSignature(signature);
         }
         if (value != null) {
             CheckMethodAdapter.checkConstant(value);
         }
-        FieldVisitor av = super.visitField(access, name, desc, signature, value);
+        FieldVisitor av = super
+                .visitField(access, name, desc, signature, value);
         return new CheckFieldAdapter(av);
     }
 
     @Override
-    public MethodVisitor visitMethod(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final String[] exceptions)
-    {
+    public MethodVisitor visitMethod(final int access, final String name,
+            final String desc, final String signature, final String[] exceptions) {
         checkState();
         checkAccess(access, Opcodes.ACC_PUBLIC + Opcodes.ACC_PRIVATE
                 + Opcodes.ACC_PROTECTED + Opcodes.ACC_STATIC
                 + Opcodes.ACC_FINAL + Opcodes.ACC_SYNCHRONIZED
                 + Opcodes.ACC_BRIDGE + Opcodes.ACC_VARARGS + Opcodes.ACC_NATIVE
                 + Opcodes.ACC_ABSTRACT + Opcodes.ACC_STRICT
-                + Opcodes.ACC_SYNTHETIC + Opcodes.ACC_DEPRECATED
-                + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
-        CheckMethodAdapter.checkMethodIdentifier(version, name, "method name");
+                + Opcodes.ACC_SYNTHETIC + Opcodes.ACC_DEPRECATED + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
+        if (!"<init>".equals(name) && !"<clinit>".equals(name)) {
+            CheckMethodAdapter.checkMethodIdentifier(version, name,
+                    "method name");
+        }
         CheckMethodAdapter.checkMethodDesc(desc);
         if (signature != null) {
-            CheckMethodAdapter.checkMethodSignature(signature);
+            checkMethodSignature(signature);
         }
         if (exceptions != null) {
             for (int i = 0; i < exceptions.length; ++i) {
@@ -543,37 +529,47 @@
         }
         CheckMethodAdapter cma;
         if (checkDataFlow) {
-            cma = new CheckMethodAdapter(access,
-                    name,
-                    desc,
-                    super.visitMethod(access, name, desc, signature, exceptions),
-                    labels);
+            cma = new CheckMethodAdapter(access, name, desc, super.visitMethod(
+                    access, name, desc, signature, exceptions), labels);
         } else {
-            cma = new CheckMethodAdapter(super.visitMethod(access,
-                    name,
-                    desc,
-                    signature,
-                    exceptions), labels);
+            cma = new CheckMethodAdapter(super.visitMethod(access, name, desc,
+                    signature, exceptions), labels);
         }
         cma.version = version;
         return cma;
     }
 
     @Override
-    public AnnotationVisitor visitAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public AnnotationVisitor visitAnnotation(final String desc,
+            final boolean visible) {
         checkState();
         CheckMethodAdapter.checkDesc(desc, false);
         return new CheckAnnotationAdapter(super.visitAnnotation(desc, visible));
     }
 
     @Override
+    public AnnotationVisitor visitTypeAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        checkState();
+        int sort = typeRef >>> 24;
+        if (sort != TypeReference.CLASS_TYPE_PARAMETER
+                && sort != TypeReference.CLASS_TYPE_PARAMETER_BOUND
+                && sort != TypeReference.CLASS_EXTENDS) {
+            throw new IllegalArgumentException("Invalid type reference sort 0x"
+                    + Integer.toHexString(sort));
+        }
+        checkTypeRefAndPath(typeRef, typePath);
+        CheckMethodAdapter.checkDesc(desc, false);
+        return new CheckAnnotationAdapter(super.visitTypeAnnotation(typeRef,
+                typePath, desc, visible));
+    }
+
+    @Override
     public void visitAttribute(final Attribute attr) {
         checkState();
         if (attr == null) {
-            throw new IllegalArgumentException("Invalid attribute (must not be null)");
+            throw new IllegalArgumentException(
+                    "Invalid attribute (must not be null)");
         }
         super.visitAttribute(attr);
     }
@@ -595,10 +591,12 @@
      */
     private void checkState() {
         if (!start) {
-            throw new IllegalStateException("Cannot visit member before visit has been called.");
+            throw new IllegalStateException(
+                    "Cannot visit member before visit has been called.");
         }
         if (end) {
-            throw new IllegalStateException("Cannot visit member after visitEnd has been called.");
+            throw new IllegalStateException(
+                    "Cannot visit member after visitEnd has been called.");
         }
     }
 
@@ -607,8 +605,10 @@
      * method also checks that mutually incompatible flags are not set
      * simultaneously.
      *
-     * @param access the access flags to be checked
-     * @param possibleAccess the valid access flags.
+     * @param access
+     *            the access flags to be checked
+     * @param possibleAccess
+     *            the valid access flags.
      */
     static void checkAccess(final int access, final int possibleAccess) {
         if ((access & ~possibleAccess) != 0) {
@@ -619,14 +619,407 @@
         int pri = (access & Opcodes.ACC_PRIVATE) == 0 ? 0 : 1;
         int pro = (access & Opcodes.ACC_PROTECTED) == 0 ? 0 : 1;
         if (pub + pri + pro > 1) {
-            throw new IllegalArgumentException("public private and protected are mutually exclusive: "
-                    + access);
+            throw new IllegalArgumentException(
+                    "public private and protected are mutually exclusive: "
+                            + access);
         }
         int fin = (access & Opcodes.ACC_FINAL) == 0 ? 0 : 1;
         int abs = (access & Opcodes.ACC_ABSTRACT) == 0 ? 0 : 1;
         if (fin + abs > 1) {
-            throw new IllegalArgumentException("final and abstract are mutually exclusive: "
-                    + access);
+            throw new IllegalArgumentException(
+                    "final and abstract are mutually exclusive: " + access);
         }
     }
+
+    /**
+     * Checks a class signature.
+     *
+     * @param signature
+     *            a string containing the signature that must be checked.
+     */
+    public static void checkClassSignature(final String signature) {
+        // ClassSignature:
+        // FormalTypeParameters? ClassTypeSignature ClassTypeSignature*
+
+        int pos = 0;
+        if (getChar(signature, 0) == '<') {
+            pos = checkFormalTypeParameters(signature, pos);
+        }
+        pos = checkClassTypeSignature(signature, pos);
+        while (getChar(signature, pos) == 'L') {
+            pos = checkClassTypeSignature(signature, pos);
+        }
+        if (pos != signature.length()) {
+            throw new IllegalArgumentException(signature + ": error at index "
+                    + pos);
+        }
+    }
+
+    /**
+     * Checks a method signature.
+     *
+     * @param signature
+     *            a string containing the signature that must be checked.
+     */
+    public static void checkMethodSignature(final String signature) {
+        // MethodTypeSignature:
+        // FormalTypeParameters? ( TypeSignature* ) ( TypeSignature | V ) (
+        // ^ClassTypeSignature | ^TypeVariableSignature )*
+
+        int pos = 0;
+        if (getChar(signature, 0) == '<') {
+            pos = checkFormalTypeParameters(signature, pos);
+        }
+        pos = checkChar('(', signature, pos);
+        while ("ZCBSIFJDL[T".indexOf(getChar(signature, pos)) != -1) {
+            pos = checkTypeSignature(signature, pos);
+        }
+        pos = checkChar(')', signature, pos);
+        if (getChar(signature, pos) == 'V') {
+            ++pos;
+        } else {
+            pos = checkTypeSignature(signature, pos);
+        }
+        while (getChar(signature, pos) == '^') {
+            ++pos;
+            if (getChar(signature, pos) == 'L') {
+                pos = checkClassTypeSignature(signature, pos);
+            } else {
+                pos = checkTypeVariableSignature(signature, pos);
+            }
+        }
+        if (pos != signature.length()) {
+            throw new IllegalArgumentException(signature + ": error at index "
+                    + pos);
+        }
+    }
+
+    /**
+     * Checks a field signature.
+     *
+     * @param signature
+     *            a string containing the signature that must be checked.
+     */
+    public static void checkFieldSignature(final String signature) {
+        int pos = checkFieldTypeSignature(signature, 0);
+        if (pos != signature.length()) {
+            throw new IllegalArgumentException(signature + ": error at index "
+                    + pos);
+        }
+    }
+
+    /**
+     * Checks the reference to a type in a type annotation.
+     *
+     * @param typeRef
+     *            a reference to an annotated type.
+     * @param typePath
+     *            the path to the annotated type argument, wildcard bound, array
+     *            element type, or static inner type within 'typeRef'. May be
+     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
+     */
+    static void checkTypeRefAndPath(int typeRef, TypePath typePath) {
+        int mask = 0;
+        switch (typeRef >>> 24) {
+        case TypeReference.CLASS_TYPE_PARAMETER:
+        case TypeReference.METHOD_TYPE_PARAMETER:
+        case TypeReference.METHOD_FORMAL_PARAMETER:
+            mask = 0xFFFF0000;
+            break;
+        case TypeReference.FIELD:
+        case TypeReference.METHOD_RETURN:
+        case TypeReference.METHOD_RECEIVER:
+        case TypeReference.LOCAL_VARIABLE:
+        case TypeReference.RESOURCE_VARIABLE:
+        case TypeReference.INSTANCEOF:
+        case TypeReference.NEW:
+        case TypeReference.CONSTRUCTOR_REFERENCE:
+        case TypeReference.METHOD_REFERENCE:
+            mask = 0xFF000000;
+            break;
+        case TypeReference.CLASS_EXTENDS:
+        case TypeReference.CLASS_TYPE_PARAMETER_BOUND:
+        case TypeReference.METHOD_TYPE_PARAMETER_BOUND:
+        case TypeReference.THROWS:
+        case TypeReference.EXCEPTION_PARAMETER:
+            mask = 0xFFFFFF00;
+            break;
+        case TypeReference.CAST:
+        case TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
+        case TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT:
+        case TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
+        case TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT:
+            mask = 0xFF0000FF;
+            break;
+        default:
+            throw new IllegalArgumentException("Invalid type reference sort 0x"
+                    + Integer.toHexString(typeRef >>> 24));
+        }
+        if ((typeRef & ~mask) != 0) {
+            throw new IllegalArgumentException("Invalid type reference 0x"
+                    + Integer.toHexString(typeRef));
+        }
+        if (typePath != null) {
+            for (int i = 0; i < typePath.getLength(); ++i) {
+                int step = typePath.getStep(i);
+                if (step != TypePath.ARRAY_ELEMENT
+                        && step != TypePath.INNER_TYPE
+                        && step != TypePath.TYPE_ARGUMENT
+                        && step != TypePath.WILDCARD_BOUND) {
+                    throw new IllegalArgumentException(
+                            "Invalid type path step " + i + " in " + typePath);
+                }
+                if (step != TypePath.TYPE_ARGUMENT
+                        && typePath.getStepArgument(i) != 0) {
+                    throw new IllegalArgumentException(
+                            "Invalid type path step argument for step " + i
+                                    + " in " + typePath);
+                }
+            }
+        }
+    }
+
+    /**
+     * Checks the formal type parameters of a class or method signature.
+     *
+     * @param signature
+     *            a string containing the signature that must be checked.
+     * @param pos
+     *            index of first character to be checked.
+     * @return the index of the first character after the checked part.
+     */
+    private static int checkFormalTypeParameters(final String signature, int pos) {
+        // FormalTypeParameters:
+        // < FormalTypeParameter+ >
+
+        pos = checkChar('<', signature, pos);
+        pos = checkFormalTypeParameter(signature, pos);
+        while (getChar(signature, pos) != '>') {
+            pos = checkFormalTypeParameter(signature, pos);
+        }
+        return pos + 1;
+    }
+
+    /**
+     * Checks a formal type parameter of a class or method signature.
+     *
+     * @param signature
+     *            a string containing the signature that must be checked.
+     * @param pos
+     *            index of first character to be checked.
+     * @return the index of the first character after the checked part.
+     */
+    private static int checkFormalTypeParameter(final String signature, int pos) {
+        // FormalTypeParameter:
+        // Identifier : FieldTypeSignature? (: FieldTypeSignature)*
+
+        pos = checkIdentifier(signature, pos);
+        pos = checkChar(':', signature, pos);
+        if ("L[T".indexOf(getChar(signature, pos)) != -1) {
+            pos = checkFieldTypeSignature(signature, pos);
+        }
+        while (getChar(signature, pos) == ':') {
+            pos = checkFieldTypeSignature(signature, pos + 1);
+        }
+        return pos;
+    }
+
+    /**
+     * Checks a field type signature.
+     *
+     * @param signature
+     *            a string containing the signature that must be checked.
+     * @param pos
+     *            index of first character to be checked.
+     * @return the index of the first character after the checked part.
+     */
+    private static int checkFieldTypeSignature(final String signature, int pos) {
+        // FieldTypeSignature:
+        // ClassTypeSignature | ArrayTypeSignature | TypeVariableSignature
+        //
+        // ArrayTypeSignature:
+        // [ TypeSignature
+
+        switch (getChar(signature, pos)) {
+        case 'L':
+            return checkClassTypeSignature(signature, pos);
+        case '[':
+            return checkTypeSignature(signature, pos + 1);
+        default:
+            return checkTypeVariableSignature(signature, pos);
+        }
+    }
+
+    /**
+     * Checks a class type signature.
+     *
+     * @param signature
+     *            a string containing the signature that must be checked.
+     * @param pos
+     *            index of first character to be checked.
+     * @return the index of the first character after the checked part.
+     */
+    private static int checkClassTypeSignature(final String signature, int pos) {
+        // ClassTypeSignature:
+        // L Identifier ( / Identifier )* TypeArguments? ( . Identifier
+        // TypeArguments? )* ;
+
+        pos = checkChar('L', signature, pos);
+        pos = checkIdentifier(signature, pos);
+        while (getChar(signature, pos) == '/') {
+            pos = checkIdentifier(signature, pos + 1);
+        }
+        if (getChar(signature, pos) == '<') {
+            pos = checkTypeArguments(signature, pos);
+        }
+        while (getChar(signature, pos) == '.') {
+            pos = checkIdentifier(signature, pos + 1);
+            if (getChar(signature, pos) == '<') {
+                pos = checkTypeArguments(signature, pos);
+            }
+        }
+        return checkChar(';', signature, pos);
+    }
+
+    /**
+     * Checks the type arguments in a class type signature.
+     *
+     * @param signature
+     *            a string containing the signature that must be checked.
+     * @param pos
+     *            index of first character to be checked.
+     * @return the index of the first character after the checked part.
+     */
+    private static int checkTypeArguments(final String signature, int pos) {
+        // TypeArguments:
+        // < TypeArgument+ >
+
+        pos = checkChar('<', signature, pos);
+        pos = checkTypeArgument(signature, pos);
+        while (getChar(signature, pos) != '>') {
+            pos = checkTypeArgument(signature, pos);
+        }
+        return pos + 1;
+    }
+
+    /**
+     * Checks a type argument in a class type signature.
+     *
+     * @param signature
+     *            a string containing the signature that must be checked.
+     * @param pos
+     *            index of first character to be checked.
+     * @return the index of the first character after the checked part.
+     */
+    private static int checkTypeArgument(final String signature, int pos) {
+        // TypeArgument:
+        // * | ( ( + | - )? FieldTypeSignature )
+
+        char c = getChar(signature, pos);
+        if (c == '*') {
+            return pos + 1;
+        } else if (c == '+' || c == '-') {
+            pos++;
+        }
+        return checkFieldTypeSignature(signature, pos);
+    }
+
+    /**
+     * Checks a type variable signature.
+     *
+     * @param signature
+     *            a string containing the signature that must be checked.
+     * @param pos
+     *            index of first character to be checked.
+     * @return the index of the first character after the checked part.
+     */
+    private static int checkTypeVariableSignature(final String signature,
+            int pos) {
+        // TypeVariableSignature:
+        // T Identifier ;
+
+        pos = checkChar('T', signature, pos);
+        pos = checkIdentifier(signature, pos);
+        return checkChar(';', signature, pos);
+    }
+
+    /**
+     * Checks a type signature.
+     *
+     * @param signature
+     *            a string containing the signature that must be checked.
+     * @param pos
+     *            index of first character to be checked.
+     * @return the index of the first character after the checked part.
+     */
+    private static int checkTypeSignature(final String signature, int pos) {
+        // TypeSignature:
+        // Z | C | B | S | I | F | J | D | FieldTypeSignature
+
+        switch (getChar(signature, pos)) {
+        case 'Z':
+        case 'C':
+        case 'B':
+        case 'S':
+        case 'I':
+        case 'F':
+        case 'J':
+        case 'D':
+            return pos + 1;
+        default:
+            return checkFieldTypeSignature(signature, pos);
+        }
+    }
+
+    /**
+     * Checks an identifier.
+     *
+     * @param signature
+     *            a string containing the signature that must be checked.
+     * @param pos
+     *            index of first character to be checked.
+     * @return the index of the first character after the checked part.
+     */
+    private static int checkIdentifier(final String signature, int pos) {
+        if (!Character.isJavaIdentifierStart(getChar(signature, pos))) {
+            throw new IllegalArgumentException(signature
+                    + ": identifier expected at index " + pos);
+        }
+        ++pos;
+        while (Character.isJavaIdentifierPart(getChar(signature, pos))) {
+            ++pos;
+        }
+        return pos;
+    }
+
+    /**
+     * Checks a single character.
+     *
+     * @param signature
+     *            a string containing the signature that must be checked.
+     * @param pos
+     *            index of first character to be checked.
+     * @return the index of the first character after the checked part.
+     */
+    private static int checkChar(final char c, final String signature, int pos) {
+        if (getChar(signature, pos) == c) {
+            return pos + 1;
+        }
+        throw new IllegalArgumentException(signature + ": '" + c
+                + "' expected at index " + pos);
+    }
+
+    /**
+     * Returns the signature car at the given index.
+     *
+     * @param signature
+     *            a signature.
+     * @param pos
+     *            an index in signature.
+     * @return the character at the given index, or 0 if there is no such
+     *         character.
+     */
+    private static char getChar(final String signature, int pos) {
+        return pos < signature.length() ? signature.charAt(pos) : (char) 0;
+    }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckFieldAdapter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckFieldAdapter.java
index 868991e..b09559c 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckFieldAdapter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckFieldAdapter.java
@@ -62,6 +62,8 @@
 import jdk.internal.org.objectweb.asm.Attribute;
 import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.TypePath;
+import jdk.internal.org.objectweb.asm.TypeReference;
 
 /**
  * A {@link FieldVisitor} that checks that its methods are properly used.
@@ -75,38 +77,55 @@
      * this constructor</i>. Instead, they must use the
      * {@link #CheckFieldAdapter(int, FieldVisitor)} version.
      *
-     * @param fv the field visitor to which this adapter must delegate calls.
+     * @param fv
+     *            the field visitor to which this adapter must delegate calls.
      */
     public CheckFieldAdapter(final FieldVisitor fv) {
-        this(Opcodes.ASM4, fv);
+        this(Opcodes.ASM5, fv);
     }
 
     /**
      * Constructs a new {@link CheckFieldAdapter}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
-     * @param fv the field visitor to which this adapter must delegate calls.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param fv
+     *            the field visitor to which this adapter must delegate calls.
      */
     protected CheckFieldAdapter(final int api, final FieldVisitor fv) {
         super(api, fv);
     }
 
     @Override
-    public AnnotationVisitor visitAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public AnnotationVisitor visitAnnotation(final String desc,
+            final boolean visible) {
         checkEnd();
         CheckMethodAdapter.checkDesc(desc, false);
         return new CheckAnnotationAdapter(super.visitAnnotation(desc, visible));
     }
 
     @Override
+    public AnnotationVisitor visitTypeAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        checkEnd();
+        int sort = typeRef >>> 24;
+        if (sort != TypeReference.FIELD) {
+            throw new IllegalArgumentException("Invalid type reference sort 0x"
+                    + Integer.toHexString(sort));
+        }
+        CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath);
+        CheckMethodAdapter.checkDesc(desc, false);
+        return new CheckAnnotationAdapter(super.visitTypeAnnotation(typeRef,
+                typePath, desc, visible));
+    }
+
+    @Override
     public void visitAttribute(final Attribute attr) {
         checkEnd();
         if (attr == null) {
-            throw new IllegalArgumentException("Invalid attribute (must not be null)");
+            throw new IllegalArgumentException(
+                    "Invalid attribute (must not be null)");
         }
         super.visitAttribute(attr);
     }
@@ -120,7 +139,8 @@
 
     private void checkEnd() {
         if (end) {
-            throw new IllegalStateException("Cannot call a visit method after visitEnd has been called");
+            throw new IllegalStateException(
+                    "Cannot call a visit method after visitEnd has been called");
         }
     }
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java
index 51e9262..b597098 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java
@@ -75,6 +75,8 @@
 import jdk.internal.org.objectweb.asm.MethodVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.Type;
+import jdk.internal.org.objectweb.asm.TypePath;
+import jdk.internal.org.objectweb.asm.TypeReference;
 import jdk.internal.org.objectweb.asm.tree.MethodNode;
 import jdk.internal.org.objectweb.asm.tree.analysis.Analyzer;
 import jdk.internal.org.objectweb.asm.tree.analysis.BasicValue;
@@ -104,6 +106,11 @@
     public int version;
 
     /**
+     * The access flags of the method.
+     */
+    private int access;
+
+    /**
      * <tt>true</tt> if the visitCode method has been called.
      */
     private boolean startCode;
@@ -136,6 +143,21 @@
     private Set<Label> usedLabels;
 
     /**
+     * If an explicit first frame has been visited before the first instruction.
+     */
+    private boolean hasExplicitFirstFrame;
+
+    /**
+     * Number of visited frames in expanded form.
+     */
+    private int expandedFrames;
+
+    /**
+     * Number of visited frames in compressed form.
+     */
+    private int compressedFrames;
+
+    /**
      * The exception handler ranges. Each pair of list element contains the
      * start and end labels of an exception handler block.
      */
@@ -381,7 +403,8 @@
      * <i>Subclasses must not use this constructor</i>. Instead, they must use
      * the {@link #CheckMethodAdapter(int, MethodVisitor, Map)} version.
      *
-     * @param mv the method visitor to which this adapter must delegate calls.
+     * @param mv
+     *            the method visitor to which this adapter must delegate calls.
      */
     public CheckMethodAdapter(final MethodVisitor mv) {
         this(mv, new HashMap<Label, Integer>());
@@ -394,14 +417,14 @@
      * <i>Subclasses must not use this constructor</i>. Instead, they must use
      * the {@link #CheckMethodAdapter(int, MethodVisitor, Map)} version.
      *
-     * @param mv the method visitor to which this adapter must delegate calls.
-     * @param labels a map of already visited labels (in other methods).
+     * @param mv
+     *            the method visitor to which this adapter must delegate calls.
+     * @param labels
+     *            a map of already visited labels (in other methods).
      */
-    public CheckMethodAdapter(
-        final MethodVisitor mv,
-        final Map<Label, Integer> labels)
-    {
-        this(Opcodes.ASM4, mv, labels);
+    public CheckMethodAdapter(final MethodVisitor mv,
+            final Map<Label, Integer> labels) {
+        this(Opcodes.ASM5, mv, labels);
     }
 
     /**
@@ -409,14 +432,13 @@
      * will not perform any data flow check (see
      * {@link #CheckMethodAdapter(int,String,String,MethodVisitor,Map)}).
      *
-     * @param mv the method visitor to which this adapter must delegate calls.
-     * @param labels a map of already visited labels (in other methods).
+     * @param mv
+     *            the method visitor to which this adapter must delegate calls.
+     * @param labels
+     *            a map of already visited labels (in other methods).
      */
-    protected CheckMethodAdapter(
-        final int api,
-        final MethodVisitor mv,
-        final Map<Label, Integer> labels)
-    {
+    protected CheckMethodAdapter(final int api, final MethodVisitor mv,
+            final Map<Label, Integer> labels) {
         super(api, mv);
         this.labels = labels;
         this.usedLabels = new HashSet<Label>();
@@ -429,30 +451,32 @@
      * signature is <tt>void m ()</tt>, the invalid instruction IRETURN, or the
      * invalid sequence IADD L2I will be detected.
      *
-     * @param access the method's access flags.
-     * @param name the method's name.
-     * @param desc the method's descriptor (see {@link Type Type}).
-     * @param cmv the method visitor to which this adapter must delegate calls.
-     * @param labels a map of already visited labels (in other methods).
+     * @param access
+     *            the method's access flags.
+     * @param name
+     *            the method's name.
+     * @param desc
+     *            the method's descriptor (see {@link Type Type}).
+     * @param cmv
+     *            the method visitor to which this adapter must delegate calls.
+     * @param labels
+     *            a map of already visited labels (in other methods).
      */
-    public CheckMethodAdapter(
-        final int access,
-        final String name,
-        final String desc,
-        final MethodVisitor cmv,
-        final Map<Label, Integer> labels)
-    {
+    public CheckMethodAdapter(final int access, final String name,
+            final String desc, final MethodVisitor cmv,
+            final Map<Label, Integer> labels) {
         this(new MethodNode(access, name, desc, null, null) {
             @Override
             public void visitEnd() {
-                Analyzer<BasicValue> a = new Analyzer<BasicValue>(new BasicVerifier());
+                Analyzer<BasicValue> a = new Analyzer<BasicValue>(
+                        new BasicVerifier());
                 try {
                     a.analyze("dummy", this);
                 } catch (Exception e) {
                     if (e instanceof IndexOutOfBoundsException
-                            && maxLocals == 0 && maxStack == 0)
-                    {
-                        throw new RuntimeException("Data flow checking option requires valid, non zero maxLocals and maxStack values.");
+                            && maxLocals == 0 && maxStack == 0) {
+                        throw new RuntimeException(
+                                "Data flow checking option requires valid, non zero maxLocals and maxStack values.");
                     }
                     e.printStackTrace();
                     StringWriter sw = new StringWriter();
@@ -464,89 +488,111 @@
                 }
                 accept(cmv);
             }
-        },
-                labels);
+        }, labels);
+        this.access = access;
     }
 
     @Override
-    public AnnotationVisitor visitAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public void visitParameter(String name, int access) {
+        if (name != null) {
+            checkUnqualifiedName(version, name, "name");
+        }
+        CheckClassAdapter.checkAccess(access, Opcodes.ACC_FINAL
+                + Opcodes.ACC_MANDATED + Opcodes.ACC_SYNTHETIC);
+    }
+
+    @Override
+    public AnnotationVisitor visitAnnotation(final String desc,
+            final boolean visible) {
         checkEndMethod();
         checkDesc(desc, false);
         return new CheckAnnotationAdapter(super.visitAnnotation(desc, visible));
     }
 
     @Override
+    public AnnotationVisitor visitTypeAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        checkEndMethod();
+        int sort = typeRef >>> 24;
+        if (sort != TypeReference.METHOD_TYPE_PARAMETER
+                && sort != TypeReference.METHOD_TYPE_PARAMETER_BOUND
+                && sort != TypeReference.METHOD_RETURN
+                && sort != TypeReference.METHOD_RECEIVER
+                && sort != TypeReference.METHOD_FORMAL_PARAMETER
+                && sort != TypeReference.THROWS) {
+            throw new IllegalArgumentException("Invalid type reference sort 0x"
+                    + Integer.toHexString(sort));
+        }
+        CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath);
+        CheckMethodAdapter.checkDesc(desc, false);
+        return new CheckAnnotationAdapter(super.visitTypeAnnotation(typeRef,
+                typePath, desc, visible));
+    }
+
+    @Override
     public AnnotationVisitor visitAnnotationDefault() {
         checkEndMethod();
         return new CheckAnnotationAdapter(super.visitAnnotationDefault(), false);
     }
 
     @Override
-    public AnnotationVisitor visitParameterAnnotation(
-        final int parameter,
-        final String desc,
-        final boolean visible)
-    {
+    public AnnotationVisitor visitParameterAnnotation(final int parameter,
+            final String desc, final boolean visible) {
         checkEndMethod();
         checkDesc(desc, false);
-        return new CheckAnnotationAdapter(super.visitParameterAnnotation(parameter,
-                desc,
-                visible));
+        return new CheckAnnotationAdapter(super.visitParameterAnnotation(
+                parameter, desc, visible));
     }
 
     @Override
     public void visitAttribute(final Attribute attr) {
         checkEndMethod();
         if (attr == null) {
-            throw new IllegalArgumentException("Invalid attribute (must not be null)");
+            throw new IllegalArgumentException(
+                    "Invalid attribute (must not be null)");
         }
         super.visitAttribute(attr);
     }
 
     @Override
     public void visitCode() {
+        if ((access & Opcodes.ACC_ABSTRACT) != 0) {
+            throw new RuntimeException("Abstract methods cannot have code");
+        }
         startCode = true;
         super.visitCode();
     }
 
     @Override
-    public void visitFrame(
-        final int type,
-        final int nLocal,
-        final Object[] local,
-        final int nStack,
-        final Object[] stack)
-    {
+    public void visitFrame(final int type, final int nLocal,
+            final Object[] local, final int nStack, final Object[] stack) {
         int mLocal;
         int mStack;
         switch (type) {
-            case Opcodes.F_NEW:
-            case Opcodes.F_FULL:
-                mLocal = Integer.MAX_VALUE;
-                mStack = Integer.MAX_VALUE;
-                break;
+        case Opcodes.F_NEW:
+        case Opcodes.F_FULL:
+            mLocal = Integer.MAX_VALUE;
+            mStack = Integer.MAX_VALUE;
+            break;
 
-            case Opcodes.F_SAME:
-                mLocal = 0;
-                mStack = 0;
-                break;
+        case Opcodes.F_SAME:
+            mLocal = 0;
+            mStack = 0;
+            break;
 
-            case Opcodes.F_SAME1:
-                mLocal = 0;
-                mStack = 1;
-                break;
+        case Opcodes.F_SAME1:
+            mLocal = 0;
+            mStack = 1;
+            break;
 
-            case Opcodes.F_APPEND:
-            case Opcodes.F_CHOP:
-                mLocal = 3;
-                mStack = 0;
-                break;
+        case Opcodes.F_APPEND:
+        case Opcodes.F_CHOP:
+            mLocal = 3;
+            mStack = 0;
+            break;
 
-            default:
-                throw new IllegalArgumentException("Invalid frame type " + type);
+        default:
+            throw new IllegalArgumentException("Invalid frame type " + type);
         }
 
         if (nLocal > mLocal) {
@@ -560,19 +606,36 @@
 
         if (type != Opcodes.F_CHOP) {
             if (nLocal > 0 && (local == null || local.length < nLocal)) {
-                throw new IllegalArgumentException("Array local[] is shorter than nLocal");
+                throw new IllegalArgumentException(
+                        "Array local[] is shorter than nLocal");
             }
             for (int i = 0; i < nLocal; ++i) {
                 checkFrameValue(local[i]);
             }
         }
         if (nStack > 0 && (stack == null || stack.length < nStack)) {
-            throw new IllegalArgumentException("Array stack[] is shorter than nStack");
+            throw new IllegalArgumentException(
+                    "Array stack[] is shorter than nStack");
         }
         for (int i = 0; i < nStack; ++i) {
             checkFrameValue(stack[i]);
         }
-
+        if (type == Opcodes.F_NEW) {
+            if (insnCount == 0) {
+                hasExplicitFirstFrame = true;
+            } else if (!hasExplicitFirstFrame) {
+                throw new RuntimeException(
+                        "In expanded form, a first frame must be explicitly "
+                                + "visited before the first instruction.");
+            }
+            ++expandedFrames;
+        } else {
+            ++compressedFrames;
+        }
+        if (expandedFrames > 0 && compressedFrames > 0) {
+            throw new RuntimeException(
+                    "Expanded and compressed frames must not be mixed.");
+        }
         super.visitFrame(type, nLocal, local, nStack, stack);
     }
 
@@ -591,18 +654,19 @@
         checkEndCode();
         checkOpcode(opcode, 1);
         switch (opcode) {
-            case Opcodes.BIPUSH:
-                checkSignedByte(operand, "Invalid operand");
-                break;
-            case Opcodes.SIPUSH:
-                checkSignedShort(operand, "Invalid operand");
-                break;
-            // case Constants.NEWARRAY:
-            default:
-                if (operand < Opcodes.T_BOOLEAN || operand > Opcodes.T_LONG) {
-                    throw new IllegalArgumentException("Invalid operand (must be an array type code T_...): "
-                            + operand);
-                }
+        case Opcodes.BIPUSH:
+            checkSignedByte(operand, "Invalid operand");
+            break;
+        case Opcodes.SIPUSH:
+            checkSignedShort(operand, "Invalid operand");
+            break;
+        // case Constants.NEWARRAY:
+        default:
+            if (operand < Opcodes.T_BOOLEAN || operand > Opcodes.T_LONG) {
+                throw new IllegalArgumentException(
+                        "Invalid operand (must be an array type code T_...): "
+                                + operand);
+            }
         }
         super.visitIntInsn(opcode, operand);
         ++insnCount;
@@ -625,20 +689,16 @@
         checkOpcode(opcode, 3);
         checkInternalName(type, "type");
         if (opcode == Opcodes.NEW && type.charAt(0) == '[') {
-            throw new IllegalArgumentException("NEW cannot be used to create arrays: "
-                    + type);
+            throw new IllegalArgumentException(
+                    "NEW cannot be used to create arrays: " + type);
         }
         super.visitTypeInsn(opcode, type);
         ++insnCount;
     }
 
     @Override
-    public void visitFieldInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitFieldInsn(final int opcode, final String owner,
+            final String name, final String desc) {
         checkStartCode();
         checkEndCode();
         checkOpcode(opcode, 4);
@@ -650,16 +710,14 @@
     }
 
     @Override
-    public void visitMethodInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitMethodInsn(final int opcode, final String owner,
+            final String name, final String desc) {
         checkStartCode();
         checkEndCode();
         checkOpcode(opcode, 5);
-        checkMethodIdentifier(version, name, "name");
+        if (opcode != Opcodes.INVOKESPECIAL || !"<init>".equals(name)) {
+            checkMethodIdentifier(version, name, "name");
+        }
         checkInternalName(owner, "owner");
         checkMethodDesc(desc);
         super.visitMethodInsn(opcode, owner, name, desc);
@@ -667,19 +725,14 @@
     }
 
     @Override
-    public void visitInvokeDynamicInsn(
-        String name,
-        String desc,
-        Handle bsm,
-        Object... bsmArgs)
-    {
+    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+            Object... bsmArgs) {
         checkStartCode();
         checkEndCode();
         checkMethodIdentifier(version, name, "name");
         checkMethodDesc(desc);
         if (bsm.getTag() != Opcodes.H_INVOKESTATIC
-                && bsm.getTag() != Opcodes.H_NEWINVOKESPECIAL)
-        {
+                && bsm.getTag() != Opcodes.H_NEWINVOKESPECIAL) {
             throw new IllegalArgumentException("invalid handle tag "
                     + bsm.getTag());
         }
@@ -734,12 +787,8 @@
     }
 
     @Override
-    public void visitTableSwitchInsn(
-        final int min,
-        final int max,
-        final Label dflt,
-        final Label... labels)
-    {
+    public void visitTableSwitchInsn(final int min, final int max,
+            final Label dflt, final Label... labels) {
         checkStartCode();
         checkEndCode();
         if (max < min) {
@@ -749,7 +798,8 @@
         checkLabel(dflt, false, "default label");
         checkNonDebugLabel(dflt);
         if (labels == null || labels.length != max - min + 1) {
-            throw new IllegalArgumentException("There must be max - min + 1 labels");
+            throw new IllegalArgumentException(
+                    "There must be max - min + 1 labels");
         }
         for (int i = 0; i < labels.length; ++i) {
             checkLabel(labels[i], false, "label at index " + i);
@@ -763,17 +813,15 @@
     }
 
     @Override
-    public void visitLookupSwitchInsn(
-        final Label dflt,
-        final int[] keys,
-        final Label[] labels)
-    {
+    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+            final Label[] labels) {
         checkEndCode();
         checkStartCode();
         checkLabel(dflt, false, "default label");
         checkNonDebugLabel(dflt);
         if (keys == null || labels == null || keys.length != labels.length) {
-            throw new IllegalArgumentException("There must be the same number of keys and labels");
+            throw new IllegalArgumentException(
+                    "There must be the same number of keys and labels");
         }
         for (int i = 0; i < labels.length; ++i) {
             checkLabel(labels[i], false, "label at index " + i);
@@ -793,28 +841,49 @@
         checkEndCode();
         checkDesc(desc, false);
         if (desc.charAt(0) != '[') {
-            throw new IllegalArgumentException("Invalid descriptor (must be an array type descriptor): "
-                    + desc);
+            throw new IllegalArgumentException(
+                    "Invalid descriptor (must be an array type descriptor): "
+                            + desc);
         }
         if (dims < 1) {
-            throw new IllegalArgumentException("Invalid dimensions (must be greater than 0): "
-                    + dims);
+            throw new IllegalArgumentException(
+                    "Invalid dimensions (must be greater than 0): " + dims);
         }
         if (dims > desc.lastIndexOf('[') + 1) {
-            throw new IllegalArgumentException("Invalid dimensions (must not be greater than dims(desc)): "
-                    + dims);
+            throw new IllegalArgumentException(
+                    "Invalid dimensions (must not be greater than dims(desc)): "
+                            + dims);
         }
         super.visitMultiANewArrayInsn(desc, dims);
         ++insnCount;
     }
 
     @Override
-    public void visitTryCatchBlock(
-        final Label start,
-        final Label end,
-        final Label handler,
-        final String type)
-    {
+    public AnnotationVisitor visitInsnAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        checkStartCode();
+        checkEndCode();
+        int sort = typeRef >>> 24;
+        if (sort != TypeReference.INSTANCEOF && sort != TypeReference.NEW
+                && sort != TypeReference.CONSTRUCTOR_REFERENCE
+                && sort != TypeReference.METHOD_REFERENCE
+                && sort != TypeReference.CAST
+                && sort != TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+                && sort != TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT
+                && sort != TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+                && sort != TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT) {
+            throw new IllegalArgumentException("Invalid type reference sort 0x"
+                    + Integer.toHexString(sort));
+        }
+        CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath);
+        CheckMethodAdapter.checkDesc(desc, false);
+        return new CheckAnnotationAdapter(super.visitInsnAnnotation(typeRef,
+                typePath, desc, visible));
+    }
+
+    @Override
+    public void visitTryCatchBlock(final Label start, final Label end,
+            final Label handler, final String type) {
         checkStartCode();
         checkEndCode();
         checkLabel(start, false, "start label");
@@ -824,9 +893,9 @@
         checkNonDebugLabel(end);
         checkNonDebugLabel(handler);
         if (labels.get(start) != null || labels.get(end) != null
-                || labels.get(handler) != null)
-        {
-            throw new IllegalStateException("Try catch blocks must be visited before their labels");
+                || labels.get(handler) != null) {
+            throw new IllegalStateException(
+                    "Try catch blocks must be visited before their labels");
         }
         if (type != null) {
             checkInternalName(type, "type");
@@ -837,14 +906,25 @@
     }
 
     @Override
-    public void visitLocalVariable(
-        final String name,
-        final String desc,
-        final String signature,
-        final Label start,
-        final Label end,
-        final int index)
-    {
+    public AnnotationVisitor visitTryCatchAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        checkStartCode();
+        checkEndCode();
+        int sort = typeRef >>> 24;
+        if (sort != TypeReference.EXCEPTION_PARAMETER) {
+            throw new IllegalArgumentException("Invalid type reference sort 0x"
+                    + Integer.toHexString(sort));
+        }
+        CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath);
+        CheckMethodAdapter.checkDesc(desc, false);
+        return new CheckAnnotationAdapter(super.visitTryCatchAnnotation(
+                typeRef, typePath, desc, visible));
+    }
+
+    @Override
+    public void visitLocalVariable(final String name, final String desc,
+            final String signature, final Label start, final Label end,
+            final int index) {
         checkStartCode();
         checkEndCode();
         checkUnqualifiedName(version, name, "name");
@@ -855,12 +935,47 @@
         int s = labels.get(start).intValue();
         int e = labels.get(end).intValue();
         if (e < s) {
-            throw new IllegalArgumentException("Invalid start and end labels (end must be greater than start)");
+            throw new IllegalArgumentException(
+                    "Invalid start and end labels (end must be greater than start)");
         }
         super.visitLocalVariable(name, desc, signature, start, end, index);
     }
 
     @Override
+    public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
+            TypePath typePath, Label[] start, Label[] end, int[] index,
+            String desc, boolean visible) {
+        checkStartCode();
+        checkEndCode();
+        int sort = typeRef >>> 24;
+        if (sort != TypeReference.LOCAL_VARIABLE
+                && sort != TypeReference.RESOURCE_VARIABLE) {
+            throw new IllegalArgumentException("Invalid type reference sort 0x"
+                    + Integer.toHexString(sort));
+        }
+        CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath);
+        checkDesc(desc, false);
+        if (start == null || end == null || index == null
+                || end.length != start.length || index.length != start.length) {
+            throw new IllegalArgumentException(
+                    "Invalid start, end and index arrays (must be non null and of identical length");
+        }
+        for (int i = 0; i < start.length; ++i) {
+            checkLabel(start[i], true, "start label");
+            checkLabel(end[i], true, "end label");
+            checkUnsignedShort(index[i], "Invalid variable index");
+            int s = labels.get(start[i]).intValue();
+            int e = labels.get(end[i]).intValue();
+            if (e < s) {
+                throw new IllegalArgumentException(
+                        "Invalid start and end labels (end must be greater than start)");
+            }
+        }
+        return super.visitLocalVariableAnnotation(typeRef, typePath, start,
+                end, index, desc, visible);
+    }
+
+    @Override
     public void visitLineNumber(final int line, final Label start) {
         checkStartCode();
         checkEndCode();
@@ -879,14 +994,16 @@
                 throw new IllegalStateException("Undefined label used");
             }
         }
-        for (int i = 0; i < handlers.size(); ) {
+        for (int i = 0; i < handlers.size();) {
             Integer start = labels.get(handlers.get(i++));
             Integer end = labels.get(handlers.get(i++));
             if (start == null || end == null) {
-                throw new IllegalStateException("Undefined try catch block labels");
+                throw new IllegalStateException(
+                        "Undefined try catch block labels");
             }
             if (end.intValue() <= start.intValue()) {
-                throw new IllegalStateException("Emty try catch block handler range");
+                throw new IllegalStateException(
+                        "Emty try catch block handler range");
             }
         }
         checkUnsignedShort(maxStack, "Invalid max stack");
@@ -908,7 +1025,8 @@
      */
     void checkStartCode() {
         if (!startCode) {
-            throw new IllegalStateException("Cannot visit instructions before visitCode has been called.");
+            throw new IllegalStateException(
+                    "Cannot visit instructions before visitCode has been called.");
         }
     }
 
@@ -917,7 +1035,8 @@
      */
     void checkEndCode() {
         if (endCode) {
-            throw new IllegalStateException("Cannot visit instructions after visitMaxs has been called.");
+            throw new IllegalStateException(
+                    "Cannot visit instructions after visitMaxs has been called.");
         }
     }
 
@@ -926,21 +1045,22 @@
      */
     void checkEndMethod() {
         if (endMethod) {
-            throw new IllegalStateException("Cannot visit elements after visitEnd has been called.");
+            throw new IllegalStateException(
+                    "Cannot visit elements after visitEnd has been called.");
         }
     }
 
     /**
      * Checks a stack frame value.
      *
-     * @param value the value to be checked.
+     * @param value
+     *            the value to be checked.
      */
     void checkFrameValue(final Object value) {
         if (value == Opcodes.TOP || value == Opcodes.INTEGER
                 || value == Opcodes.FLOAT || value == Opcodes.LONG
                 || value == Opcodes.DOUBLE || value == Opcodes.NULL
-                || value == Opcodes.UNINITIALIZED_THIS)
-        {
+                || value == Opcodes.UNINITIALIZED_THIS) {
             return;
         }
         if (value instanceof String) {
@@ -958,8 +1078,10 @@
     /**
      * Checks that the type of the given opcode is equal to the given type.
      *
-     * @param opcode the opcode to be checked.
-     * @param type the expected opcode type.
+     * @param opcode
+     *            the opcode to be checked.
+     * @param type
+     *            the expected opcode type.
      */
     static void checkOpcode(final int opcode, final int type) {
         if (opcode < 0 || opcode > 199 || TYPE[opcode] != type) {
@@ -970,8 +1092,10 @@
     /**
      * Checks that the given value is a signed byte.
      *
-     * @param value the value to be checked.
-     * @param msg an message to be used in case of error.
+     * @param value
+     *            the value to be checked.
+     * @param msg
+     *            an message to be used in case of error.
      */
     static void checkSignedByte(final int value, final String msg) {
         if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
@@ -983,8 +1107,10 @@
     /**
      * Checks that the given value is a signed short.
      *
-     * @param value the value to be checked.
-     * @param msg an message to be used in case of error.
+     * @param value
+     *            the value to be checked.
+     * @param msg
+     *            an message to be used in case of error.
      */
     static void checkSignedShort(final int value, final String msg) {
         if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
@@ -996,8 +1122,10 @@
     /**
      * Checks that the given value is an unsigned short.
      *
-     * @param value the value to be checked.
-     * @param msg an message to be used in case of error.
+     * @param value
+     *            the value to be checked.
+     * @param msg
+     *            an message to be used in case of error.
      */
     static void checkUnsignedShort(final int value, final String msg) {
         if (value < 0 || value > 65535) {
@@ -1010,13 +1138,13 @@
      * Checks that the given value is an {@link Integer}, a{@link Float}, a
      * {@link Long}, a {@link Double} or a {@link String}.
      *
-     * @param cst the value to be checked.
+     * @param cst
+     *            the value to be checked.
      */
     static void checkConstant(final Object cst) {
         if (!(cst instanceof Integer) && !(cst instanceof Float)
                 && !(cst instanceof Long) && !(cst instanceof Double)
-                && !(cst instanceof String))
-        {
+                && !(cst instanceof String)) {
             throw new IllegalArgumentException("Invalid constant: " + cst);
         }
     }
@@ -1028,19 +1156,21 @@
                 throw new IllegalArgumentException("Illegal LDC constant value");
             }
             if (s != Type.METHOD && (version & 0xFFFF) < Opcodes.V1_5) {
-                throw new IllegalArgumentException("ldc of a constant class requires at least version 1.5");
+                throw new IllegalArgumentException(
+                        "ldc of a constant class requires at least version 1.5");
             }
             if (s == Type.METHOD && (version & 0xFFFF) < Opcodes.V1_7) {
-                throw new IllegalArgumentException("ldc of a method type requires at least version 1.7");
+                throw new IllegalArgumentException(
+                        "ldc of a method type requires at least version 1.7");
             }
         } else if (cst instanceof Handle) {
             if ((version & 0xFFFF) < Opcodes.V1_7) {
-                throw new IllegalArgumentException("ldc of a handle requires at least version 1.7");
+                throw new IllegalArgumentException(
+                        "ldc of a handle requires at least version 1.7");
             }
             int tag = ((Handle) cst).getTag();
             if (tag < Opcodes.H_GETFIELD || tag > Opcodes.H_INVOKEINTERFACE) {
-                throw new IllegalArgumentException("invalid handle tag "
-                        + tag);
+                throw new IllegalArgumentException("invalid handle tag " + tag);
             }
         } else {
             checkConstant(cst);
@@ -1050,15 +1180,15 @@
     /**
      * Checks that the given string is a valid unqualified name.
      *
-     * @param version the class version.
-     * @param name the string to be checked.
-     * @param msg a message to be used in case of error.
+     * @param version
+     *            the class version.
+     * @param name
+     *            the string to be checked.
+     * @param msg
+     *            a message to be used in case of error.
      */
-    static void checkUnqualifiedName(
-        int version,
-        final String name,
-        final String msg)
-    {
+    static void checkUnqualifiedName(int version, final String name,
+            final String msg) {
         if ((version & 0xFFFF) < Opcodes.V1_5) {
             checkIdentifier(name, msg);
         } else {
@@ -1074,8 +1204,10 @@
     /**
      * Checks that the given string is a valid Java identifier.
      *
-     * @param name the string to be checked.
-     * @param msg a message to be used in case of error.
+     * @param name
+     *            the string to be checked.
+     * @param msg
+     *            a message to be used in case of error.
      */
     static void checkIdentifier(final String name, final String msg) {
         checkIdentifier(name, 0, -1, msg);
@@ -1084,21 +1216,20 @@
     /**
      * Checks that the given substring is a valid Java identifier.
      *
-     * @param name the string to be checked.
-     * @param start index of the first character of the identifier (inclusive).
-     * @param end index of the last character of the identifier (exclusive). -1
-     *        is equivalent to <tt>name.length()</tt> if name is not
-     *        <tt>null</tt>.
-     * @param msg a message to be used in case of error.
+     * @param name
+     *            the string to be checked.
+     * @param start
+     *            index of the first character of the identifier (inclusive).
+     * @param end
+     *            index of the last character of the identifier (exclusive). -1
+     *            is equivalent to <tt>name.length()</tt> if name is not
+     *            <tt>null</tt>.
+     * @param msg
+     *            a message to be used in case of error.
      */
-    static void checkIdentifier(
-        final String name,
-        final int start,
-        final int end,
-        final String msg)
-    {
-        if (name == null || (end == -1 ? name.length() <= start : end <= start))
-        {
+    static void checkIdentifier(final String name, final int start,
+            final int end, final String msg) {
+        if (name == null || (end == -1 ? name.length() <= start : end <= start)) {
             throw new IllegalArgumentException("Invalid " + msg
                     + " (must not be null or empty)");
         }
@@ -1116,25 +1247,21 @@
     }
 
     /**
-     * Checks that the given string is a valid Java identifier or is equal to
-     * '&lt;init&gt;' or '&lt;clinit&gt;'.
+     * Checks that the given string is a valid Java identifier.
      *
-     * @param version the class version.
-     * @param name the string to be checked.
-     * @param msg a message to be used in case of error.
+     * @param version
+     *            the class version.
+     * @param name
+     *            the string to be checked.
+     * @param msg
+     *            a message to be used in case of error.
      */
-    static void checkMethodIdentifier(
-        int version,
-        final String name,
-        final String msg)
-    {
+    static void checkMethodIdentifier(int version, final String name,
+            final String msg) {
         if (name == null || name.length() == 0) {
             throw new IllegalArgumentException("Invalid " + msg
                     + " (must not be null or empty)");
         }
-        if ("<init>".equals(name) || "<clinit>".equals(name)) {
-            return;
-        }
         if ((version & 0xFFFF) >= Opcodes.V1_5) {
             for (int i = 0; i < name.length(); ++i) {
                 if (".;[/<>".indexOf(name.charAt(i)) != -1) {
@@ -1145,17 +1272,19 @@
             return;
         }
         if (!Character.isJavaIdentifierStart(name.charAt(0))) {
-            throw new IllegalArgumentException("Invalid "
-                    + msg
-                    + " (must be a '<init>', '<clinit>' or a valid Java identifier): "
-                    + name);
+            throw new IllegalArgumentException(
+                    "Invalid "
+                            + msg
+                            + " (must be a '<init>', '<clinit>' or a valid Java identifier): "
+                            + name);
         }
         for (int i = 1; i < name.length(); ++i) {
             if (!Character.isJavaIdentifierPart(name.charAt(i))) {
-                throw new IllegalArgumentException("Invalid "
-                        + msg
-                        + " (must be '<init>' or '<clinit>' or a valid Java identifier): "
-                        + name);
+                throw new IllegalArgumentException(
+                        "Invalid "
+                                + msg
+                                + " (must be '<init>' or '<clinit>' or a valid Java identifier): "
+                                + name);
             }
         }
     }
@@ -1163,8 +1292,10 @@
     /**
      * Checks that the given string is a valid internal class name.
      *
-     * @param name the string to be checked.
-     * @param msg a message to be used in case of error.
+     * @param name
+     *            the string to be checked.
+     * @param msg
+     *            a message to be used in case of error.
      */
     static void checkInternalName(final String name, final String msg) {
         if (name == null || name.length() == 0) {
@@ -1181,19 +1312,19 @@
     /**
      * Checks that the given substring is a valid internal class name.
      *
-     * @param name the string to be checked.
-     * @param start index of the first character of the identifier (inclusive).
-     * @param end index of the last character of the identifier (exclusive). -1
-     *        is equivalent to <tt>name.length()</tt> if name is not
-     *        <tt>null</tt>.
-     * @param msg a message to be used in case of error.
+     * @param name
+     *            the string to be checked.
+     * @param start
+     *            index of the first character of the identifier (inclusive).
+     * @param end
+     *            index of the last character of the identifier (exclusive). -1
+     *            is equivalent to <tt>name.length()</tt> if name is not
+     *            <tt>null</tt>.
+     * @param msg
+     *            a message to be used in case of error.
      */
-    static void checkInternalName(
-        final String name,
-        final int start,
-        final int end,
-        final String msg)
-    {
+    static void checkInternalName(final String name, final int start,
+            final int end, final String msg) {
         int max = end == -1 ? name.length() : end;
         try {
             int begin = start;
@@ -1206,19 +1337,22 @@
                 checkIdentifier(name, begin, slash, null);
                 begin = slash + 1;
             } while (slash != max);
-        } catch (IllegalArgumentException _) {
-            throw new IllegalArgumentException("Invalid "
-                    + msg
-                    + " (must be a fully qualified class name in internal form): "
-                    + name);
+        } catch (IllegalArgumentException unused) {
+            throw new IllegalArgumentException(
+                    "Invalid "
+                            + msg
+                            + " (must be a fully qualified class name in internal form): "
+                            + name);
         }
     }
 
     /**
      * Checks that the given string is a valid type descriptor.
      *
-     * @param desc the string to be checked.
-     * @param canBeVoid <tt>true</tt> if <tt>V</tt> can be considered valid.
+     * @param desc
+     *            the string to be checked.
+     * @param canBeVoid
+     *            <tt>true</tt> if <tt>V</tt> can be considered valid.
      */
     static void checkDesc(final String desc, final boolean canBeVoid) {
         int end = checkDesc(desc, 0, canBeVoid);
@@ -1230,75 +1364,77 @@
     /**
      * Checks that a the given substring is a valid type descriptor.
      *
-     * @param desc the string to be checked.
-     * @param start index of the first character of the identifier (inclusive).
-     * @param canBeVoid <tt>true</tt> if <tt>V</tt> can be considered valid.
+     * @param desc
+     *            the string to be checked.
+     * @param start
+     *            index of the first character of the identifier (inclusive).
+     * @param canBeVoid
+     *            <tt>true</tt> if <tt>V</tt> can be considered valid.
      * @return the index of the last character of the type decriptor, plus one.
      */
-    static int checkDesc(
-        final String desc,
-        final int start,
-        final boolean canBeVoid)
-    {
+    static int checkDesc(final String desc, final int start,
+            final boolean canBeVoid) {
         if (desc == null || start >= desc.length()) {
-            throw new IllegalArgumentException("Invalid type descriptor (must not be null or empty)");
+            throw new IllegalArgumentException(
+                    "Invalid type descriptor (must not be null or empty)");
         }
         int index;
         switch (desc.charAt(start)) {
-            case 'V':
-                if (canBeVoid) {
-                    return start + 1;
-                } else {
-                    throw new IllegalArgumentException("Invalid descriptor: "
-                            + desc);
-                }
-            case 'Z':
-            case 'C':
-            case 'B':
-            case 'S':
-            case 'I':
-            case 'F':
-            case 'J':
-            case 'D':
+        case 'V':
+            if (canBeVoid) {
                 return start + 1;
-            case '[':
-                index = start + 1;
-                while (index < desc.length() && desc.charAt(index) == '[') {
-                    ++index;
-                }
-                if (index < desc.length()) {
-                    return checkDesc(desc, index, false);
-                } else {
-                    throw new IllegalArgumentException("Invalid descriptor: "
-                            + desc);
-                }
-            case 'L':
-                index = desc.indexOf(';', start);
-                if (index == -1 || index - start < 2) {
-                    throw new IllegalArgumentException("Invalid descriptor: "
-                            + desc);
-                }
-                try {
-                    checkInternalName(desc, start + 1, index, null);
-                } catch (IllegalArgumentException _) {
-                    throw new IllegalArgumentException("Invalid descriptor: "
-                            + desc);
-                }
-                return index + 1;
-            default:
+            } else {
                 throw new IllegalArgumentException("Invalid descriptor: "
                         + desc);
+            }
+        case 'Z':
+        case 'C':
+        case 'B':
+        case 'S':
+        case 'I':
+        case 'F':
+        case 'J':
+        case 'D':
+            return start + 1;
+        case '[':
+            index = start + 1;
+            while (index < desc.length() && desc.charAt(index) == '[') {
+                ++index;
+            }
+            if (index < desc.length()) {
+                return checkDesc(desc, index, false);
+            } else {
+                throw new IllegalArgumentException("Invalid descriptor: "
+                        + desc);
+            }
+        case 'L':
+            index = desc.indexOf(';', start);
+            if (index == -1 || index - start < 2) {
+                throw new IllegalArgumentException("Invalid descriptor: "
+                        + desc);
+            }
+            try {
+                checkInternalName(desc, start + 1, index, null);
+            } catch (IllegalArgumentException unused) {
+                throw new IllegalArgumentException("Invalid descriptor: "
+                        + desc);
+            }
+            return index + 1;
+        default:
+            throw new IllegalArgumentException("Invalid descriptor: " + desc);
         }
     }
 
     /**
      * Checks that the given string is a valid method descriptor.
      *
-     * @param desc the string to be checked.
+     * @param desc
+     *            the string to be checked.
      */
     static void checkMethodDesc(final String desc) {
         if (desc == null || desc.length() == 0) {
-            throw new IllegalArgumentException("Invalid method descriptor (must not be null or empty)");
+            throw new IllegalArgumentException(
+                    "Invalid method descriptor (must not be null or empty)");
         }
         if (desc.charAt(0) != '(' || desc.length() < 3) {
             throw new IllegalArgumentException("Invalid descriptor: " + desc);
@@ -1320,322 +1456,18 @@
     }
 
     /**
-     * Checks a class signature.
-     *
-     * @param signature a string containing the signature that must be checked.
-     */
-    static void checkClassSignature(final String signature) {
-        // ClassSignature:
-        // FormalTypeParameters? ClassTypeSignature ClassTypeSignature*
-
-        int pos = 0;
-        if (getChar(signature, 0) == '<') {
-            pos = checkFormalTypeParameters(signature, pos);
-        }
-        pos = checkClassTypeSignature(signature, pos);
-        while (getChar(signature, pos) == 'L') {
-            pos = checkClassTypeSignature(signature, pos);
-        }
-        if (pos != signature.length()) {
-            throw new IllegalArgumentException(signature + ": error at index "
-                    + pos);
-        }
-    }
-
-    /**
-     * Checks a method signature.
-     *
-     * @param signature a string containing the signature that must be checked.
-     */
-    static void checkMethodSignature(final String signature) {
-        // MethodTypeSignature:
-        // FormalTypeParameters? ( TypeSignature* ) ( TypeSignature | V ) (
-        // ^ClassTypeSignature | ^TypeVariableSignature )*
-
-        int pos = 0;
-        if (getChar(signature, 0) == '<') {
-            pos = checkFormalTypeParameters(signature, pos);
-        }
-        pos = checkChar('(', signature, pos);
-        while ("ZCBSIFJDL[T".indexOf(getChar(signature, pos)) != -1) {
-            pos = checkTypeSignature(signature, pos);
-        }
-        pos = checkChar(')', signature, pos);
-        if (getChar(signature, pos) == 'V') {
-            ++pos;
-        } else {
-            pos = checkTypeSignature(signature, pos);
-        }
-        while (getChar(signature, pos) == '^') {
-            ++pos;
-            if (getChar(signature, pos) == 'L') {
-                pos = checkClassTypeSignature(signature, pos);
-            } else {
-                pos = checkTypeVariableSignature(signature, pos);
-            }
-        }
-        if (pos != signature.length()) {
-            throw new IllegalArgumentException(signature + ": error at index "
-                    + pos);
-        }
-    }
-
-    /**
-     * Checks a field signature.
-     *
-     * @param signature a string containing the signature that must be checked.
-     */
-    static void checkFieldSignature(final String signature) {
-        int pos = checkFieldTypeSignature(signature, 0);
-        if (pos != signature.length()) {
-            throw new IllegalArgumentException(signature + ": error at index "
-                    + pos);
-        }
-    }
-
-    /**
-     * Checks the formal type parameters of a class or method signature.
-     *
-     * @param signature a string containing the signature that must be checked.
-     * @param pos index of first character to be checked.
-     * @return the index of the first character after the checked part.
-     */
-    private static int checkFormalTypeParameters(final String signature, int pos)
-    {
-        // FormalTypeParameters:
-        // < FormalTypeParameter+ >
-
-        pos = checkChar('<', signature, pos);
-        pos = checkFormalTypeParameter(signature, pos);
-        while (getChar(signature, pos) != '>') {
-            pos = checkFormalTypeParameter(signature, pos);
-        }
-        return pos + 1;
-    }
-
-    /**
-     * Checks a formal type parameter of a class or method signature.
-     *
-     * @param signature a string containing the signature that must be checked.
-     * @param pos index of first character to be checked.
-     * @return the index of the first character after the checked part.
-     */
-    private static int checkFormalTypeParameter(final String signature, int pos)
-    {
-        // FormalTypeParameter:
-        // Identifier : FieldTypeSignature? (: FieldTypeSignature)*
-
-        pos = checkIdentifier(signature, pos);
-        pos = checkChar(':', signature, pos);
-        if ("L[T".indexOf(getChar(signature, pos)) != -1) {
-            pos = checkFieldTypeSignature(signature, pos);
-        }
-        while (getChar(signature, pos) == ':') {
-            pos = checkFieldTypeSignature(signature, pos + 1);
-        }
-        return pos;
-    }
-
-    /**
-     * Checks a field type signature.
-     *
-     * @param signature a string containing the signature that must be checked.
-     * @param pos index of first character to be checked.
-     * @return the index of the first character after the checked part.
-     */
-    private static int checkFieldTypeSignature(final String signature, int pos)
-    {
-        // FieldTypeSignature:
-        // ClassTypeSignature | ArrayTypeSignature | TypeVariableSignature
-        //
-        // ArrayTypeSignature:
-        // [ TypeSignature
-
-        switch (getChar(signature, pos)) {
-            case 'L':
-                return checkClassTypeSignature(signature, pos);
-            case '[':
-                return checkTypeSignature(signature, pos + 1);
-            default:
-                return checkTypeVariableSignature(signature, pos);
-        }
-    }
-
-    /**
-     * Checks a class type signature.
-     *
-     * @param signature a string containing the signature that must be checked.
-     * @param pos index of first character to be checked.
-     * @return the index of the first character after the checked part.
-     */
-    private static int checkClassTypeSignature(final String signature, int pos)
-    {
-        // ClassTypeSignature:
-        // L Identifier ( / Identifier )* TypeArguments? ( . Identifier
-        // TypeArguments? )* ;
-
-        pos = checkChar('L', signature, pos);
-        pos = checkIdentifier(signature, pos);
-        while (getChar(signature, pos) == '/') {
-            pos = checkIdentifier(signature, pos + 1);
-        }
-        if (getChar(signature, pos) == '<') {
-            pos = checkTypeArguments(signature, pos);
-        }
-        while (getChar(signature, pos) == '.') {
-            pos = checkIdentifier(signature, pos + 1);
-            if (getChar(signature, pos) == '<') {
-                pos = checkTypeArguments(signature, pos);
-            }
-        }
-        return checkChar(';', signature, pos);
-    }
-
-    /**
-     * Checks the type arguments in a class type signature.
-     *
-     * @param signature a string containing the signature that must be checked.
-     * @param pos index of first character to be checked.
-     * @return the index of the first character after the checked part.
-     */
-    private static int checkTypeArguments(final String signature, int pos) {
-        // TypeArguments:
-        // < TypeArgument+ >
-
-        pos = checkChar('<', signature, pos);
-        pos = checkTypeArgument(signature, pos);
-        while (getChar(signature, pos) != '>') {
-            pos = checkTypeArgument(signature, pos);
-        }
-        return pos + 1;
-    }
-
-    /**
-     * Checks a type argument in a class type signature.
-     *
-     * @param signature a string containing the signature that must be checked.
-     * @param pos index of first character to be checked.
-     * @return the index of the first character after the checked part.
-     */
-    private static int checkTypeArgument(final String signature, int pos) {
-        // TypeArgument:
-        // * | ( ( + | - )? FieldTypeSignature )
-
-        char c = getChar(signature, pos);
-        if (c == '*') {
-            return pos + 1;
-        } else if (c == '+' || c == '-') {
-            pos++;
-        }
-        return checkFieldTypeSignature(signature, pos);
-    }
-
-    /**
-     * Checks a type variable signature.
-     *
-     * @param signature a string containing the signature that must be checked.
-     * @param pos index of first character to be checked.
-     * @return the index of the first character after the checked part.
-     */
-    private static int checkTypeVariableSignature(
-        final String signature,
-        int pos)
-    {
-        // TypeVariableSignature:
-        // T Identifier ;
-
-        pos = checkChar('T', signature, pos);
-        pos = checkIdentifier(signature, pos);
-        return checkChar(';', signature, pos);
-    }
-
-    /**
-     * Checks a type signature.
-     *
-     * @param signature a string containing the signature that must be checked.
-     * @param pos index of first character to be checked.
-     * @return the index of the first character after the checked part.
-     */
-    private static int checkTypeSignature(final String signature, int pos) {
-        // TypeSignature:
-        // Z | C | B | S | I | F | J | D | FieldTypeSignature
-
-        switch (getChar(signature, pos)) {
-            case 'Z':
-            case 'C':
-            case 'B':
-            case 'S':
-            case 'I':
-            case 'F':
-            case 'J':
-            case 'D':
-                return pos + 1;
-            default:
-                return checkFieldTypeSignature(signature, pos);
-        }
-    }
-
-    /**
-     * Checks an identifier.
-     *
-     * @param signature a string containing the signature that must be checked.
-     * @param pos index of first character to be checked.
-     * @return the index of the first character after the checked part.
-     */
-    private static int checkIdentifier(final String signature, int pos) {
-        if (!Character.isJavaIdentifierStart(getChar(signature, pos))) {
-            throw new IllegalArgumentException(signature
-                    + ": identifier expected at index " + pos);
-        }
-        ++pos;
-        while (Character.isJavaIdentifierPart(getChar(signature, pos))) {
-            ++pos;
-        }
-        return pos;
-    }
-
-    /**
-     * Checks a single character.
-     *
-     * @param signature a string containing the signature that must be checked.
-     * @param pos index of first character to be checked.
-     * @return the index of the first character after the checked part.
-     */
-    private static int checkChar(final char c, final String signature, int pos)
-    {
-        if (getChar(signature, pos) == c) {
-            return pos + 1;
-        }
-        throw new IllegalArgumentException(signature + ": '" + c
-                + "' expected at index " + pos);
-    }
-
-    /**
-     * Returns the signature car at the given index.
-     *
-     * @param signature a signature.
-     * @param pos an index in signature.
-     * @return the character at the given index, or 0 if there is no such
-     *         character.
-     */
-    private static char getChar(final String signature, int pos) {
-        return pos < signature.length() ? signature.charAt(pos) : (char) 0;
-    }
-
-    /**
      * Checks that the given label is not null. This method can also check that
      * the label has been visited.
      *
-     * @param label the label to be checked.
-     * @param checkVisited <tt>true</tt> to check that the label has been
-     *        visited.
-     * @param msg a message to be used in case of error.
+     * @param label
+     *            the label to be checked.
+     * @param checkVisited
+     *            <tt>true</tt> to check that the label has been visited.
+     * @param msg
+     *            a message to be used in case of error.
      */
-    void checkLabel(
-        final Label label,
-        final boolean checkVisited,
-        final String msg)
-    {
+    void checkLabel(final Label label, final boolean checkVisited,
+            final String msg) {
         if (label == null) {
             throw new IllegalArgumentException("Invalid " + msg
                     + " (must not be null)");
@@ -1649,7 +1481,8 @@
     /**
      * Checks that the given label is not a label used only for debug purposes.
      *
-     * @param label the label to be checked.
+     * @param label
+     *            the label to be checked.
      */
     private static void checkNonDebugLabel(final Label label) {
         Field f = getLabelStatusField();
@@ -1660,7 +1493,8 @@
             throw new Error("Internal error");
         }
         if ((status & 0x01) != 0) {
-            throw new IllegalArgumentException("Labels used for debug info cannot be reused for control flow");
+            throw new IllegalArgumentException(
+                    "Labels used for debug info cannot be reused for control flow");
         }
     }
 
@@ -1682,7 +1516,8 @@
     /**
      * Returns the field of the Label class whose name is given.
      *
-     * @param name a field name.
+     * @param name
+     *            a field name.
      * @return the field of the Label class whose name is given, or null.
      */
     private static Field getLabelField(final String name) {
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckSignatureAdapter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckSignatureAdapter.java
index 9aa009e..ad3bca8 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckSignatureAdapter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckSignatureAdapter.java
@@ -70,19 +70,22 @@
 
     /**
      * Type to be used to check class signatures. See
-     * {@link #CheckSignatureAdapter(int, SignatureVisitor) CheckSignatureAdapter}.
+     * {@link #CheckSignatureAdapter(int, SignatureVisitor)
+     * CheckSignatureAdapter}.
      */
     public static final int CLASS_SIGNATURE = 0;
 
     /**
      * Type to be used to check method signatures. See
-     * {@link #CheckSignatureAdapter(int, SignatureVisitor) CheckSignatureAdapter}.
+     * {@link #CheckSignatureAdapter(int, SignatureVisitor)
+     * CheckSignatureAdapter}.
      */
     public static final int METHOD_SIGNATURE = 1;
 
     /**
      * Type to be used to check type signatures.See
-     * {@link #CheckSignatureAdapter(int, SignatureVisitor) CheckSignatureAdapter}.
+     * {@link #CheckSignatureAdapter(int, SignatureVisitor)
+     * CheckSignatureAdapter}.
      */
     public static final int TYPE_SIGNATURE = 2;
 
@@ -130,32 +133,34 @@
      * not use this constructor</i>. Instead, they must use the
      * {@link #CheckSignatureAdapter(int, int, SignatureVisitor)} version.
      *
-     * @param type the type of signature to be checked. See
-     *        {@link #CLASS_SIGNATURE}, {@link #METHOD_SIGNATURE} and
-     *        {@link #TYPE_SIGNATURE}.
-     * @param sv the visitor to which this adapter must delegate calls. May be
-     *        <tt>null</tt>.
+     * @param type
+     *            the type of signature to be checked. See
+     *            {@link #CLASS_SIGNATURE}, {@link #METHOD_SIGNATURE} and
+     *            {@link #TYPE_SIGNATURE}.
+     * @param sv
+     *            the visitor to which this adapter must delegate calls. May be
+     *            <tt>null</tt>.
      */
     public CheckSignatureAdapter(final int type, final SignatureVisitor sv) {
-        this(Opcodes.ASM4, type, sv);
+        this(Opcodes.ASM5, type, sv);
     }
 
     /**
      * Creates a new {@link CheckSignatureAdapter} object.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
-     * @param type the type of signature to be checked. See
-     *        {@link #CLASS_SIGNATURE}, {@link #METHOD_SIGNATURE} and
-     *        {@link #TYPE_SIGNATURE}.
-     * @param sv the visitor to which this adapter must delegate calls. May be
-     *        <tt>null</tt>.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param type
+     *            the type of signature to be checked. See
+     *            {@link #CLASS_SIGNATURE}, {@link #METHOD_SIGNATURE} and
+     *            {@link #TYPE_SIGNATURE}.
+     * @param sv
+     *            the visitor to which this adapter must delegate calls. May be
+     *            <tt>null</tt>.
      */
-    protected CheckSignatureAdapter(
-        final int api,
-        final int type,
-        final SignatureVisitor sv)
-    {
+    protected CheckSignatureAdapter(final int api, final int type,
+            final SignatureVisitor sv) {
         super(api);
         this.type = type;
         this.state = EMPTY;
@@ -167,8 +172,7 @@
     @Override
     public void visitFormalTypeParameter(final String name) {
         if (type == TYPE_SIGNATURE
-                || (state != EMPTY && state != FORMAL && state != BOUND))
-        {
+                || (state != EMPTY && state != FORMAL && state != BOUND)) {
             throw new IllegalStateException();
         }
         CheckMethodAdapter.checkIdentifier(name, "formal type parameter");
@@ -201,8 +205,7 @@
 
     @Override
     public SignatureVisitor visitSuperclass() {
-        if (type != CLASS_SIGNATURE || (state & (EMPTY | FORMAL | BOUND)) == 0)
-        {
+        if (type != CLASS_SIGNATURE || (state & (EMPTY | FORMAL | BOUND)) == 0) {
             throw new IllegalArgumentException();
         }
         state = SUPER;
@@ -224,8 +227,7 @@
     @Override
     public SignatureVisitor visitParameterType() {
         if (type != METHOD_SIGNATURE
-                || (state & (EMPTY | FORMAL | BOUND | PARAM)) == 0)
-        {
+                || (state & (EMPTY | FORMAL | BOUND | PARAM)) == 0) {
             throw new IllegalArgumentException();
         }
         state = PARAM;
@@ -236,8 +238,7 @@
     @Override
     public SignatureVisitor visitReturnType() {
         if (type != METHOD_SIGNATURE
-                || (state & (EMPTY | FORMAL | BOUND | PARAM)) == 0)
-        {
+                || (state & (EMPTY | FORMAL | BOUND | PARAM)) == 0) {
             throw new IllegalArgumentException();
         }
         state = RETURN;
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java
index b823eee..5d50e8f 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java
@@ -66,6 +66,7 @@
 import jdk.internal.org.objectweb.asm.Handle;
 import jdk.internal.org.objectweb.asm.Label;
 import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.TypePath;
 
 /**
  * An abstract converter from visit events to text.
@@ -132,8 +133,8 @@
         }
 
         s = "H_GETFIELD,H_GETSTATIC,H_PUTFIELD,H_PUTSTATIC,"
-          + "H_INVOKEVIRTUAL,H_INVOKESTATIC,H_INVOKESPECIAL,"
-          + "H_NEWINVOKESPECIAL,H_INVOKEINTERFACE,";
+                + "H_INVOKEVIRTUAL,H_INVOKESTATIC,H_INVOKESPECIAL,"
+                + "H_NEWINVOKESPECIAL,H_INVOKEINTERFACE,";
         HANDLE_TAG = new String[10];
         j = 0;
         i = 1;
@@ -145,7 +146,7 @@
 
     /**
      * The ASM API version implemented by this class. The value of this field
-     * must be one of {@link Opcodes#ASM4}.
+     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
      */
     protected final int api;
 
@@ -178,81 +179,67 @@
     }
 
     /**
-     * Class header.
-     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visit}.
+     * Class header. See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visit}.
      */
-    public abstract void visit(
-        final int version,
-        final int access,
-        final String name,
-        final String signature,
-        final String superName,
-        final String[] interfaces);
+    public abstract void visit(final int version, final int access,
+            final String name, final String signature, final String superName,
+            final String[] interfaces);
 
     /**
-     * Class source.
-     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitSource}.
+     * Class source. See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitSource}.
      */
     public abstract void visitSource(final String file, final String debug);
 
     /**
-     * Class outer class.
-     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitOuterClass}.
+     * Class outer class. See
+     * {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitOuterClass}.
      */
-    public abstract void visitOuterClass(
-        final String owner,
-        final String name,
-        final String desc);
+    public abstract void visitOuterClass(final String owner, final String name,
+            final String desc);
 
     /**
-     * Class annotation.
-     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitAnnotation}.
+     * Class annotation. See
+     * {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitAnnotation}.
      */
-    public abstract Printer visitClassAnnotation(
-        final String desc,
-        final boolean visible);
+    public abstract Printer visitClassAnnotation(final String desc,
+            final boolean visible);
 
     /**
-     * Class attribute.
-     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitAttribute}.
+     * Class type annotation. See
+     * {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitTypeAnnotation}.
+     */
+    public Printer visitClassTypeAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    /**
+     * Class attribute. See
+     * {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitAttribute}.
      */
     public abstract void visitClassAttribute(final Attribute attr);
 
     /**
-     * Class inner name.
-     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitInnerClass}.
+     * Class inner name. See
+     * {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitInnerClass}.
      */
-    public abstract void visitInnerClass(
-        final String name,
-        final String outerName,
-        final String innerName,
-        final int access);
+    public abstract void visitInnerClass(final String name,
+            final String outerName, final String innerName, final int access);
 
     /**
-     * Class field.
-     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitField}.
+     * Class field. See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitField}.
      */
-    public abstract Printer visitField(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final Object value);
+    public abstract Printer visitField(final int access, final String name,
+            final String desc, final String signature, final Object value);
 
     /**
-     * Class method.
-     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitMethod}.
+     * Class method. See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitMethod}.
      */
-    public abstract Printer visitMethod(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final String[] exceptions);
+    public abstract Printer visitMethod(final int access, final String name,
+            final String desc, final String signature, final String[] exceptions);
 
     /**
-     * Class end.
-     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitEnd}.
+     * Class end. See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitEnd}.
      */
     public abstract void visitClassEnd();
 
@@ -261,37 +248,31 @@
     // ------------------------------------------------------------------------
 
     /**
-     * Annotation value.
-     * See {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visit}.
+     * Annotation value. See {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visit}.
      */
     public abstract void visit(final String name, final Object value);
 
     /**
-     * Annotation enum value.
-     * See {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visitEnum}.
+     * Annotation enum value. See
+     * {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visitEnum}.
      */
-    public abstract void visitEnum(
-        final String name,
-        final String desc,
-        final String value);
+    public abstract void visitEnum(final String name, final String desc,
+            final String value);
 
     /**
-     * Nested annotation value.
-     * See {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visitAnnotation}.
+     * Nested annotation value. See
+     * {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visitAnnotation}.
      */
-    public abstract Printer visitAnnotation(
-        final String name,
-        final String desc);
+    public abstract Printer visitAnnotation(final String name, final String desc);
 
     /**
-     * Annotation array value.
-     * See {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visitArray}.
+     * Annotation array value. See
+     * {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visitArray}.
      */
     public abstract Printer visitArray(final String name);
 
     /**
-     * Annotation end.
-     * See {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visitEnd}.
+     * Annotation end. See {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visitEnd}.
      */
     public abstract void visitAnnotationEnd();
 
@@ -300,22 +281,29 @@
     // ------------------------------------------------------------------------
 
     /**
-     * Field annotation.
-     * See {@link jdk.internal.org.objectweb.asm.FieldVisitor#visitAnnotation}.
+     * Field annotation. See
+     * {@link jdk.internal.org.objectweb.asm.FieldVisitor#visitAnnotation}.
      */
-    public abstract Printer visitFieldAnnotation(
-        final String desc,
-        final boolean visible);
+    public abstract Printer visitFieldAnnotation(final String desc,
+            final boolean visible);
 
     /**
-     * Field attribute.
-     * See {@link jdk.internal.org.objectweb.asm.FieldVisitor#visitAttribute}.
+     * Field type annotation. See
+     * {@link jdk.internal.org.objectweb.asm.FieldVisitor#visitTypeAnnotation}.
+     */
+    public Printer visitFieldTypeAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    /**
+     * Field attribute. See
+     * {@link jdk.internal.org.objectweb.asm.FieldVisitor#visitAttribute}.
      */
     public abstract void visitFieldAttribute(final Attribute attr);
 
     /**
-     * Field end.
-     * See {@link jdk.internal.org.objectweb.asm.FieldVisitor#visitEnd}.
+     * Field end. See {@link jdk.internal.org.objectweb.asm.FieldVisitor#visitEnd}.
      */
     public abstract void visitFieldEnd();
 
@@ -324,193 +312,206 @@
     // ------------------------------------------------------------------------
 
     /**
-     * Method default annotation.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitAnnotationDefault}.
+     * Method parameter. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitParameter(String, int)}.
+     */
+    public void visitParameter(String name, int access) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    /**
+     * Method default annotation. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitAnnotationDefault}.
      */
     public abstract Printer visitAnnotationDefault();
 
     /**
-     * Method annotation.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitAnnotation}.
+     * Method annotation. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitAnnotation}.
      */
-    public abstract Printer visitMethodAnnotation(
-        final String desc,
-        final boolean visible);
+    public abstract Printer visitMethodAnnotation(final String desc,
+            final boolean visible);
 
     /**
-     * Method parameter annotation.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitParameterAnnotation}.
+     * Method type annotation. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTypeAnnotation}.
      */
-    public abstract Printer visitParameterAnnotation(
-        final int parameter,
-        final String desc,
-        final boolean visible);
+    public Printer visitMethodTypeAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        throw new RuntimeException("Must be overriden");
+    }
 
     /**
-     * Method attribute.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitAttribute}.
+     * Method parameter annotation. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitParameterAnnotation}.
+     */
+    public abstract Printer visitParameterAnnotation(final int parameter,
+            final String desc, final boolean visible);
+
+    /**
+     * Method attribute. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitAttribute}.
      */
     public abstract void visitMethodAttribute(final Attribute attr);
 
     /**
-     * Method start.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitCode}.
+     * Method start. See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitCode}.
      */
     public abstract void visitCode();
 
     /**
-     * Method stack frame.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitFrame}.
+     * Method stack frame. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitFrame}.
      */
-    public abstract void visitFrame(
-        final int type,
-        final int nLocal,
-        final Object[] local,
-        final int nStack,
-        final Object[] stack);
+    public abstract void visitFrame(final int type, final int nLocal,
+            final Object[] local, final int nStack, final Object[] stack);
 
     /**
-     * Method instruction.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitInsn}.
+     * Method instruction. See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitInsn}
+     * .
      */
     public abstract void visitInsn(final int opcode);
 
     /**
-     * Method instruction.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitIntInsn}.
+     * Method instruction. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitIntInsn}.
      */
     public abstract void visitIntInsn(final int opcode, final int operand);
 
     /**
-     * Method instruction.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitVarInsn}.
+     * Method instruction. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitVarInsn}.
      */
     public abstract void visitVarInsn(final int opcode, final int var);
 
     /**
-     * Method instruction.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTypeInsn}.
+     * Method instruction. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTypeInsn}.
      */
     public abstract void visitTypeInsn(final int opcode, final String type);
 
     /**
-     * Method instruction.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitFieldInsn}.
+     * Method instruction. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitFieldInsn}.
      */
-    public abstract void visitFieldInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc);
+    public abstract void visitFieldInsn(final int opcode, final String owner,
+            final String name, final String desc);
 
     /**
-     * Method instruction.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitMethodInsn}.
+     * Method instruction. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitMethodInsn}.
      */
-    public abstract void visitMethodInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc);
+    public abstract void visitMethodInsn(final int opcode, final String owner,
+            final String name, final String desc);
 
     /**
-     * Method instruction.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitInvokeDynamicInsn}.
+     * Method instruction. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitInvokeDynamicInsn}.
      */
-    public abstract void visitInvokeDynamicInsn(
-        String name,
-        String desc,
-        Handle bsm,
-        Object... bsmArgs);
+    public abstract void visitInvokeDynamicInsn(String name, String desc,
+            Handle bsm, Object... bsmArgs);
 
     /**
-     * Method instruction.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitJumpInsn}.
+     * Method instruction. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitJumpInsn}.
      */
     public abstract void visitJumpInsn(final int opcode, final Label label);
 
     /**
-     * Method label.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLabel}.
+     * Method label. See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLabel}.
      */
     public abstract void visitLabel(final Label label);
 
     /**
-     * Method instruction.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLdcInsn}.
+     * Method instruction. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLdcInsn}.
      */
     public abstract void visitLdcInsn(final Object cst);
 
     /**
-     * Method instruction.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitIincInsn}.
+     * Method instruction. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitIincInsn}.
      */
     public abstract void visitIincInsn(final int var, final int increment);
 
     /**
-     * Method instruction.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTableSwitchInsn}.
+     * Method instruction. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTableSwitchInsn}.
      */
-    public abstract void visitTableSwitchInsn(
-        final int min,
-        final int max,
-        final Label dflt,
-        final Label... labels);
+    public abstract void visitTableSwitchInsn(final int min, final int max,
+            final Label dflt, final Label... labels);
 
     /**
-     * Method instruction.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLookupSwitchInsn}.
+     * Method instruction. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLookupSwitchInsn}.
      */
-    public abstract void visitLookupSwitchInsn(
-        final Label dflt,
-        final int[] keys,
-        final Label[] labels);
+    public abstract void visitLookupSwitchInsn(final Label dflt,
+            final int[] keys, final Label[] labels);
 
     /**
-     * Method instruction.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitMultiANewArrayInsn}.
+     * Method instruction. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitMultiANewArrayInsn}.
      */
-    public abstract void visitMultiANewArrayInsn(
-        final String desc,
-        final int dims);
+    public abstract void visitMultiANewArrayInsn(final String desc,
+            final int dims);
 
     /**
-     * Method exception handler.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTryCatchBlock}.
+     * Instruction type annotation. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitInsnAnnotation}.
      */
-    public abstract void visitTryCatchBlock(
-        final Label start,
-        final Label end,
-        final Label handler,
-        final String type);
+    public Printer visitInsnAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        throw new RuntimeException("Must be overriden");
+    }
 
     /**
-     * Method debug info.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLocalVariable}.
+     * Method exception handler. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTryCatchBlock}.
      */
-    public abstract void visitLocalVariable(
-        final String name,
-        final String desc,
-        final String signature,
-        final Label start,
-        final Label end,
-        final int index);
+    public abstract void visitTryCatchBlock(final Label start, final Label end,
+            final Label handler, final String type);
 
     /**
-     * Method debug info.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLineNumber}.
+     * Try catch block type annotation. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTryCatchAnnotation}.
+     */
+    public Printer visitTryCatchAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    /**
+     * Method debug info. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLocalVariable}.
+     */
+    public abstract void visitLocalVariable(final String name,
+            final String desc, final String signature, final Label start,
+            final Label end, final int index);
+
+    /**
+     * Local variable type annotation. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTryCatchAnnotation}.
+     */
+    public Printer visitLocalVariableAnnotation(final int typeRef,
+            final TypePath typePath, final Label[] start, final Label[] end,
+            final int[] index, final String desc, final boolean visible) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    /**
+     * Method debug info. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLineNumber}.
      */
     public abstract void visitLineNumber(final int line, final Label start);
 
     /**
-     * Method max stack and max locals.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitMaxs}.
+     * Method max stack and max locals. See
+     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitMaxs}.
      */
     public abstract void visitMaxs(final int maxStack, final int maxLocals);
 
     /**
-     * Method end.
-     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitEnd}.
+     * Method end. See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitEnd}.
      */
     public abstract void visitMethodEnd();
 
@@ -526,7 +527,8 @@
     /**
      * Prints the text constructed by this visitor.
      *
-     * @param pw the print writer to be used.
+     * @param pw
+     *            the print writer to be used.
      */
     public void print(final PrintWriter pw) {
         printList(pw, text);
@@ -535,8 +537,10 @@
     /**
      * Appends a quoted string to a given buffer.
      *
-     * @param buf the buffer where the string must be added.
-     * @param s the string to be added.
+     * @param buf
+     *            the buffer where the string must be added.
+     * @param s
+     *            the string to be added.
      */
     public static void appendString(final StringBuffer buf, final String s) {
         buf.append('\"');
@@ -570,9 +574,11 @@
     /**
      * Prints the given string tree.
      *
-     * @param pw the writer to be used to print the tree.
-     * @param l a string tree, i.e., a string list that can contain other string
-     *        lists, and so on recursively.
+     * @param pw
+     *            the writer to be used to print the tree.
+     * @param l
+     *            a string tree, i.e., a string list that can contain other
+     *            string lists, and so on recursively.
      */
     static void printList(final PrintWriter pw, final List<?> l) {
         for (int i = 0; i < l.size(); ++i) {
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/Textifiable.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/Textifiable.java
index 1a78998..e278277 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/Textifiable.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/Textifiable.java
@@ -22,7 +22,7 @@
  * questions.
  */
 
-/*
+/**
  * This file is available under and governed by the GNU General Public
  * License version 2 only, as published by the Free Software Foundation.
  * However, the following notice accompanied the original version of this
@@ -76,8 +76,10 @@
     /**
      * Build a human readable representation of this attribute.
      *
-     * @param buf a buffer used for printing Java code.
-     * @param labelNames map of label instances to their names.
+     * @param buf
+     *            a buffer used for printing Java code.
+     * @param labelNames
+     *            map of label instances to their names.
      */
     void textify(StringBuffer buf, Map<Label, String> labelNames);
 }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java
index b96d241..3c039ce 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java
@@ -69,6 +69,8 @@
 import jdk.internal.org.objectweb.asm.Label;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.Type;
+import jdk.internal.org.objectweb.asm.TypePath;
+import jdk.internal.org.objectweb.asm.TypeReference;
 import jdk.internal.org.objectweb.asm.signature.SignatureReader;
 
 /**
@@ -172,28 +174,30 @@
      * version.
      */
     public Textifier() {
-        this(Opcodes.ASM4);
+        this(Opcodes.ASM5);
     }
 
     /**
      * Constructs a new {@link Textifier}.
      *
-     * @param api the ASM API version implemented by this visitor. Must be one
-     *        of {@link Opcodes#ASM4}.
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
      */
     protected Textifier(final int api) {
         super(api);
     }
 
     /**
-     * Prints a disassembled view of the given class to the standard output. <p>
-     * Usage: Textifier [-debug] &lt;binary class name or class
-     * file name &gt;
+     * Prints a disassembled view of the given class to the standard output.
+     * <p>
+     * Usage: Textifier [-debug] &lt;binary class name or class file name &gt;
      *
-     * @param args the command line arguments.
+     * @param args
+     *            the command line arguments.
      *
-     * @throws Exception if the class cannot be found, or if an IO exception
-     *         occurs.
+     * @throws Exception
+     *             if the class cannot be found, or if an IO exception occurs.
      */
     public static void main(final String[] args) throws Exception {
         int i = 0;
@@ -211,21 +215,20 @@
             }
         }
         if (!ok) {
-            System.err.println("Prints a disassembled view of the given class.");
+            System.err
+                    .println("Prints a disassembled view of the given class.");
             System.err.println("Usage: Textifier [-debug] "
                     + "<fully qualified class name or class file name>");
             return;
         }
         ClassReader cr;
         if (args[i].endsWith(".class") || args[i].indexOf('\\') > -1
-                || args[i].indexOf('/') > -1)
-        {
+                || args[i].indexOf('/') > -1) {
             cr = new ClassReader(new FileInputStream(args[i]));
         } else {
             cr = new ClassReader(args[i]);
         }
-        cr.accept(new TraceClassVisitor(new PrintWriter(System.out)),
-                flags);
+        cr.accept(new TraceClassVisitor(new PrintWriter(System.out)), flags);
     }
 
     // ------------------------------------------------------------------------
@@ -233,38 +236,27 @@
     // ------------------------------------------------------------------------
 
     @Override
-    public void visit(
-        final int version,
-        final int access,
-        final String name,
-        final String signature,
-        final String superName,
-        final String[] interfaces)
-    {
+    public void visit(final int version, final int access, final String name,
+            final String signature, final String superName,
+            final String[] interfaces) {
         int major = version & 0xFFFF;
         int minor = version >>> 16;
         buf.setLength(0);
-        buf.append("// class version ")
-                .append(major)
-                .append('.')
-                .append(minor)
-                .append(" (")
-                .append(version)
-                .append(")\n");
+        buf.append("// class version ").append(major).append('.').append(minor)
+                .append(" (").append(version).append(")\n");
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             buf.append("// DEPRECATED\n");
         }
-        buf.append("// access flags 0x").append(Integer.toHexString(access).toUpperCase()).append('\n');
+        buf.append("// access flags 0x")
+                .append(Integer.toHexString(access).toUpperCase()).append('\n');
 
         appendDescriptor(CLASS_SIGNATURE, signature);
         if (signature != null) {
             TraceSignatureVisitor sv = new TraceSignatureVisitor(access);
             SignatureReader r = new SignatureReader(signature);
             r.accept(sv);
-            buf.append("// declaration: ")
-                    .append(name)
-                    .append(sv.getDeclaration())
-                    .append('\n');
+            buf.append("// declaration: ").append(name)
+                    .append(sv.getDeclaration()).append('\n');
         }
 
         appendAccess(access & ~Opcodes.ACC_SUPER);
@@ -298,15 +290,11 @@
     public void visitSource(final String file, final String debug) {
         buf.setLength(0);
         if (file != null) {
-            buf.append(tab)
-                    .append("// compiled from: ")
-                    .append(file)
+            buf.append(tab).append("// compiled from: ").append(file)
                     .append('\n');
         }
         if (debug != null) {
-            buf.append(tab)
-                    .append("// debug info: ")
-                    .append(debug)
+            buf.append(tab).append("// debug info: ").append(debug)
                     .append('\n');
         }
         if (buf.length() > 0) {
@@ -315,11 +303,8 @@
     }
 
     @Override
-    public void visitOuterClass(
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitOuterClass(final String owner, final String name,
+            final String desc) {
         buf.setLength(0);
         buf.append(tab).append("OUTERCLASS ");
         appendDescriptor(INTERNAL_NAME, owner);
@@ -333,30 +318,33 @@
     }
 
     @Override
-    public Textifier visitClassAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public Textifier visitClassAnnotation(final String desc,
+            final boolean visible) {
         text.add("\n");
         return visitAnnotation(desc, visible);
     }
 
     @Override
+    public Printer visitClassTypeAnnotation(int typeRef, TypePath typePath,
+            String desc, boolean visible) {
+        text.add("\n");
+        return visitTypeAnnotation(typeRef, typePath, desc, visible);
+    }
+
+    @Override
     public void visitClassAttribute(final Attribute attr) {
         text.add("\n");
         visitAttribute(attr);
     }
 
     @Override
-    public void visitInnerClass(
-        final String name,
-        final String outerName,
-        final String innerName,
-        final int access)
-    {
+    public void visitInnerClass(final String name, final String outerName,
+            final String innerName, final int access) {
         buf.setLength(0);
         buf.append(tab).append("// access flags 0x");
-        buf.append(Integer.toHexString(access & ~Opcodes.ACC_SUPER).toUpperCase()).append('\n');
+        buf.append(
+                Integer.toHexString(access & ~Opcodes.ACC_SUPER).toUpperCase())
+                .append('\n');
         buf.append(tab);
         appendAccess(access);
         buf.append("INNERCLASS ");
@@ -370,19 +358,15 @@
     }
 
     @Override
-    public Textifier visitField(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final Object value)
-    {
+    public Textifier visitField(final int access, final String name,
+            final String desc, final String signature, final Object value) {
         buf.setLength(0);
         buf.append('\n');
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             buf.append(tab).append("// DEPRECATED\n");
         }
-        buf.append(tab).append("// access flags 0x").append(Integer.toHexString(access).toUpperCase()).append('\n');
+        buf.append(tab).append("// access flags 0x")
+                .append(Integer.toHexString(access).toUpperCase()).append('\n');
         if (signature != null) {
             buf.append(tab);
             appendDescriptor(FIELD_SIGNATURE, signature);
@@ -390,10 +374,8 @@
             TraceSignatureVisitor sv = new TraceSignatureVisitor(0);
             SignatureReader r = new SignatureReader(signature);
             r.acceptType(sv);
-            buf.append(tab)
-                    .append("// declaration: ")
-                    .append(sv.getDeclaration())
-                    .append('\n');
+            buf.append(tab).append("// declaration: ")
+                    .append(sv.getDeclaration()).append('\n');
         }
 
         buf.append(tab);
@@ -419,19 +401,15 @@
     }
 
     @Override
-    public Textifier visitMethod(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final String[] exceptions)
-    {
+    public Textifier visitMethod(final int access, final String name,
+            final String desc, final String signature, final String[] exceptions) {
         buf.setLength(0);
         buf.append('\n');
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             buf.append(tab).append("// DEPRECATED\n");
         }
-        buf.append(tab).append("// access flags 0x").append(Integer.toHexString(access).toUpperCase()).append('\n');
+        buf.append(tab).append("// access flags 0x")
+                .append(Integer.toHexString(access).toUpperCase()).append('\n');
 
         if (signature != null) {
             buf.append(tab);
@@ -444,12 +422,8 @@
             String genericReturn = v.getReturnType();
             String genericExceptions = v.getExceptions();
 
-            buf.append(tab)
-                    .append("// declaration: ")
-                    .append(genericReturn)
-                    .append(' ')
-                    .append(name)
-                    .append(genericDecl);
+            buf.append(tab).append("// declaration: ").append(genericReturn)
+                    .append(' ').append(name).append(genericDecl);
             if (genericExceptions != null) {
                 buf.append(" throws ").append(genericExceptions);
             }
@@ -622,11 +596,8 @@
     }
 
     @Override
-    public void visitEnum(
-        final String name,
-        final String desc,
-        final String value)
-    {
+    public void visitEnum(final String name, final String desc,
+            final String value) {
         buf.setLength(0);
         appendComa(valueNumber++);
         if (name != null) {
@@ -638,10 +609,7 @@
     }
 
     @Override
-    public Textifier visitAnnotation(
-        final String name,
-        final String desc)
-    {
+    public Textifier visitAnnotation(final String name, final String desc) {
         buf.setLength(0);
         appendComa(valueNumber++);
         if (name != null) {
@@ -658,9 +626,7 @@
     }
 
     @Override
-    public Textifier visitArray(
-        final String name)
-    {
+    public Textifier visitArray(final String name) {
         buf.setLength(0);
         appendComa(valueNumber++);
         if (name != null) {
@@ -683,14 +649,18 @@
     // ------------------------------------------------------------------------
 
     @Override
-    public Textifier visitFieldAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public Textifier visitFieldAnnotation(final String desc,
+            final boolean visible) {
         return visitAnnotation(desc, visible);
     }
 
     @Override
+    public Printer visitFieldTypeAnnotation(int typeRef, TypePath typePath,
+            String desc, boolean visible) {
+        return visitTypeAnnotation(typeRef, typePath, desc, visible);
+    }
+
+    @Override
     public void visitFieldAttribute(final Attribute attr) {
         visitAttribute(attr);
     }
@@ -704,6 +674,16 @@
     // ------------------------------------------------------------------------
 
     @Override
+    public void visitParameter(final String name, final int access) {
+        buf.setLength(0);
+        buf.append(tab2).append("// parameter ");
+        appendAccess(access);
+        buf.append(' ').append((name == null) ? "<no name>" : name)
+                .append('\n');
+        text.add(buf.toString());
+    }
+
+    @Override
     public Textifier visitAnnotationDefault() {
         text.add(tab2 + "default=");
         Textifier t = createTextifier();
@@ -713,19 +693,20 @@
     }
 
     @Override
-    public Textifier visitMethodAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public Textifier visitMethodAnnotation(final String desc,
+            final boolean visible) {
         return visitAnnotation(desc, visible);
     }
 
     @Override
-    public Textifier visitParameterAnnotation(
-        final int parameter,
-        final String desc,
-        final boolean visible)
-    {
+    public Printer visitMethodTypeAnnotation(int typeRef, TypePath typePath,
+            String desc, boolean visible) {
+        return visitTypeAnnotation(typeRef, typePath, desc, visible);
+    }
+
+    @Override
+    public Textifier visitParameterAnnotation(final int parameter,
+            final String desc, final boolean visible) {
         buf.setLength(0);
         buf.append(tab2).append('@');
         appendDescriptor(FIELD_DESCRIPTOR, desc);
@@ -759,40 +740,35 @@
     }
 
     @Override
-    public void visitFrame(
-        final int type,
-        final int nLocal,
-        final Object[] local,
-        final int nStack,
-        final Object[] stack)
-    {
+    public void visitFrame(final int type, final int nLocal,
+            final Object[] local, final int nStack, final Object[] stack) {
         buf.setLength(0);
         buf.append(ltab);
         buf.append("FRAME ");
         switch (type) {
-            case Opcodes.F_NEW:
-            case Opcodes.F_FULL:
-                buf.append("FULL [");
-                appendFrameTypes(nLocal, local);
-                buf.append("] [");
-                appendFrameTypes(nStack, stack);
-                buf.append(']');
-                break;
-            case Opcodes.F_APPEND:
-                buf.append("APPEND [");
-                appendFrameTypes(nLocal, local);
-                buf.append(']');
-                break;
-            case Opcodes.F_CHOP:
-                buf.append("CHOP ").append(nLocal);
-                break;
-            case Opcodes.F_SAME:
-                buf.append("SAME");
-                break;
-            case Opcodes.F_SAME1:
-                buf.append("SAME1 ");
-                appendFrameTypes(1, stack);
-                break;
+        case Opcodes.F_NEW:
+        case Opcodes.F_FULL:
+            buf.append("FULL [");
+            appendFrameTypes(nLocal, local);
+            buf.append("] [");
+            appendFrameTypes(nStack, stack);
+            buf.append(']');
+            break;
+        case Opcodes.F_APPEND:
+            buf.append("APPEND [");
+            appendFrameTypes(nLocal, local);
+            buf.append(']');
+            break;
+        case Opcodes.F_CHOP:
+            buf.append("CHOP ").append(nLocal);
+            break;
+        case Opcodes.F_SAME:
+            buf.append("SAME");
+            break;
+        case Opcodes.F_SAME1:
+            buf.append("SAME1 ");
+            appendFrameTypes(1, stack);
+            break;
         }
         buf.append('\n');
         text.add(buf.toString());
@@ -811,20 +787,15 @@
         buf.append(tab2)
                 .append(OPCODES[opcode])
                 .append(' ')
-                .append(opcode == Opcodes.NEWARRAY
-                        ? TYPES[operand]
-                        : Integer.toString(operand))
-                .append('\n');
+                .append(opcode == Opcodes.NEWARRAY ? TYPES[operand] : Integer
+                        .toString(operand)).append('\n');
         text.add(buf.toString());
     }
 
     @Override
     public void visitVarInsn(final int opcode, final int var) {
         buf.setLength(0);
-        buf.append(tab2)
-                .append(OPCODES[opcode])
-                .append(' ')
-                .append(var)
+        buf.append(tab2).append(OPCODES[opcode]).append(' ').append(var)
                 .append('\n');
         text.add(buf.toString());
     }
@@ -839,12 +810,8 @@
     }
 
     @Override
-    public void visitFieldInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitFieldInsn(final int opcode, final String owner,
+            final String name, final String desc) {
         buf.setLength(0);
         buf.append(tab2).append(OPCODES[opcode]).append(' ');
         appendDescriptor(INTERNAL_NAME, owner);
@@ -855,12 +822,8 @@
     }
 
     @Override
-    public void visitMethodInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitMethodInsn(final int opcode, final String owner,
+            final String name, final String desc) {
         buf.setLength(0);
         buf.append(tab2).append(OPCODES[opcode]).append(' ');
         appendDescriptor(INTERNAL_NAME, owner);
@@ -871,12 +834,8 @@
     }
 
     @Override
-    public void visitInvokeDynamicInsn(
-        String name,
-        String desc,
-        Handle bsm,
-        Object... bsmArgs)
-    {
+    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+            Object... bsmArgs) {
         buf.setLength(0);
         buf.append(tab2).append("INVOKEDYNAMIC").append(' ');
         buf.append(name);
@@ -884,11 +843,11 @@
         buf.append(" [");
         appendHandle(bsm);
         buf.append(tab3).append("// arguments:");
-        if(bsmArgs.length == 0) {
+        if (bsmArgs.length == 0) {
             buf.append(" none");
         } else {
             buf.append('\n').append(tab3);
-            for(int i = 0; i < bsmArgs.length; i++) {
+            for (int i = 0; i < bsmArgs.length; i++) {
                 Object cst = bsmArgs[i];
                 if (cst instanceof String) {
                     Printer.appendString(buf, (String) cst);
@@ -944,22 +903,14 @@
     @Override
     public void visitIincInsn(final int var, final int increment) {
         buf.setLength(0);
-        buf.append(tab2)
-                .append("IINC ")
-                .append(var)
-                .append(' ')
-                .append(increment)
-                .append('\n');
+        buf.append(tab2).append("IINC ").append(var).append(' ')
+                .append(increment).append('\n');
         text.add(buf.toString());
     }
 
     @Override
-    public void visitTableSwitchInsn(
-        final int min,
-        final int max,
-        final Label dflt,
-        final Label... labels)
-    {
+    public void visitTableSwitchInsn(final int min, final int max,
+            final Label dflt, final Label... labels) {
         buf.setLength(0);
         buf.append(tab2).append("TABLESWITCH\n");
         for (int i = 0; i < labels.length; ++i) {
@@ -974,11 +925,8 @@
     }
 
     @Override
-    public void visitLookupSwitchInsn(
-        final Label dflt,
-        final int[] keys,
-        final Label[] labels)
-    {
+    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+            final Label[] labels) {
         buf.setLength(0);
         buf.append(tab2).append("LOOKUPSWITCH\n");
         for (int i = 0; i < labels.length; ++i) {
@@ -1002,12 +950,14 @@
     }
 
     @Override
-    public void visitTryCatchBlock(
-        final Label start,
-        final Label end,
-        final Label handler,
-        final String type)
-    {
+    public Printer visitInsnAnnotation(int typeRef, TypePath typePath,
+            String desc, boolean visible) {
+        return visitTypeAnnotation(typeRef, typePath, desc, visible);
+    }
+
+    @Override
+    public void visitTryCatchBlock(final Label start, final Label end,
+            final Label handler, final String type) {
         buf.setLength(0);
         buf.append(tab2).append("TRYCATCHBLOCK ");
         appendLabel(start);
@@ -1022,14 +972,28 @@
     }
 
     @Override
-    public void visitLocalVariable(
-        final String name,
-        final String desc,
-        final String signature,
-        final Label start,
-        final Label end,
-        final int index)
-    {
+    public Printer visitTryCatchAnnotation(int typeRef, TypePath typePath,
+            String desc, boolean visible) {
+        buf.setLength(0);
+        buf.append(tab2).append("TRYCATCHBLOCK @");
+        appendDescriptor(FIELD_DESCRIPTOR, desc);
+        buf.append('(');
+        text.add(buf.toString());
+        Textifier t = createTextifier();
+        text.add(t.getText());
+        buf.setLength(0);
+        buf.append(") : ");
+        appendTypeReference(typeRef);
+        buf.append(", ").append(typePath);
+        buf.append(visible ? "\n" : " // invisible\n");
+        text.add(buf.toString());
+        return t;
+    }
+
+    @Override
+    public void visitLocalVariable(final String name, final String desc,
+            final String signature, final Label start, final Label end,
+            final int index) {
         buf.setLength(0);
         buf.append(tab2).append("LOCALVARIABLE ").append(name).append(' ');
         appendDescriptor(FIELD_DESCRIPTOR, desc);
@@ -1046,15 +1010,40 @@
             TraceSignatureVisitor sv = new TraceSignatureVisitor(0);
             SignatureReader r = new SignatureReader(signature);
             r.acceptType(sv);
-            buf.append(tab2)
-                    .append("// declaration: ")
-                    .append(sv.getDeclaration())
-                    .append('\n');
+            buf.append(tab2).append("// declaration: ")
+                    .append(sv.getDeclaration()).append('\n');
         }
         text.add(buf.toString());
     }
 
     @Override
+    public Printer visitLocalVariableAnnotation(int typeRef, TypePath typePath,
+            Label[] start, Label[] end, int[] index, String desc,
+            boolean visible) {
+        buf.setLength(0);
+        buf.append(tab2).append("LOCALVARIABLE @");
+        appendDescriptor(FIELD_DESCRIPTOR, desc);
+        buf.append('(');
+        text.add(buf.toString());
+        Textifier t = createTextifier();
+        text.add(t.getText());
+        buf.setLength(0);
+        buf.append(") : ");
+        appendTypeReference(typeRef);
+        buf.append(", ").append(typePath);
+        for (int i = 0; i < start.length; ++i) {
+            buf.append(" [ ");
+            appendLabel(start[i]);
+            buf.append(" - ");
+            appendLabel(end[i]);
+            buf.append(" - ").append(index[i]).append(" ]");
+        }
+        buf.append(visible ? "\n" : " // invisible\n");
+        text.add(buf.toString());
+        return t;
+    }
+
+    @Override
     public void visitLineNumber(final int line, final Label start) {
         buf.setLength(0);
         buf.append(tab2).append("LINENUMBER ").append(line).append(' ');
@@ -1085,14 +1074,13 @@
     /**
      * Prints a disassembled view of the given annotation.
      *
-     * @param desc the class descriptor of the annotation class.
-     * @param visible <tt>true</tt> if the annotation is visible at runtime.
+     * @param desc
+     *            the class descriptor of the annotation class.
+     * @param visible
+     *            <tt>true</tt> if the annotation is visible at runtime.
      * @return a visitor to visit the annotation values.
      */
-    public Textifier visitAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public Textifier visitAnnotation(final String desc, final boolean visible) {
         buf.setLength(0);
         buf.append(tab).append('@');
         appendDescriptor(FIELD_DESCRIPTOR, desc);
@@ -1105,9 +1093,43 @@
     }
 
     /**
+     * Prints a disassembled view of the given type annotation.
+     *
+     * @param typeRef
+     *            a reference to the annotated type. See {@link TypeReference}.
+     * @param typePath
+     *            the path to the annotated type argument, wildcard bound, array
+     *            element type, or static inner type within 'typeRef'. May be
+     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
+     * @param desc
+     *            the class descriptor of the annotation class.
+     * @param visible
+     *            <tt>true</tt> if the annotation is visible at runtime.
+     * @return a visitor to visit the annotation values.
+     */
+    public Textifier visitTypeAnnotation(final int typeRef,
+            final TypePath typePath, final String desc, final boolean visible) {
+        buf.setLength(0);
+        buf.append(tab).append('@');
+        appendDescriptor(FIELD_DESCRIPTOR, desc);
+        buf.append('(');
+        text.add(buf.toString());
+        Textifier t = createTextifier();
+        text.add(t.getText());
+        buf.setLength(0);
+        buf.append(") : ");
+        appendTypeReference(typeRef);
+        buf.append(", ").append(typePath);
+        buf.append(visible ? "\n" : " // invisible\n");
+        text.add(buf.toString());
+        return t;
+    }
+
+    /**
      * Prints a disassembled view of the given attribute.
      *
-     * @param attr an attribute.
+     * @param attr
+     *            an attribute.
      */
     public void visitAttribute(final Attribute attr) {
         buf.setLength(0);
@@ -1140,15 +1162,16 @@
      * Appends an internal name, a type descriptor or a type signature to
      * {@link #buf buf}.
      *
-     * @param type indicates if desc is an internal name, a field descriptor, a
-     *        method descriptor, a class signature, ...
-     * @param desc an internal name, type descriptor, or type signature. May be
-     *        <tt>null</tt>.
+     * @param type
+     *            indicates if desc is an internal name, a field descriptor, a
+     *            method descriptor, a class signature, ...
+     * @param desc
+     *            an internal name, type descriptor, or type signature. May be
+     *            <tt>null</tt>.
      */
     protected void appendDescriptor(final int type, final String desc) {
         if (type == CLASS_SIGNATURE || type == FIELD_SIGNATURE
-                || type == METHOD_SIGNATURE)
-        {
+                || type == METHOD_SIGNATURE) {
             if (desc != null) {
                 buf.append("// signature ").append(desc).append('\n');
             }
@@ -1161,7 +1184,8 @@
      * Appends the name of the given label to {@link #buf buf}. Creates a new
      * label name if the given label does not yet have one.
      *
-     * @param l a label.
+     * @param l
+     *            a label.
      */
     protected void appendLabel(final Label l) {
         if (labelNames == null) {
@@ -1178,40 +1202,42 @@
     /**
      * Appends the information about the given handle to {@link #buf buf}.
      *
-     * @param h a handle, non null.
+     * @param h
+     *            a handle, non null.
      */
     protected void appendHandle(final Handle h) {
         buf.append('\n').append(tab3);
         int tag = h.getTag();
-        buf.append("// handle kind 0x").append(Integer.toHexString(tag)).append(" : ");
+        buf.append("// handle kind 0x").append(Integer.toHexString(tag))
+                .append(" : ");
         switch (tag) {
-            case Opcodes.H_GETFIELD:
-                buf.append("GETFIELD");
-                break;
-            case Opcodes.H_GETSTATIC:
-                buf.append("GETSTATIC");
-                break;
-            case Opcodes.H_PUTFIELD:
-                buf.append("PUTFIELD");
-                break;
-            case Opcodes.H_PUTSTATIC:
-                buf.append("PUTSTATIC");
-                break;
-            case Opcodes.H_INVOKEINTERFACE:
-                buf.append("INVOKEINTERFACE");
-                break;
-            case Opcodes.H_INVOKESPECIAL:
-                buf.append("INVOKESPECIAL");
-                break;
-            case Opcodes.H_INVOKESTATIC:
-                buf.append("INVOKESTATIC");
-                break;
-            case Opcodes.H_INVOKEVIRTUAL:
-                buf.append("INVOKEVIRTUAL");
-                break;
-            case Opcodes.H_NEWINVOKESPECIAL:
-                buf.append("NEWINVOKESPECIAL");
-                break;
+        case Opcodes.H_GETFIELD:
+            buf.append("GETFIELD");
+            break;
+        case Opcodes.H_GETSTATIC:
+            buf.append("GETSTATIC");
+            break;
+        case Opcodes.H_PUTFIELD:
+            buf.append("PUTFIELD");
+            break;
+        case Opcodes.H_PUTSTATIC:
+            buf.append("PUTSTATIC");
+            break;
+        case Opcodes.H_INVOKEINTERFACE:
+            buf.append("INVOKEINTERFACE");
+            break;
+        case Opcodes.H_INVOKESPECIAL:
+            buf.append("INVOKESPECIAL");
+            break;
+        case Opcodes.H_INVOKESTATIC:
+            buf.append("INVOKESTATIC");
+            break;
+        case Opcodes.H_INVOKEVIRTUAL:
+            buf.append("INVOKEVIRTUAL");
+            break;
+        case Opcodes.H_NEWINVOKESPECIAL:
+            buf.append("NEWINVOKESPECIAL");
+            break;
         }
         buf.append('\n');
         buf.append(tab3);
@@ -1224,10 +1250,11 @@
     }
 
     /**
-     * Appends a string representation of the given access modifiers to {@link
-     * #buf buf}.
+     * Appends a string representation of the given access modifiers to
+     * {@link #buf buf}.
      *
-     * @param access some access modifiers.
+     * @param access
+     *            some access modifiers.
      */
     private void appendAccess(final int access) {
         if ((access & Opcodes.ACC_PUBLIC) != 0) {
@@ -1260,6 +1287,12 @@
         if ((access & Opcodes.ACC_STRICT) != 0) {
             buf.append("strictfp ");
         }
+        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+            buf.append("synthetic ");
+        }
+        if ((access & Opcodes.ACC_MANDATED) != 0) {
+            buf.append("mandated ");
+        }
         if ((access & Opcodes.ACC_ENUM) != 0) {
             buf.append("enum ");
         }
@@ -1271,6 +1304,90 @@
         }
     }
 
+    private void appendTypeReference(final int typeRef) {
+        TypeReference ref = new TypeReference(typeRef);
+        switch (ref.getSort()) {
+        case TypeReference.CLASS_TYPE_PARAMETER:
+            buf.append("CLASS_TYPE_PARAMETER ").append(
+                    ref.getTypeParameterIndex());
+            break;
+        case TypeReference.METHOD_TYPE_PARAMETER:
+            buf.append("METHOD_TYPE_PARAMETER ").append(
+                    ref.getTypeParameterIndex());
+            break;
+        case TypeReference.CLASS_EXTENDS:
+            buf.append("CLASS_EXTENDS ").append(ref.getSuperTypeIndex());
+            break;
+        case TypeReference.CLASS_TYPE_PARAMETER_BOUND:
+            buf.append("CLASS_TYPE_PARAMETER_BOUND ")
+                    .append(ref.getTypeParameterIndex()).append(", ")
+                    .append(ref.getTypeParameterBoundIndex());
+            break;
+        case TypeReference.METHOD_TYPE_PARAMETER_BOUND:
+            buf.append("METHOD_TYPE_PARAMETER_BOUND ")
+                    .append(ref.getTypeParameterIndex()).append(", ")
+                    .append(ref.getTypeParameterBoundIndex());
+            break;
+        case TypeReference.FIELD:
+            buf.append("FIELD");
+            break;
+        case TypeReference.METHOD_RETURN:
+            buf.append("METHOD_RETURN");
+            break;
+        case TypeReference.METHOD_RECEIVER:
+            buf.append("METHOD_RECEIVER");
+            break;
+        case TypeReference.METHOD_FORMAL_PARAMETER:
+            buf.append("METHOD_FORMAL_PARAMETER ").append(
+                    ref.getFormalParameterIndex());
+            break;
+        case TypeReference.THROWS:
+            buf.append("THROWS ").append(ref.getExceptionIndex());
+            break;
+        case TypeReference.LOCAL_VARIABLE:
+            buf.append("LOCAL_VARIABLE");
+            break;
+        case TypeReference.RESOURCE_VARIABLE:
+            buf.append("RESOURCE_VARIABLE");
+            break;
+        case TypeReference.EXCEPTION_PARAMETER:
+            buf.append("EXCEPTION_PARAMETER ").append(
+                    ref.getTryCatchBlockIndex());
+            break;
+        case TypeReference.INSTANCEOF:
+            buf.append("INSTANCEOF");
+            break;
+        case TypeReference.NEW:
+            buf.append("NEW");
+            break;
+        case TypeReference.CONSTRUCTOR_REFERENCE:
+            buf.append("CONSTRUCTOR_REFERENCE");
+            break;
+        case TypeReference.METHOD_REFERENCE:
+            buf.append("METHOD_REFERENCE");
+            break;
+        case TypeReference.CAST:
+            buf.append("CAST ").append(ref.getTypeArgumentIndex());
+            break;
+        case TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
+            buf.append("CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT ").append(
+                    ref.getTypeArgumentIndex());
+            break;
+        case TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT:
+            buf.append("METHOD_INVOCATION_TYPE_ARGUMENT ").append(
+                    ref.getTypeArgumentIndex());
+            break;
+        case TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
+            buf.append("CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT ").append(
+                    ref.getTypeArgumentIndex());
+            break;
+        case TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT:
+            buf.append("METHOD_REFERENCE_TYPE_ARGUMENT ").append(
+                    ref.getTypeArgumentIndex());
+            break;
+        }
+    }
+
     private void appendFrameTypes(final int n, final Object[] o) {
         for (int i = 0; i < n; ++i) {
             if (i > 0) {
@@ -1285,27 +1402,27 @@
                 }
             } else if (o[i] instanceof Integer) {
                 switch (((Integer) o[i]).intValue()) {
-                    case 0:
-                        appendDescriptor(FIELD_DESCRIPTOR, "T");
-                        break;
-                    case 1:
-                        appendDescriptor(FIELD_DESCRIPTOR, "I");
-                        break;
-                    case 2:
-                        appendDescriptor(FIELD_DESCRIPTOR, "F");
-                        break;
-                    case 3:
-                        appendDescriptor(FIELD_DESCRIPTOR, "D");
-                        break;
-                    case 4:
-                        appendDescriptor(FIELD_DESCRIPTOR, "J");
-                        break;
-                    case 5:
-                        appendDescriptor(FIELD_DESCRIPTOR, "N");
-                        break;
-                    case 6:
-                        appendDescriptor(FIELD_DESCRIPTOR, "U");
-                        break;
+                case 0:
+                    appendDescriptor(FIELD_DESCRIPTOR, "T");
+                    break;
+                case 1:
+                    appendDescriptor(FIELD_DESCRIPTOR, "I");
+                    break;
+                case 2:
+                    appendDescriptor(FIELD_DESCRIPTOR, "F");
+                    break;
+                case 3:
+                    appendDescriptor(FIELD_DESCRIPTOR, "D");
+                    break;
+                case 4:
+                    appendDescriptor(FIELD_DESCRIPTOR, "J");
+                    break;
+                case 5:
+                    appendDescriptor(FIELD_DESCRIPTOR, "N");
+                    break;
+                case 6:
+                    appendDescriptor(FIELD_DESCRIPTOR, "U");
+                    break;
                 }
             } else {
                 appendLabel((Label) o[i]);
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceAnnotationVisitor.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceAnnotationVisitor.java
index a08a1a7..d521c2c 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceAnnotationVisitor.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceAnnotationVisitor.java
@@ -76,7 +76,7 @@
     }
 
     public TraceAnnotationVisitor(final AnnotationVisitor av, final Printer p) {
-        super(Opcodes.ASM4, av);
+        super(Opcodes.ASM5, av);
         this.p = p;
     }
 
@@ -87,33 +87,26 @@
     }
 
     @Override
-    public void visitEnum(
-        final String name,
-        final String desc,
-        final String value)
-    {
+    public void visitEnum(final String name, final String desc,
+            final String value) {
         p.visitEnum(name, desc, value);
         super.visitEnum(name, desc, value);
     }
 
     @Override
-    public AnnotationVisitor visitAnnotation(
-        final String name,
-        final String desc)
-    {
+    public AnnotationVisitor visitAnnotation(final String name,
+            final String desc) {
         Printer p = this.p.visitAnnotation(name, desc);
-        AnnotationVisitor av = this.av == null
-                ? null
-                : this.av.visitAnnotation(name, desc);
+        AnnotationVisitor av = this.av == null ? null : this.av
+                .visitAnnotation(name, desc);
         return new TraceAnnotationVisitor(av, p);
     }
 
     @Override
     public AnnotationVisitor visitArray(final String name) {
         Printer p = this.p.visitArray(name);
-        AnnotationVisitor av = this.av == null
-                ? null
-                : this.av.visitArray(name);
+        AnnotationVisitor av = this.av == null ? null : this.av
+                .visitArray(name);
         return new TraceAnnotationVisitor(av, p);
     }
 
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java
index fd2d66a..e927bff 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java
@@ -30,7 +30,6 @@
  *
  * ASM: a very small and fast Java bytecode manipulation framework
  * Copyright (c) 2000-2011 INRIA, France Telecom
- * Copyright (c) 2011 Google
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -67,15 +66,20 @@
 import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.TypePath;
 
 /**
  * A {@link ClassVisitor} that prints the classes it visits with a
  * {@link Printer}. This class visitor can be used in the middle of a class
  * visitor chain to trace the class that is visited at a given point in this
- * chain. This may be useful for debugging purposes. <p> The trace printed when
- * visiting the <tt>Hello</tt> class is the following: <p> <blockquote>
+ * chain. This may be useful for debugging purposes.
+ * <p>
+ * The trace printed when visiting the <tt>Hello</tt> class is the following:
+ * <p>
+ * <blockquote>
  *
- * <pre> // class version 49.0 (49) // access flags 0x21 public class Hello {
+ * <pre>
+ * // class version 49.0 (49) // access flags 0x21 public class Hello {
  *
  * // compiled from: Hello.java
  *
@@ -85,14 +89,21 @@
  * // access flags 0x9 public static main ([Ljava/lang/String;)V GETSTATIC
  * java/lang/System out Ljava/io/PrintStream; LDC &quot;hello&quot;
  * INVOKEVIRTUAL java/io/PrintStream println (Ljava/lang/String;)V RETURN
- * MAXSTACK = 2 MAXLOCALS = 1 } </pre>
+ * MAXSTACK = 2 MAXLOCALS = 1 }
+ * </pre>
  *
- * </blockquote> where <tt>Hello</tt> is defined by: <p> <blockquote>
+ * </blockquote> where <tt>Hello</tt> is defined by:
+ * <p>
+ * <blockquote>
  *
- * <pre> public class Hello {
+ * <pre>
+ * public class Hello {
  *
- * public static void main(String[] args) {
- * System.out.println(&quot;hello&quot;); } } </pre>
+ *     public static void main(String[] args) {
+ *         System.out.println(&quot;hello&quot;);
+ *     }
+ * }
+ * </pre>
  *
  * </blockquote>
  *
@@ -114,7 +125,8 @@
     /**
      * Constructs a new {@link TraceClassVisitor}.
      *
-     * @param pw the print writer to be used to print the class.
+     * @param pw
+     *            the print writer to be used to print the class.
      */
     public TraceClassVisitor(final PrintWriter pw) {
         this(null, pw);
@@ -123,9 +135,11 @@
     /**
      * Constructs a new {@link TraceClassVisitor}.
      *
-     * @param cv the {@link ClassVisitor} to which this visitor delegates calls.
-     *        May be <tt>null</tt>.
-     * @param pw the print writer to be used to print the class.
+     * @param cv
+     *            the {@link ClassVisitor} to which this visitor delegates
+     *            calls. May be <tt>null</tt>.
+     * @param pw
+     *            the print writer to be used to print the class.
      */
     public TraceClassVisitor(final ClassVisitor cv, final PrintWriter pw) {
         this(cv, new Textifier(), pw);
@@ -134,32 +148,27 @@
     /**
      * Constructs a new {@link TraceClassVisitor}.
      *
-     * @param cv the {@link ClassVisitor} to which this visitor delegates calls.
-     *        May be <tt>null</tt>.
-     * @param p the object that actually converts visit events into text.
-     * @param pw the print writer to be used to print the class. May be null if
-     *        you simply want to use the result via
-     *        {@link Printer#getText()}, instead of printing it.
+     * @param cv
+     *            the {@link ClassVisitor} to which this visitor delegates
+     *            calls. May be <tt>null</tt>.
+     * @param p
+     *            the object that actually converts visit events into text.
+     * @param pw
+     *            the print writer to be used to print the class. May be null if
+     *            you simply want to use the result via
+     *            {@link Printer#getText()}, instead of printing it.
      */
-    public TraceClassVisitor(
-        final ClassVisitor cv,
-        final Printer p,
-        final PrintWriter pw)
-    {
-        super(Opcodes.ASM4, cv);
+    public TraceClassVisitor(final ClassVisitor cv, final Printer p,
+            final PrintWriter pw) {
+        super(Opcodes.ASM5, cv);
         this.pw = pw;
         this.p = p;
     }
 
     @Override
-    public void visit(
-        final int version,
-        final int access,
-        final String name,
-        final String signature,
-        final String superName,
-        final String[] interfaces)
-    {
+    public void visit(final int version, final int access, final String name,
+            final String signature, final String superName,
+            final String[] interfaces) {
         p.visit(version, access, name, signature, superName, interfaces);
         super.visit(version, access, name, signature, superName, interfaces);
     }
@@ -171,20 +180,15 @@
     }
 
     @Override
-    public void visitOuterClass(
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitOuterClass(final String owner, final String name,
+            final String desc) {
         p.visitOuterClass(owner, name, desc);
         super.visitOuterClass(owner, name, desc);
     }
 
     @Override
-    public AnnotationVisitor visitAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public AnnotationVisitor visitAnnotation(final String desc,
+            final boolean visible) {
         Printer p = this.p.visitClassAnnotation(desc, visible);
         AnnotationVisitor av = cv == null ? null : cv.visitAnnotation(desc,
                 visible);
@@ -192,61 +196,44 @@
     }
 
     @Override
+    public AnnotationVisitor visitTypeAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        Printer p = this.p.visitClassTypeAnnotation(typeRef, typePath, desc,
+                visible);
+        AnnotationVisitor av = cv == null ? null : cv.visitTypeAnnotation(
+                typeRef, typePath, desc, visible);
+        return new TraceAnnotationVisitor(av, p);
+    }
+
+    @Override
     public void visitAttribute(final Attribute attr) {
         p.visitClassAttribute(attr);
         super.visitAttribute(attr);
     }
 
     @Override
-    public void visitInnerClass(
-        final String name,
-        final String outerName,
-        final String innerName,
-        final int access)
-    {
+    public void visitInnerClass(final String name, final String outerName,
+            final String innerName, final int access) {
         p.visitInnerClass(name, outerName, innerName, access);
         super.visitInnerClass(name, outerName, innerName, access);
     }
 
     @Override
-    public FieldVisitor visitField(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final Object value)
-    {
-        Printer p = this.p.visitField(access,
-                name,
-                desc,
-                signature,
-                value);
-        FieldVisitor fv = cv == null ? null : cv.visitField(access,
-                name,
-                desc,
-                signature,
-                value);
+    public FieldVisitor visitField(final int access, final String name,
+            final String desc, final String signature, final Object value) {
+        Printer p = this.p.visitField(access, name, desc, signature, value);
+        FieldVisitor fv = cv == null ? null : cv.visitField(access, name, desc,
+                signature, value);
         return new TraceFieldVisitor(fv, p);
     }
 
     @Override
-    public MethodVisitor visitMethod(
-        final int access,
-        final String name,
-        final String desc,
-        final String signature,
-        final String[] exceptions)
-    {
-        Printer p = this.p.visitMethod(access,
-                name,
-                desc,
-                signature,
+    public MethodVisitor visitMethod(final int access, final String name,
+            final String desc, final String signature, final String[] exceptions) {
+        Printer p = this.p.visitMethod(access, name, desc, signature,
                 exceptions);
-        MethodVisitor mv = cv == null ? null : cv.visitMethod(access,
-                name,
-                desc,
-                signature,
-                exceptions);
+        MethodVisitor mv = cv == null ? null : cv.visitMethod(access, name,
+                desc, signature, exceptions);
         return new TraceMethodVisitor(mv, p);
     }
 
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceFieldVisitor.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceFieldVisitor.java
index 2b4d8cb..4c15f99 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceFieldVisitor.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceFieldVisitor.java
@@ -30,7 +30,6 @@
  *
  * ASM: a very small and fast Java bytecode manipulation framework
  * Copyright (c) 2000-2011 INRIA, France Telecom
- * Copyright (c) 2011 Google
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -63,6 +62,7 @@
 import jdk.internal.org.objectweb.asm.Attribute;
 import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.TypePath;
 
 /**
  * A {@link FieldVisitor} that prints the fields it visits with a
@@ -79,15 +79,13 @@
     }
 
     public TraceFieldVisitor(final FieldVisitor fv, final Printer p) {
-        super(Opcodes.ASM4, fv);
+        super(Opcodes.ASM5, fv);
         this.p = p;
     }
 
     @Override
-    public AnnotationVisitor visitAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public AnnotationVisitor visitAnnotation(final String desc,
+            final boolean visible) {
         Printer p = this.p.visitFieldAnnotation(desc, visible);
         AnnotationVisitor av = fv == null ? null : fv.visitAnnotation(desc,
                 visible);
@@ -95,6 +93,16 @@
     }
 
     @Override
+    public AnnotationVisitor visitTypeAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        Printer p = this.p.visitFieldTypeAnnotation(typeRef, typePath, desc,
+                visible);
+        AnnotationVisitor av = fv == null ? null : fv.visitTypeAnnotation(
+                typeRef, typePath, desc, visible);
+        return new TraceAnnotationVisitor(av, p);
+    }
+
+    @Override
     public void visitAttribute(final Attribute attr) {
         p.visitFieldAttribute(attr);
         super.visitAttribute(attr);
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java
index c40964c..bf80e1f 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java
@@ -30,7 +30,6 @@
  *
  * ASM: a very small and fast Java bytecode manipulation framework
  * Copyright (c) 2000-2011 INRIA, France Telecom
- * Copyright (c) 2011 Google
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -65,6 +64,7 @@
 import jdk.internal.org.objectweb.asm.Label;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.TypePath;
 
 /**
  * A {@link MethodVisitor} that prints the methods it visits with a
@@ -81,15 +81,19 @@
     }
 
     public TraceMethodVisitor(final MethodVisitor mv, final Printer p) {
-        super(Opcodes.ASM4, mv);
+        super(Opcodes.ASM5, mv);
         this.p = p;
     }
 
     @Override
-    public AnnotationVisitor visitAnnotation(
-        final String desc,
-        final boolean visible)
-    {
+    public void visitParameter(String name, int access) {
+        p.visitParameter(name, access);
+        super.visitParameter(name, access);
+    }
+
+    @Override
+    public AnnotationVisitor visitAnnotation(final String desc,
+            final boolean visible) {
         Printer p = this.p.visitMethodAnnotation(desc, visible);
         AnnotationVisitor av = mv == null ? null : mv.visitAnnotation(desc,
                 visible);
@@ -97,6 +101,16 @@
     }
 
     @Override
+    public AnnotationVisitor visitTypeAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        Printer p = this.p.visitMethodTypeAnnotation(typeRef, typePath, desc,
+                visible);
+        AnnotationVisitor av = mv == null ? null : mv.visitTypeAnnotation(
+                typeRef, typePath, desc, visible);
+        return new TraceAnnotationVisitor(av, p);
+    }
+
+    @Override
     public void visitAttribute(final Attribute attr) {
         p.visitMethodAttribute(attr);
         super.visitAttribute(attr);
@@ -110,17 +124,11 @@
     }
 
     @Override
-    public AnnotationVisitor visitParameterAnnotation(
-        final int parameter,
-        final String desc,
-        final boolean visible)
-    {
-        Printer p = this.p.visitParameterAnnotation(parameter,
-                desc,
-                visible);
-        AnnotationVisitor av = mv == null
-                ? null
-                : mv.visitParameterAnnotation(parameter, desc, visible);
+    public AnnotationVisitor visitParameterAnnotation(final int parameter,
+            final String desc, final boolean visible) {
+        Printer p = this.p.visitParameterAnnotation(parameter, desc, visible);
+        AnnotationVisitor av = mv == null ? null : mv.visitParameterAnnotation(
+                parameter, desc, visible);
         return new TraceAnnotationVisitor(av, p);
     }
 
@@ -131,13 +139,8 @@
     }
 
     @Override
-    public void visitFrame(
-        final int type,
-        final int nLocal,
-        final Object[] local,
-        final int nStack,
-        final Object[] stack)
-    {
+    public void visitFrame(final int type, final int nLocal,
+            final Object[] local, final int nStack, final Object[] stack) {
         p.visitFrame(type, nLocal, local, nStack, stack);
         super.visitFrame(type, nLocal, local, nStack, stack);
     }
@@ -167,34 +170,22 @@
     }
 
     @Override
-    public void visitFieldInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitFieldInsn(final int opcode, final String owner,
+            final String name, final String desc) {
         p.visitFieldInsn(opcode, owner, name, desc);
         super.visitFieldInsn(opcode, owner, name, desc);
     }
 
     @Override
-    public void visitMethodInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
+    public void visitMethodInsn(final int opcode, final String owner,
+            final String name, final String desc) {
         p.visitMethodInsn(opcode, owner, name, desc);
         super.visitMethodInsn(opcode, owner, name, desc);
     }
 
     @Override
-    public void visitInvokeDynamicInsn(
-        String name,
-        String desc,
-        Handle bsm,
-        Object... bsmArgs)
-    {
+    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+            Object... bsmArgs) {
         p.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
         super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
     }
@@ -224,22 +215,15 @@
     }
 
     @Override
-    public void visitTableSwitchInsn(
-        final int min,
-        final int max,
-        final Label dflt,
-        final Label... labels)
-    {
+    public void visitTableSwitchInsn(final int min, final int max,
+            final Label dflt, final Label... labels) {
         p.visitTableSwitchInsn(min, max, dflt, labels);
         super.visitTableSwitchInsn(min, max, dflt, labels);
     }
 
     @Override
-    public void visitLookupSwitchInsn(
-        final Label dflt,
-        final int[] keys,
-        final Label[] labels)
-    {
+    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+            final Label[] labels) {
         p.visitLookupSwitchInsn(dflt, keys, labels);
         super.visitLookupSwitchInsn(dflt, keys, labels);
     }
@@ -251,30 +235,53 @@
     }
 
     @Override
-    public void visitTryCatchBlock(
-        final Label start,
-        final Label end,
-        final Label handler,
-        final String type)
-    {
+    public AnnotationVisitor visitInsnAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        Printer p = this.p
+                .visitInsnAnnotation(typeRef, typePath, desc, visible);
+        AnnotationVisitor av = mv == null ? null : mv.visitInsnAnnotation(
+                typeRef, typePath, desc, visible);
+        return new TraceAnnotationVisitor(av, p);
+    }
+
+    @Override
+    public void visitTryCatchBlock(final Label start, final Label end,
+            final Label handler, final String type) {
         p.visitTryCatchBlock(start, end, handler, type);
         super.visitTryCatchBlock(start, end, handler, type);
     }
 
     @Override
-    public void visitLocalVariable(
-        final String name,
-        final String desc,
-        final String signature,
-        final Label start,
-        final Label end,
-        final int index)
-    {
+    public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        Printer p = this.p.visitTryCatchAnnotation(typeRef, typePath, desc,
+                visible);
+        AnnotationVisitor av = mv == null ? null : mv.visitTryCatchAnnotation(
+                typeRef, typePath, desc, visible);
+        return new TraceAnnotationVisitor(av, p);
+    }
+
+    @Override
+    public void visitLocalVariable(final String name, final String desc,
+            final String signature, final Label start, final Label end,
+            final int index) {
         p.visitLocalVariable(name, desc, signature, start, end, index);
         super.visitLocalVariable(name, desc, signature, start, end, index);
     }
 
     @Override
+    public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
+            TypePath typePath, Label[] start, Label[] end, int[] index,
+            String desc, boolean visible) {
+        Printer p = this.p.visitLocalVariableAnnotation(typeRef, typePath,
+                start, end, index, desc, visible);
+        AnnotationVisitor av = mv == null ? null : mv
+                .visitLocalVariableAnnotation(typeRef, typePath, start, end,
+                        index, desc, visible);
+        return new TraceAnnotationVisitor(av, p);
+    }
+
+    @Override
     public void visitLineNumber(final int line, final Label start) {
         p.visitLineNumber(line, start);
         super.visitLineNumber(line, start);
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceSignatureVisitor.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceSignatureVisitor.java
index 8244bcf..f492584 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceSignatureVisitor.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceSignatureVisitor.java
@@ -104,13 +104,13 @@
     private String separator = "";
 
     public TraceSignatureVisitor(final int access) {
-        super(Opcodes.ASM4);
+        super(Opcodes.ASM5);
         isInterface = (access & Opcodes.ACC_INTERFACE) != 0;
         this.declaration = new StringBuffer();
     }
 
     private TraceSignatureVisitor(final StringBuffer buf) {
-        super(Opcodes.ASM4);
+        super(Opcodes.ASM5);
         this.declaration = buf;
     }
 
@@ -146,8 +146,7 @@
 
     @Override
     public SignatureVisitor visitInterface() {
-        separator = seenInterface ? ", " : isInterface
-                ? " extends "
+        separator = seenInterface ? ", " : isInterface ? " extends "
                 : " implements ";
         seenInterface = true;
         startType();
@@ -194,34 +193,34 @@
     @Override
     public void visitBaseType(final char descriptor) {
         switch (descriptor) {
-            case 'V':
-                declaration.append("void");
-                break;
-            case 'B':
-                declaration.append("byte");
-                break;
-            case 'J':
-                declaration.append("long");
-                break;
-            case 'Z':
-                declaration.append("boolean");
-                break;
-            case 'I':
-                declaration.append("int");
-                break;
-            case 'S':
-                declaration.append("short");
-                break;
-            case 'C':
-                declaration.append("char");
-                break;
-            case 'F':
-                declaration.append("float");
-                break;
-            // case 'D':
-            default:
-                declaration.append("double");
-                break;
+        case 'V':
+            declaration.append("void");
+            break;
+        case 'B':
+            declaration.append("byte");
+            break;
+        case 'J':
+            declaration.append("long");
+            break;
+        case 'Z':
+            declaration.append("boolean");
+            break;
+        case 'I':
+            declaration.append("int");
+            break;
+        case 'S':
+            declaration.append("short");
+            break;
+        case 'C':
+            declaration.append("char");
+            break;
+        case 'F':
+            declaration.append("float");
+            break;
+        // case 'D':
+        default:
+            declaration.append("double");
+            break;
         }
         endType();
     }
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/version.txt b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/version.txt
new file mode 100644
index 0000000..d795ab2
--- /dev/null
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/version.txt
@@ -0,0 +1,12 @@
+Path: .
+Working Copy Root Path: /w/lthudson/hudson-data/jobs/objectweb-cr-pull/workspace/ASM_5_FUTURE
+URL: svn://svn.forge.objectweb.org/svnroot/asm/branches/ASM_5_FUTURE
+Repository Root: svn://svn.forge.objectweb.org/svnroot/asm
+Repository UUID: 271bd773-ee82-43a6-9b2b-1890ed8ce7f9
+Revision: 1681
+Node Kind: directory
+Schedule: normal
+Last Changed Author: forax
+Last Changed Rev: 1681
+Last Changed Date: 2013-04-01 11:28:58 -0700 (Mon, 01 Apr 2013)
+
diff --git a/jdk/src/share/classes/sun/font/FileFontStrike.java b/jdk/src/share/classes/sun/font/FileFontStrike.java
index 6762241..2a8cde5 100644
--- a/jdk/src/share/classes/sun/font/FileFontStrike.java
+++ b/jdk/src/share/classes/sun/font/FileFontStrike.java
@@ -747,14 +747,9 @@
             return origMinX;
         }
 
-        long pixelData;
-        if (StrikeCache.nativeAddressSize == 4) {
-            pixelData = 0xffffffff &
-                StrikeCache.unsafe.getInt(ptr + StrikeCache.pixelDataOffset);
-        } else {
-            pixelData =
-                StrikeCache.unsafe.getLong(ptr + StrikeCache.pixelDataOffset);
-        }
+        long pixelData =
+            StrikeCache.unsafe.getAddress(ptr + StrikeCache.pixelDataOffset);
+
         if (pixelData == 0L) {
             return origMinX;
         }
diff --git a/jdk/src/share/classes/sun/font/GlyphList.java b/jdk/src/share/classes/sun/font/GlyphList.java
index c02c7c4..5044604 100644
--- a/jdk/src/share/classes/sun/font/GlyphList.java
+++ b/jdk/src/share/classes/sun/font/GlyphList.java
@@ -361,16 +361,10 @@
                 graybits = new byte[len];
             }
         }
-        long pixelDataAddress;
-        if (StrikeCache.nativeAddressSize == 4) {
-            pixelDataAddress = 0xffffffff &
-                StrikeCache.unsafe.getInt(images[glyphindex] +
+        long pixelDataAddress =
+            StrikeCache.unsafe.getAddress(images[glyphindex] +
                                           StrikeCache.pixelDataOffset);
-        } else {
-            pixelDataAddress =
-            StrikeCache.unsafe.getLong(images[glyphindex] +
-                                       StrikeCache.pixelDataOffset);
-        }
+
         if (pixelDataAddress == 0L) {
             return graybits;
         }
diff --git a/jdk/src/share/classes/sun/misc/JavaLangAccess.java b/jdk/src/share/classes/sun/misc/JavaLangAccess.java
index db8d821..888d4ea 100644
--- a/jdk/src/share/classes/sun/misc/JavaLangAccess.java
+++ b/jdk/src/share/classes/sun/misc/JavaLangAccess.java
@@ -97,4 +97,14 @@
      * Returns the ith StackTraceElement for the given throwable.
      */
     StackTraceElement getStackTraceElement(Throwable t, int i);
+
+    /**
+     * Returns a new string backed by the provided character array. The
+     * character array is not copied and must never be modified after the
+     * String is created, in order to fulfill String's contract.
+     *
+     * @param chars the character array to back the string
+     * @return a newly created string whose content is the character array
+     */
+    String newStringUnsafe(char[] chars);
 }
diff --git a/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java b/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java
index 69a9e65..c53eede 100644
--- a/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java
+++ b/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java
@@ -321,15 +321,7 @@
         public void run() {
             while (!finished) {
                 try {
-                    ListIterator<HttpConnection> li =
-                        connsToRegister.listIterator();
-                    for (HttpConnection c : connsToRegister) {
-                        reRegister(c);
-                    }
-                    connsToRegister.clear();
-
                     List<Event> list = null;
-                    selector.select(1000);
                     synchronized (lolock) {
                         if (events.size() > 0) {
                             list = events;
@@ -343,8 +335,14 @@
                         }
                     }
 
-                    /* process the selected list now  */
+                    for (HttpConnection c : connsToRegister) {
+                        reRegister(c);
+                    }
+                    connsToRegister.clear();
 
+                    selector.select(1000);
+
+                    /* process the selected list now  */
                     Set<SelectionKey> selected = selector.selectedKeys();
                     Iterator<SelectionKey> iter = selected.iterator();
                     while (iter.hasNext()) {
diff --git a/jdk/src/share/classes/sun/net/www/MessageHeader.java b/jdk/src/share/classes/sun/net/www/MessageHeader.java
index 3a46def..d6982b6 100644
--- a/jdk/src/share/classes/sun/net/www/MessageHeader.java
+++ b/jdk/src/share/classes/sun/net/www/MessageHeader.java
@@ -31,12 +31,7 @@
 
 import java.io.*;
 import java.util.Collections;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
+import java.util.*;
 
 /** An RFC 844 or MIME message header.  Includes methods
     for parsing headers from incoming streams, fetching
@@ -60,6 +55,17 @@
     }
 
     /**
+     * Returns list of header names in a comma separated list
+     */
+    public synchronized String getHeaderNamesInList() {
+        StringJoiner joiner = new StringJoiner(",");
+        for (int i=0; i<nkeys; i++) {
+            joiner.add(keys[i]);
+        }
+        return joiner.toString();
+    }
+
+    /**
      * Reset a message header (all key/values removed)
      */
     public synchronized void reset() {
diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
index 780e595..4e002e8 100644
--- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
@@ -36,6 +36,7 @@
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.net.SocketTimeoutException;
+import java.net.SocketPermission;
 import java.net.Proxy;
 import java.net.ProxySelector;
 import java.net.URI;
@@ -45,8 +46,13 @@
 import java.net.CacheResponse;
 import java.net.SecureCacheResponse;
 import java.net.CacheRequest;
+import java.net.HttpURLPermission;
 import java.net.Authenticator.RequestorType;
+import java.security.AccessController;
+import java.security.PrivilegedExceptionAction;
+import java.security.PrivilegedActionException;
 import java.io.*;
+import java.net.*;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
@@ -303,6 +309,19 @@
      */
     private MessageHeader requests;
 
+    /* The headers actually set by the user are recorded here also
+     */
+    private MessageHeader userHeaders;
+
+    /* Headers and request method cannot be changed
+     * once this flag is set in :-
+     *     - getOutputStream()
+     *     - getInputStream())
+     *     - connect()
+     * Access synchronized on this.
+     */
+    private boolean connecting = false;
+
     /* The following two fields are only used with Digest Authentication */
     String domain;      /* The list of authentication domains */
     DigestAuthentication.Parameters digestparams;
@@ -370,6 +389,9 @@
     private int connectTimeout = NetworkClient.DEFAULT_CONNECT_TIMEOUT;
     private int readTimeout = NetworkClient.DEFAULT_READ_TIMEOUT;
 
+    /* A permission converted from a HttpURLPermission */
+    private SocketPermission socketPermission;
+
     /* Logging support */
     private static final PlatformLogger logger =
             PlatformLogger.getLogger("sun.net.www.protocol.http.HttpURLConnection");
@@ -487,6 +509,14 @@
         }
     }
 
+    public synchronized void setRequestMethod(String method)
+                        throws ProtocolException {
+        if (connecting) {
+            throw new IllegalStateException("connect in progress");
+        }
+        super.setRequestMethod(method);
+    }
+
     /* adds the standard key/val pairs to reqests if necessary & write to
      * given PrintStream
      */
@@ -729,6 +759,7 @@
         super(u);
         requests = new MessageHeader();
         responses = new MessageHeader();
+        userHeaders = new MessageHeader();
         this.handler = handler;
         instProxy = p;
         if (instProxy instanceof sun.net.ApplicationProxy) {
@@ -849,6 +880,9 @@
     // overridden in HTTPS subclass
 
     public void connect() throws IOException {
+        synchronized (this) {
+            connecting = true;
+        }
         plainConnect();
     }
 
@@ -867,10 +901,86 @@
         return false;
     }
 
-    protected void plainConnect()  throws IOException {
-        if (connected) {
-            return;
+    private String getHostAndPort(URL url) {
+        String host = url.getHost();
+        int port = url.getPort();
+        if (port == -1) {
+            String scheme = url.getProtocol();
+            if ("http".equals(scheme)) {
+                return host + ":80";
+            } else { // scheme must be https
+                return host + ":443";
+            }
         }
+        return host + ":" + Integer.toString(port);
+    }
+
+    protected void plainConnect()  throws IOException {
+        synchronized (this) {
+            if (connected) {
+                return;
+            }
+        }
+        SocketPermission p = URLtoSocketPermission(this.url);
+        if (p != null) {
+            try {
+                AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<Void>() {
+                        public Void run() throws IOException {
+                            plainConnect0();
+                            return null;
+                        }
+                    }
+//                    }, null, p -- replace line above, when limited doPriv ready
+                );
+            } catch (PrivilegedActionException e) {
+                    throw (IOException) e.getException();
+            }
+        } else {
+            // run without additional permission
+            plainConnect0();
+        }
+    }
+
+    /**
+     *  if the caller has a HttpURLPermission for connecting to the
+     *  given URL, then return a SocketPermission which permits
+     *  access to that destination. Return null otherwise. The permission
+     *  is cached in a field (which can only be changed by redirects)
+     */
+    SocketPermission URLtoSocketPermission(URL url) throws IOException {
+
+        if (socketPermission != null) {
+            return socketPermission;
+        }
+
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm == null) {
+            return null;
+        }
+
+        // the permission, which we might grant
+
+        SocketPermission newPerm = new SocketPermission(
+            getHostAndPort(url), "connect"
+        );
+
+        String actions = getRequestMethod()+":" +
+                getUserSetHeaders().getHeaderNamesInList();
+
+        HttpURLPermission p = new HttpURLPermission(url.toString(), actions);
+        try {
+            sm.checkPermission(p);
+            socketPermission = newPerm;
+            return socketPermission;
+        } catch (SecurityException e) {
+            // fall thru
+        }
+        return null;
+    }
+
+    protected void plainConnect0()  throws IOException {
         // try to see if request can be served from local cache
         if (cacheHandler != null && getUseCaches()) {
             try {
@@ -1068,7 +1178,28 @@
 
     @Override
     public synchronized OutputStream getOutputStream() throws IOException {
+        connecting = true;
+        SocketPermission p = URLtoSocketPermission(this.url);
 
+        if (p != null) {
+            try {
+                return AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<OutputStream>() {
+                        public OutputStream run() throws IOException {
+                            return getOutputStream0();
+                        }
+                    }
+//                    }, null, p -- replace line above, when limited doPriv ready
+                );
+            } catch (PrivilegedActionException e) {
+                throw (IOException) e.getException();
+            }
+        } else {
+            return getOutputStream0();
+        }
+    }
+
+    private synchronized OutputStream getOutputStream0() throws IOException {
         try {
             if (!doOutput) {
                 throw new ProtocolException("cannot write to a URLConnection"
@@ -1094,7 +1225,7 @@
 
             boolean expectContinue = false;
             String expects = requests.findValue("Expect");
-            if ("100-Continue".equalsIgnoreCase(expects)) {
+            if ("100-Continue".equalsIgnoreCase(expects) && streaming()) {
                 http.setIgnoreContinue(false);
                 expectContinue = true;
             }
@@ -1231,8 +1362,30 @@
     }
 
     @Override
-    @SuppressWarnings("empty-statement")
     public synchronized InputStream getInputStream() throws IOException {
+        connecting = true;
+        SocketPermission p = URLtoSocketPermission(this.url);
+
+        if (p != null) {
+            try {
+                return AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<InputStream>() {
+                        public InputStream run() throws IOException {
+                            return getInputStream0();
+                        }
+                    }
+//                    }, null, p -- replace line above, when limited doPriv ready
+                );
+            } catch (PrivilegedActionException e) {
+                throw (IOException) e.getException();
+            }
+        } else {
+            return getInputStream0();
+        }
+    }
+
+    @SuppressWarnings("empty-statement")
+    private synchronized InputStream getInputStream0() throws IOException {
 
         if (!doInput) {
             throw new ProtocolException("Cannot read from URLConnection"
@@ -2319,18 +2472,19 @@
             return false;
         }
 
-        int stat = getResponseCode();
+        final int stat = getResponseCode();
         if (stat < 300 || stat > 307 || stat == 306
                                 || stat == HTTP_NOT_MODIFIED) {
             return false;
         }
-        String loc = getHeaderField("Location");
+        final String loc = getHeaderField("Location");
         if (loc == null) {
             /* this should be present - if not, we have no choice
              * but to go forward w/ the response we got
              */
             return false;
         }
+
         URL locUrl;
         try {
             locUrl = new URL(loc);
@@ -2342,6 +2496,38 @@
           // treat loc as a relative URI to conform to popular browsers
           locUrl = new URL(url, loc);
         }
+
+        final URL locUrl0 = locUrl;
+        socketPermission = null; // force recalculation
+        SocketPermission p = URLtoSocketPermission(locUrl);
+
+        if (p != null) {
+            try {
+                return AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<Boolean>() {
+                        public Boolean run() throws IOException {
+                            return followRedirect0(loc, stat, locUrl0);
+                        }
+                    }
+//                    }, null, p -- replace line above, when limited doPriv ready
+                );
+            } catch (PrivilegedActionException e) {
+                throw (IOException) e.getException();
+            }
+        } else {
+            // run without additional permission
+            return followRedirect0(loc, stat, locUrl);
+        }
+    }
+
+    /* Tells us whether to follow a redirect.  If so, it
+     * closes the connection (break any keep-alive) and
+     * resets the url, re-connects, and resets the request
+     * property.
+     */
+    private boolean followRedirect0(String loc, int stat, URL locUrl)
+        throws IOException
+    {
         disconnectInternal();
         if (streaming()) {
             throw new HttpRetryException (RETRY_MSG3, stat, loc);
@@ -2753,17 +2939,24 @@
      * @param value the value to be set
      */
     @Override
-    public void setRequestProperty(String key, String value) {
-        if (connected)
+    public synchronized void setRequestProperty(String key, String value) {
+        if (connected || connecting)
             throw new IllegalStateException("Already connected");
         if (key == null)
             throw new NullPointerException ("key is null");
 
         if (isExternalMessageHeaderAllowed(key, value)) {
             requests.set(key, value);
+            if (!key.equalsIgnoreCase("Content-Type")) {
+                userHeaders.set(key, value);
+            }
         }
     }
 
+    MessageHeader getUserSetHeaders() {
+        return userHeaders;
+    }
+
     /**
      * Adds a general request property specified by a
      * key-value pair.  This method will not overwrite
@@ -2776,14 +2969,17 @@
      * @since 1.4
      */
     @Override
-    public void addRequestProperty(String key, String value) {
-        if (connected)
+    public synchronized void addRequestProperty(String key, String value) {
+        if (connected || connecting)
             throw new IllegalStateException("Already connected");
         if (key == null)
             throw new NullPointerException ("key is null");
 
         if (isExternalMessageHeaderAllowed(key, value)) {
             requests.add(key, value);
+            if (!key.equalsIgnoreCase("Content-Type")) {
+                    userHeaders.add(key, value);
+            }
         }
     }
 
diff --git a/jdk/src/share/classes/sun/nio/cs/ext/ISO2022_JP_2.java b/jdk/src/share/classes/sun/nio/cs/ext/ISO2022_JP_2.java
index 1263157..0389a12 100644
--- a/jdk/src/share/classes/sun/nio/cs/ext/ISO2022_JP_2.java
+++ b/jdk/src/share/classes/sun/nio/cs/ext/ISO2022_JP_2.java
@@ -47,17 +47,17 @@
     }
 
     public CharsetDecoder newDecoder() {
-        return new Decoder(this, Decoder.DEC0208, DEC0212);
+        return new Decoder(this, Decoder.DEC0208, CoderHolder.DEC0212);
     }
 
     public CharsetEncoder newEncoder() {
-        return new Encoder(this, Encoder.ENC0208, ENC0212, true);
+        return new Encoder(this, Encoder.ENC0208, CoderHolder.ENC0212, true);
     }
 
-    private final static DoubleByte.Decoder DEC0212 =
-        (DoubleByte.Decoder)new JIS_X_0212().newDecoder();
-
-    private final static DoubleByte.Encoder ENC0212 =
-        (DoubleByte.Encoder)new JIS_X_0212().newEncoder();
-
+    private static class CoderHolder {
+        final static DoubleByte.Decoder DEC0212 =
+            (DoubleByte.Decoder)new JIS_X_0212().newDecoder();
+        final static DoubleByte.Encoder ENC0212 =
+            (DoubleByte.Encoder)new JIS_X_0212().newEncoder();
+    }
 }
diff --git a/jdk/src/share/classes/sun/nio/cs/ext/META-INF/services/java.nio.charset.spi.CharsetProvider b/jdk/src/share/classes/sun/nio/cs/ext/META-INF/services/java.nio.charset.spi.CharsetProvider
deleted file mode 100644
index cf0949e..0000000
--- a/jdk/src/share/classes/sun/nio/cs/ext/META-INF/services/java.nio.charset.spi.CharsetProvider
+++ /dev/null
@@ -1,2 +0,0 @@
-# NIO charset SPI extended charset provider
-sun.nio.cs.ext.ExtendedCharsets
diff --git a/jdk/src/share/classes/sun/nio/cs/ext/MSISO2022JP.java b/jdk/src/share/classes/sun/nio/cs/ext/MSISO2022JP.java
index 2be71a2..761809a 100644
--- a/jdk/src/share/classes/sun/nio/cs/ext/MSISO2022JP.java
+++ b/jdk/src/share/classes/sun/nio/cs/ext/MSISO2022JP.java
@@ -46,16 +46,17 @@
     }
 
     public CharsetDecoder newDecoder() {
-        return new Decoder(this, DEC0208, null);
+        return new Decoder(this, CoderHolder.DEC0208, null);
     }
 
     public CharsetEncoder newEncoder() {
-        return new Encoder(this, ENC0208, null, true);
+        return new Encoder(this, CoderHolder.ENC0208, null, true);
     }
 
-    private final static DoubleByte.Decoder DEC0208 =
-        (DoubleByte.Decoder)new JIS_X_0208_MS932().newDecoder();
-
-    private final static DoubleByte.Encoder ENC0208 =
-        (DoubleByte.Encoder)new JIS_X_0208_MS932().newEncoder();
+    private static class CoderHolder {
+        final static DoubleByte.Decoder DEC0208 =
+            (DoubleByte.Decoder)new JIS_X_0208_MS932().newDecoder();
+        final static DoubleByte.Encoder ENC0208 =
+            (DoubleByte.Encoder)new JIS_X_0208_MS932().newEncoder();
+    }
 }
diff --git a/jdk/src/share/classes/sun/print/RasterPrinterJob.java b/jdk/src/share/classes/sun/print/RasterPrinterJob.java
index 24bece5..1752016 100644
--- a/jdk/src/share/classes/sun/print/RasterPrinterJob.java
+++ b/jdk/src/share/classes/sun/print/RasterPrinterJob.java
@@ -607,13 +607,17 @@
 
     protected void updatePageAttributes(PrintService service,
                                         PageFormat page) {
+        if (this.attributes == null) {
+            this.attributes = new HashPrintRequestAttributeSet();
+        }
+
         updateAttributesWithPageFormat(service, page, this.attributes);
     }
 
     protected void updateAttributesWithPageFormat(PrintService service,
                                         PageFormat page,
-                                        PrintRequestAttributeSet attributes) {
-        if (service == null || page == null) {
+                                        PrintRequestAttributeSet pageAttributes) {
+        if (service == null || page == null || pageAttributes == null) {
             return;
         }
 
@@ -653,13 +657,10 @@
             orient = OrientationRequested.PORTRAIT;
         }
 
-        if (attributes == null) {
-            attributes = new HashPrintRequestAttributeSet();
-        }
         if (media != null) {
-            attributes.add(media);
+            pageAttributes.add(media);
         }
-        attributes.add(orient);
+        pageAttributes.add(orient);
 
         float ix = (float)(page.getPaper().getImageableX()/DPI);
         float iw = (float)(page.getPaper().getImageableWidth()/DPI);
@@ -667,7 +668,7 @@
         float ih = (float)(page.getPaper().getImageableHeight()/DPI);
         if (ix < 0) ix = 0f; if (iy < 0) iy = 0f;
         try {
-            attributes.add(new MediaPrintableArea(ix, iy, iw, ih,
+            pageAttributes.add(new MediaPrintableArea(ix, iy, iw, ih,
                                                   MediaPrintableArea.INCH));
         } catch (IllegalArgumentException iae) {
         }
diff --git a/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotation.java b/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotation.java
index c539972..1f4b9e7 100644
--- a/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotation.java
+++ b/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotation.java
@@ -83,12 +83,13 @@
         CLASS_TYPE_PARAMETER,
         METHOD_TYPE_PARAMETER,
         CLASS_EXTENDS,
-        CLASS_IMPLEMENTS,
-        CLASS_PARAMETER_BOUND,
-        METHOD_PARAMETER_BOUND,
-        METHOD_RETURN_TYPE,
-        METHOD_RECEIVER_TYPE,
-        FIELD_TYPE,
+        CLASS_IMPLEMENTS, // Not in the spec
+        CLASS_TYPE_PARAMETER_BOUND,
+        METHOD_TYPE_PARAMETER_BOUND,
+        FIELD,
+        METHOD_RETURN,
+        METHOD_RECEIVER,
+        METHOD_FORMAL_PARAMETER,
         THROWS;
     }
     public static class TypeAnnotationTargetInfo {
diff --git a/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java b/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java
index 12abe28..6b9712a 100644
--- a/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java
+++ b/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java
@@ -282,10 +282,10 @@
         AnnotatedElement boundsDecl;
         TypeAnnotationTarget target;
         if (decl instanceof Class) {
-            target = TypeAnnotationTarget.CLASS_PARAMETER_BOUND;
+            target = TypeAnnotationTarget.CLASS_TYPE_PARAMETER_BOUND;
             boundsDecl = (Class)decl;
         } else {
-            target = TypeAnnotationTarget.METHOD_PARAMETER_BOUND;
+            target = TypeAnnotationTarget.METHOD_TYPE_PARAMETER_BOUND;
             boundsDecl = (Executable)decl;
         }
         return TypeAnnotation.filter(TypeAnnotationParser.parseAllTypeAnnotations(boundsDecl), target);
@@ -371,14 +371,15 @@
     private static final byte LOCAL_VARIABLE = (byte)0x40;
     private static final byte RESOURCE_VARIABLE = (byte)0x41;
     private static final byte EXCEPTION_PARAMETER = (byte)0x42;
-    private static final byte CAST = (byte)0x43;
-    private static final byte INSTANCEOF = (byte)0x44;
-    private static final byte NEW = (byte)0x45;
-    private static final byte CONSTRUCTOR_REFERENCE_RECEIVER = (byte)0x46;
-    private static final byte METHOD_REFERENCE_RECEIVER = (byte)0x47;
-    private static final byte LAMBDA_FORMAL_PARAMETER = (byte)0x48;
-    private static final byte METHOD_REFERENCE = (byte)0x49;
-    private static final byte METHOD_REFERENCE_TYPE_ARGUMENT = (byte)0x50;
+    private static final byte INSTANCEOF = (byte)0x43;
+    private static final byte NEW = (byte)0x44;
+    private static final byte CONSTRUCTOR_REFERENCE = (byte)0x45;
+    private static final byte METHOD_REFERENCE = (byte)0x46;
+    private static final byte CAST = (byte)0x47;
+    private static final byte CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = (byte)0x48;
+    private static final byte METHOD_INVOCATION_TYPE_ARGUMENT = (byte)0x49;
+    private static final byte CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = (byte)0x4A;
+    private static final byte METHOD_REFERENCE_TYPE_ARGUMENT = (byte)0x4B;
 
     private static TypeAnnotation parseTypeAnnotation(ByteBuffer buf,
             ConstantPool cp,
@@ -417,19 +418,20 @@
                 return res;
             }} break;
         case CLASS_TYPE_PARAMETER_BOUND:
-            return parse2ByteTarget(TypeAnnotationTarget.CLASS_PARAMETER_BOUND, buf);
+            return parse2ByteTarget(TypeAnnotationTarget.CLASS_TYPE_PARAMETER_BOUND, buf);
         case METHOD_TYPE_PARAMETER_BOUND:
-            return parse2ByteTarget(TypeAnnotationTarget.METHOD_PARAMETER_BOUND, buf);
+            return parse2ByteTarget(TypeAnnotationTarget.METHOD_TYPE_PARAMETER_BOUND, buf);
         case FIELD:
-            return new TypeAnnotationTargetInfo(TypeAnnotationTarget.FIELD_TYPE);
+            return new TypeAnnotationTargetInfo(TypeAnnotationTarget.FIELD);
         case METHOD_RETURN:
-            return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_RETURN_TYPE);
+            return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_RETURN);
         case METHOD_RECEIVER:
-            return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_RECEIVER_TYPE);
+            return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_RECEIVER);
         case METHOD_FORMAL_PARAMETER: {
-            // Todo
             byte index = buf.get();
-            } break;
+            return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_FORMAL_PARAMETER,
+                    index);
+            } //unreachable break;
         case THROWS:
             return parseShortTarget(TypeAnnotationTarget.THROWS, buf);
 
@@ -445,30 +447,27 @@
                 short varLength = buf.getShort();
                 short index = buf.getShort();
             }
-            break;
+            return null;
         case EXCEPTION_PARAMETER: {
             byte index = buf.get();
-            } break;
-        case CAST:
+            }
+            return null;
         case INSTANCEOF:
-        case NEW: {
+        case NEW:
+        case CONSTRUCTOR_REFERENCE:
+        case METHOD_REFERENCE: {
             short offset = buf.getShort();
-            } break;
-        case CONSTRUCTOR_REFERENCE_RECEIVER:
-        case METHOD_REFERENCE_RECEIVER: {
-            short offset = buf.getShort();
-            byte index = buf.get();
-            } break;
-        case LAMBDA_FORMAL_PARAMETER: {
-            byte index = buf.get();
-            } break;
-        case METHOD_REFERENCE:
-            // This one isn't in the spec yet
-            break;
+            }
+            return null;
+        case CAST:
+        case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
+        case METHOD_INVOCATION_TYPE_ARGUMENT:
+        case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
         case METHOD_REFERENCE_TYPE_ARGUMENT: {
             short offset = buf.getShort();
             byte index = buf.get();
-            } break;
+            }
+            return null;
 
         default:
             // will throw error below
diff --git a/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java b/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java
index e356a49..423a0eb 100644
--- a/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java
+++ b/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
 
 import java.lang.reflect.GenericArrayType;
 import java.lang.reflect.Type;
-
+import java.util.Objects;
 
 /**
  * Implementation of GenericArrayType interface for core reflection.
@@ -81,18 +81,13 @@
         if (o instanceof GenericArrayType) {
             GenericArrayType that = (GenericArrayType) o;
 
-            Type thatComponentType = that.getGenericComponentType();
-            return genericComponentType == null ?
-                thatComponentType == null :
-                genericComponentType.equals(thatComponentType);
+            return Objects.equals(genericComponentType, that.getGenericComponentType());
         } else
             return false;
     }
 
     @Override
     public int hashCode() {
-        return (genericComponentType == null) ?
-            0:
-            genericComponentType.hashCode();
+        return Objects.hashCode(genericComponentType);
     }
 }
diff --git a/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java b/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java
index 83353ae..97524c4 100644
--- a/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java
+++ b/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
 import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
 import java.util.Arrays;
-
+import java.util.Objects;
 
 /** Implementing class for ParameterizedType interface. */
 
@@ -47,9 +47,7 @@
                                   Type ownerType) {
         this.actualTypeArguments = actualTypeArguments;
         this.rawType             = rawType;
-        if (ownerType != null) {
-            this.ownerType = ownerType;
-        } else { this.ownerType = rawType.getDeclaringClass();}
+        this.ownerType = (ownerType != null) ? ownerType : rawType.getDeclaringClass();
         validateConstructorArguments();
     }
 
@@ -62,7 +60,6 @@
         for (int i = 0; i < actualTypeArguments.length; i++) {
             // check actuals against formals' bounds
         }
-
     }
 
     /**
@@ -189,14 +186,9 @@
                 return ownerEquality && rawEquality && typeArgEquality;
             }
 
-
             return
-                (ownerType == null ?
-                 thatOwner == null :
-                 ownerType.equals(thatOwner)) &&
-                (rawType == null ?
-                 thatRawType == null :
-                 rawType.equals(thatRawType)) &&
+                Objects.equals(ownerType, thatOwner) &&
+                Objects.equals(rawType, thatRawType) &&
                 Arrays.equals(actualTypeArguments, // avoid clone
                               that.getActualTypeArguments());
         } else
@@ -207,8 +199,8 @@
     public int hashCode() {
         return
             Arrays.hashCode(actualTypeArguments) ^
-            (ownerType == null ? 0 : ownerType.hashCode() ) ^
-            (rawType == null   ? 0 : rawType.hashCode() );
+            Objects.hashCode(ownerType) ^
+            Objects.hashCode(rawType);
     }
 
     public String toString() {
@@ -239,10 +231,7 @@
             for(Type t: actualTypeArguments) {
                 if (!first)
                     sb.append(", ");
-                if (t instanceof Class)
-                    sb.append(((Class)t).getName());
-                else
-                    sb.append(t.toString());
+                sb.append(t.getTypeName());
                 first = false;
             }
             sb.append(">");
diff --git a/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java b/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java
index 0b1a13e..63da5ea 100644
--- a/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java
+++ b/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java
@@ -170,13 +170,8 @@
             GenericDeclaration thatDecl = that.getGenericDeclaration();
             String thatName = that.getName();
 
-            return
-                (genericDeclaration == null ?
-                 thatDecl == null :
-                 genericDeclaration.equals(thatDecl)) &&
-                (name == null ?
-                 thatName == null :
-                 name.equals(thatName));
+            return Objects.equals(genericDeclaration, thatDecl) &&
+                Objects.equals(name, thatName);
 
         } else
             return false;
diff --git a/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java b/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java
index cbbfae0..dbb0406 100644
--- a/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java
+++ b/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -203,10 +203,7 @@
                 sb.append(" & ");
 
             first = false;
-            if (bound instanceof Class)
-                sb.append(((Class)bound).getName() );
-            else
-                sb.append(bound.toString());
+            sb.append(bound.getTypeName());
         }
         return sb.toString();
     }
diff --git a/jdk/src/share/classes/sun/security/ec/CurveDB.java b/jdk/src/share/classes/sun/security/ec/CurveDB.java
new file mode 100644
index 0000000..1cacfa3
--- /dev/null
+++ b/jdk/src/share/classes/sun/security/ec/CurveDB.java
@@ -0,0 +1,669 @@
+/*
+ * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.ec;
+
+import java.math.BigInteger;
+
+import java.security.spec.*;
+
+import java.util.*;
+import java.util.regex.Pattern;
+
+/**
+ * Repository for well-known Elliptic Curve parameters. It is used by both
+ * the SunPKCS11 and SunJSSE code.
+ *
+ * @since   1.6
+ * @author  Andreas Sterbenz
+ */
+public class CurveDB {
+    private final static int P  = 1; // prime curve
+    private final static int B  = 2; // binary curve
+    private final static int PD = 5; // prime curve, mark as default
+    private final static int BD = 6; // binary curve, mark as default
+
+    private static final Map<String,NamedCurve> oidMap =
+        new LinkedHashMap<String,NamedCurve>();
+    private static final Map<String,NamedCurve> nameMap =
+        new HashMap<String,NamedCurve>();
+    private static final Map<Integer,NamedCurve> lengthMap =
+        new HashMap<Integer,NamedCurve>();
+
+    private static Collection<? extends NamedCurve> specCollection;
+
+    static final String SPLIT_PATTERN = ",|\\[|\\]";
+
+    // Used by SunECEntries
+    static Collection<? extends NamedCurve>getSupportedCurves() {
+        return specCollection;
+    }
+
+    // Return a NamedCurve for the specified OID/name or null if unknown.
+    static NamedCurve lookup(String name) {
+        NamedCurve spec = oidMap.get(name);
+        if (spec != null) {
+            return spec;
+        }
+
+        return nameMap.get(name);
+    }
+
+    // Return EC parameters for the specified field size. If there are known
+    // NIST recommended parameters for the given length, they are returned.
+    // Otherwise, if there are multiple matches for the given size, an
+    // arbitrary one is returns.
+    // If no parameters are known, the method returns null.
+    // NOTE that this method returns both prime and binary curves.
+    static NamedCurve lookup(int length) {
+        return lengthMap.get(length);
+    }
+
+    // Convert the given ECParameterSpec object to a NamedCurve object.
+    // If params does not represent a known named curve, return null.
+    static NamedCurve lookup(ECParameterSpec params) {
+        if ((params instanceof NamedCurve) || (params == null)) {
+            return (NamedCurve)params;
+        }
+
+        // This is a hack to allow SunJSSE to work with 3rd party crypto
+        // providers for ECC and not just SunPKCS11.
+        // This can go away once we decide how to expose curve names in the
+        // public API.
+        // Note that it assumes that the 3rd party provider encodes named
+        // curves using the short form, not explicitly. If it did that, then
+        // the SunJSSE TLS ECC extensions are wrong, which could lead to
+        // interoperability problems.
+        int fieldSize = params.getCurve().getField().getFieldSize();
+        for (NamedCurve namedCurve : specCollection) {
+            // ECParameterSpec does not define equals, so check all the
+            // components ourselves.
+            // Quick field size check first
+            if (namedCurve.getCurve().getField().getFieldSize() != fieldSize) {
+                continue;
+            }
+            if (namedCurve.getCurve().equals(params.getCurve()) == false) {
+                continue;
+            }
+            if (namedCurve.getGenerator().equals(params.getGenerator()) ==
+                    false) {
+                continue;
+            }
+            if (namedCurve.getOrder().equals(params.getOrder()) == false) {
+                continue;
+            }
+            if (namedCurve.getCofactor() != params.getCofactor()) {
+                continue;
+            }
+            // everything matches our named curve, return it
+            return namedCurve;
+        }
+        // no match found
+        return null;
+    }
+
+    private static BigInteger bi(String s) {
+        return new BigInteger(s, 16);
+    }
+
+    private static void add(String name, String soid, int type, String sfield,
+            String a, String b, String x, String y, String n, int h,
+            Pattern nameSplitPattern) {
+        BigInteger p = bi(sfield);
+        ECField field;
+        if ((type == P) || (type == PD)) {
+            field = new ECFieldFp(p);
+        } else if ((type == B) || (type == BD)) {
+            field = new ECFieldF2m(p.bitLength() - 1, p);
+        } else {
+            throw new RuntimeException("Invalid type: " + type);
+        }
+
+        EllipticCurve curve = new EllipticCurve(field, bi(a), bi(b));
+        ECPoint g = new ECPoint(bi(x), bi(y));
+
+        NamedCurve params = new NamedCurve(name, soid, curve, g, bi(n), h);
+        if (oidMap.put(soid, params) != null) {
+            throw new RuntimeException("Duplication oid: " + soid);
+        }
+
+        String[] commonNames = nameSplitPattern.split(name);
+        for (String commonName : commonNames) {
+            if (nameMap.put(commonName.trim(), params) != null) {
+                throw new RuntimeException("Duplication name: " + commonName);
+            }
+        }
+
+        int len = field.getFieldSize();
+        if ((type == PD) || (type == BD) || (lengthMap.get(len) == null)) {
+            // add entry if none present for this field size or if
+            // the curve is marked as a default curve.
+            lengthMap.put(len, params);
+        }
+    }
+
+    static {
+        Pattern nameSplitPattern = Pattern.compile(SPLIT_PATTERN);
+
+        /* SEC2 prime curves */
+        add("secp112r1", "1.3.132.0.6", P,
+            "DB7C2ABF62E35E668076BEAD208B",
+            "DB7C2ABF62E35E668076BEAD2088",
+            "659EF8BA043916EEDE8911702B22",
+            "09487239995A5EE76B55F9C2F098",
+            "A89CE5AF8724C0A23E0E0FF77500",
+            "DB7C2ABF62E35E7628DFAC6561C5",
+            1, nameSplitPattern);
+
+        add("secp112r2", "1.3.132.0.7", P,
+            "DB7C2ABF62E35E668076BEAD208B",
+            "6127C24C05F38A0AAAF65C0EF02C",
+            "51DEF1815DB5ED74FCC34C85D709",
+            "4BA30AB5E892B4E1649DD0928643",
+            "adcd46f5882e3747def36e956e97",
+            "36DF0AAFD8B8D7597CA10520D04B",
+            4, nameSplitPattern);
+
+        add("secp128r1", "1.3.132.0.28", P,
+            "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
+            "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC",
+            "E87579C11079F43DD824993C2CEE5ED3",
+            "161FF7528B899B2D0C28607CA52C5B86",
+            "CF5AC8395BAFEB13C02DA292DDED7A83",
+            "FFFFFFFE0000000075A30D1B9038A115",
+            1, nameSplitPattern);
+
+        add("secp128r2", "1.3.132.0.29", P,
+            "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
+            "D6031998D1B3BBFEBF59CC9BBFF9AEE1",
+            "5EEEFCA380D02919DC2C6558BB6D8A5D",
+            "7B6AA5D85E572983E6FB32A7CDEBC140",
+            "27B6916A894D3AEE7106FE805FC34B44",
+            "3FFFFFFF7FFFFFFFBE0024720613B5A3",
+            4, nameSplitPattern);
+
+        add("secp160k1", "1.3.132.0.9", P,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
+            "0000000000000000000000000000000000000000",
+            "0000000000000000000000000000000000000007",
+            "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB",
+            "938CF935318FDCED6BC28286531733C3F03C4FEE",
+            "0100000000000000000001B8FA16DFAB9ACA16B6B3",
+            1, nameSplitPattern);
+
+        add("secp160r1", "1.3.132.0.8", P,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
+            "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
+            "4A96B5688EF573284664698968C38BB913CBFC82",
+            "23A628553168947D59DCC912042351377AC5FB32",
+            "0100000000000000000001F4C8F927AED3CA752257",
+            1, nameSplitPattern);
+
+        add("secp160r2", "1.3.132.0.30", P,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70",
+            "B4E134D3FB59EB8BAB57274904664D5AF50388BA",
+            "52DCB034293A117E1F4FF11B30F7199D3144CE6D",
+            "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E",
+            "0100000000000000000000351EE786A818F3A1A16B",
+            1, nameSplitPattern);
+
+        add("secp192k1", "1.3.132.0.31", P,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37",
+            "000000000000000000000000000000000000000000000000",
+            "000000000000000000000000000000000000000000000003",
+            "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D",
+            "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D",
+            "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D",
+            1, nameSplitPattern);
+
+        add("secp192r1 [NIST P-192, X9.62 prime192v1]", "1.2.840.10045.3.1.1", PD,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
+            "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
+            "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
+            "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
+            "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
+            1, nameSplitPattern);
+
+        add("secp224k1", "1.3.132.0.32", P,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D",
+            "00000000000000000000000000000000000000000000000000000000",
+            "00000000000000000000000000000000000000000000000000000005",
+            "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C",
+            "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5",
+            "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",
+            1, nameSplitPattern);
+
+        add("secp224r1 [NIST P-224]", "1.3.132.0.33", PD,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
+            "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
+            "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
+            "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
+            1, nameSplitPattern);
+
+        add("secp256k1", "1.3.132.0.10", P,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
+            "0000000000000000000000000000000000000000000000000000000000000000",
+            "0000000000000000000000000000000000000000000000000000000000000007",
+            "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
+            "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",
+            1, nameSplitPattern);
+
+        add("secp256r1 [NIST P-256, X9.62 prime256v1]", "1.2.840.10045.3.1.7", PD,
+            "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
+            "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
+            "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
+            "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
+            "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
+            "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
+            1, nameSplitPattern);
+
+        add("secp384r1 [NIST P-384]", "1.3.132.0.34", PD,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
+            "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
+            "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
+            "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
+            1, nameSplitPattern);
+
+        add("secp521r1 [NIST P-521]", "1.3.132.0.35", PD,
+            "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+            "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
+            "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
+            "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
+            "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
+            "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
+            1, nameSplitPattern);
+
+        /* ANSI X9.62 prime curves */
+        add("X9.62 prime192v2", "1.2.840.10045.3.1.2", P,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
+            "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953",
+            "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A",
+            "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15",
+            "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31",
+            1, nameSplitPattern);
+
+        add("X9.62 prime192v3", "1.2.840.10045.3.1.3", P,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
+            "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916",
+            "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896",
+            "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0",
+            "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13",
+            1, nameSplitPattern);
+
+        add("X9.62 prime239v1", "1.2.840.10045.3.1.4", P,
+            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
+            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
+            "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A",
+            "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF",
+            "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE",
+            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B",
+            1, nameSplitPattern);
+
+        add("X9.62 prime239v2", "1.2.840.10045.3.1.5", P,
+            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
+            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
+            "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C",
+            "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7",
+            "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA",
+            "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063",
+            1, nameSplitPattern);
+
+        add("X9.62 prime239v3", "1.2.840.10045.3.1.6", P,
+            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
+            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
+            "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E",
+            "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A",
+            "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3",
+            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551",
+            1, nameSplitPattern);
+
+        /* SEC2 binary curves */
+        add("sect113r1", "1.3.132.0.4", B,
+            "020000000000000000000000000201",
+            "003088250CA6E7C7FE649CE85820F7",
+            "00E8BEE4D3E2260744188BE0E9C723",
+            "009D73616F35F4AB1407D73562C10F",
+            "00A52830277958EE84D1315ED31886",
+            "0100000000000000D9CCEC8A39E56F",
+            2, nameSplitPattern);
+
+        add("sect113r2", "1.3.132.0.5", B,
+            "020000000000000000000000000201",
+            "00689918DBEC7E5A0DD6DFC0AA55C7",
+            "0095E9A9EC9B297BD4BF36E059184F",
+            "01A57A6A7B26CA5EF52FCDB8164797",
+            "00B3ADC94ED1FE674C06E695BABA1D",
+            "010000000000000108789B2496AF93",
+            2, nameSplitPattern);
+
+        add("sect131r1", "1.3.132.0.22", B,
+            "080000000000000000000000000000010D",
+            "07A11B09A76B562144418FF3FF8C2570B8",
+            "0217C05610884B63B9C6C7291678F9D341",
+            "0081BAF91FDF9833C40F9C181343638399",
+            "078C6E7EA38C001F73C8134B1B4EF9E150",
+            "0400000000000000023123953A9464B54D",
+            2, nameSplitPattern);
+
+        add("sect131r2", "1.3.132.0.23", B,
+            "080000000000000000000000000000010D",
+            "03E5A88919D7CAFCBF415F07C2176573B2",
+            "04B8266A46C55657AC734CE38F018F2192",
+            "0356DCD8F2F95031AD652D23951BB366A8",
+            "0648F06D867940A5366D9E265DE9EB240F",
+            "0400000000000000016954A233049BA98F",
+            2, nameSplitPattern);
+
+        add("sect163k1 [NIST K-163]", "1.3.132.0.1", BD,
+            "0800000000000000000000000000000000000000C9",
+            "000000000000000000000000000000000000000001",
+            "000000000000000000000000000000000000000001",
+            "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
+            "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
+            "04000000000000000000020108A2E0CC0D99F8A5EF",
+            2, nameSplitPattern);
+
+        add("sect163r1", "1.3.132.0.2", B,
+            "0800000000000000000000000000000000000000C9",
+            "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2",
+            "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9",
+            "0369979697AB43897789566789567F787A7876A654",
+            "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883",
+            "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B",
+            2, nameSplitPattern);
+
+        add("sect163r2 [NIST B-163]", "1.3.132.0.15", BD,
+            "0800000000000000000000000000000000000000C9",
+            "000000000000000000000000000000000000000001",
+            "020A601907B8C953CA1481EB10512F78744A3205FD",
+            "03F0EBA16286A2D57EA0991168D4994637E8343E36",
+            "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
+            "040000000000000000000292FE77E70C12A4234C33",
+            2, nameSplitPattern);
+
+        add("sect193r1", "1.3.132.0.24", B,
+            "02000000000000000000000000000000000000000000008001",
+            "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01",
+            "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814",
+            "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1",
+            "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05",
+            "01000000000000000000000000C7F34A778F443ACC920EBA49",
+            2, nameSplitPattern);
+
+        add("sect193r2", "1.3.132.0.25", B,
+            "02000000000000000000000000000000000000000000008001",
+            "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B",
+            "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE",
+            "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F",
+            "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C",
+            "010000000000000000000000015AAB561B005413CCD4EE99D5",
+            2, nameSplitPattern);
+
+        add("sect233k1 [NIST K-233]", "1.3.132.0.26", BD,
+            "020000000000000000000000000000000000000004000000000000000001",
+            "000000000000000000000000000000000000000000000000000000000000",
+            "000000000000000000000000000000000000000000000000000000000001",
+            "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
+            "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
+            "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
+            4, nameSplitPattern);
+
+        add("sect233r1 [NIST B-233]", "1.3.132.0.27", B,
+            "020000000000000000000000000000000000000004000000000000000001",
+            "000000000000000000000000000000000000000000000000000000000001",
+            "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
+            "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
+            "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
+            "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
+            2, nameSplitPattern);
+
+        add("sect239k1", "1.3.132.0.3", B,
+            "800000000000000000004000000000000000000000000000000000000001",
+            "000000000000000000000000000000000000000000000000000000000000",
+            "000000000000000000000000000000000000000000000000000000000001",
+            "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC",
+            "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA",
+            "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5",
+            4, nameSplitPattern);
+
+        add("sect283k1 [NIST K-283]", "1.3.132.0.16", BD,
+            "0800000000000000000000000000000000000000000000000000000000000000000010A1",
+            "000000000000000000000000000000000000000000000000000000000000000000000000",
+            "000000000000000000000000000000000000000000000000000000000000000000000001",
+            "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
+            "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
+            "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
+            4, nameSplitPattern);
+
+        add("sect283r1 [NIST B-283]", "1.3.132.0.17", B,
+            "0800000000000000000000000000000000000000000000000000000000000000000010A1",
+            "000000000000000000000000000000000000000000000000000000000000000000000001",
+            "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
+            "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
+            "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
+            "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
+            2, nameSplitPattern);
+
+        add("sect409k1 [NIST K-409]", "1.3.132.0.36", BD,
+            "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
+            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
+            "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
+            "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
+            4, nameSplitPattern);
+
+        add("sect409r1 [NIST B-409]", "1.3.132.0.37", B,
+            "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
+            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
+            "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
+            "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
+            "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
+            2, nameSplitPattern);
+
+        add("sect571k1 [NIST K-571]", "1.3.132.0.38", BD,
+            "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
+            "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
+            "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
+            4, nameSplitPattern);
+
+        add("sect571r1 [NIST B-571]", "1.3.132.0.39", B,
+            "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
+            "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
+            "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
+            "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
+            2, nameSplitPattern);
+
+        /* ANSI X9.62 binary curves */
+        add("X9.62 c2tnb191v1", "1.2.840.10045.3.0.5", B,
+            "800000000000000000000000000000000000000000000201",
+            "2866537B676752636A68F56554E12640276B649EF7526267",
+            "2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC",
+            "36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D",
+            "765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB",
+            "40000000000000000000000004A20E90C39067C893BBB9A5",
+            2, nameSplitPattern);
+
+        add("X9.62 c2tnb191v2", "1.2.840.10045.3.0.6", B,
+            "800000000000000000000000000000000000000000000201",
+            "401028774D7777C7B7666D1366EA432071274F89FF01E718",
+            "0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01",
+            "3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10",
+            "17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A",
+            "20000000000000000000000050508CB89F652824E06B8173",
+            4, nameSplitPattern);
+
+        add("X9.62 c2tnb191v3", "1.2.840.10045.3.0.7", B,
+            "800000000000000000000000000000000000000000000201",
+            "6C01074756099122221056911C77D77E77A777E7E7E77FCB",
+            "71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8",
+            "375D4CE24FDE434489DE8746E71786015009E66E38A926DD",
+            "545A39176196575D985999366E6AD34CE0A77CD7127B06BE",
+            "155555555555555555555555610C0B196812BFB6288A3EA3",
+            6, nameSplitPattern);
+
+        add("X9.62 c2tnb239v1", "1.2.840.10045.3.0.11", B,
+            "800000000000000000000000000000000000000000000000001000000001",
+            "32010857077C5431123A46B808906756F543423E8D27877578125778AC76",
+            "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16",
+            "57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D",
+            "61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305",
+            "2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447",
+            4, nameSplitPattern);
+
+        add("X9.62 c2tnb239v2", "1.2.840.10045.3.0.12", B,
+            "800000000000000000000000000000000000000000000000001000000001",
+            "4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F",
+            "5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B",
+            "28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205",
+            "5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833",
+            "1555555555555555555555555555553C6F2885259C31E3FCDF154624522D",
+            6, nameSplitPattern);
+
+        add("X9.62 c2tnb239v3", "1.2.840.10045.3.0.13", B,
+            "800000000000000000000000000000000000000000000000001000000001",
+            "01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F",
+            "6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40",
+            "70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92",
+            "2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461",
+            "0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF",
+            0xA, nameSplitPattern);
+
+        add("X9.62 c2tnb359v1", "1.2.840.10045.3.0.18", B,
+            "800000000000000000000000000000000000000000000000000000000000000000000000100000000000000001",
+            "5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557",
+            "2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988",
+            "3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097",
+            "53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E4AE2DE211305A407104BD",
+            "01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B",
+            0x4C, nameSplitPattern);
+
+        add("X9.62 c2tnb431r1", "1.2.840.10045.3.0.20", B,
+            "800000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000001",
+            "1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F",
+            "10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618",
+            "120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7",
+            "20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760",
+            "0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91",
+            0x2760, nameSplitPattern);
+
+        /* ANSI X9.62 binary curves from the 1998 standard but forbidden
+         * in the 2005 version of the standard.
+         * We don't register them but leave them here for the time being in
+         * case we need to support them after all.
+         */
+/*
+        add("X9.62 c2pnb163v1", "1.2.840.10045.3.0.1", B,
+            "080000000000000000000000000000000000000107",
+            "072546B5435234A422E0789675F432C89435DE5242",
+            "00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9",
+            "07AF69989546103D79329FCC3D74880F33BBE803CB",
+            "01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F",
+            "0400000000000000000001E60FC8821CC74DAEAFC1",
+            2, nameSplitPattern);
+
+        add("X9.62 c2pnb163v2", "1.2.840.10045.3.0.2", B,
+            "080000000000000000000000000000000000000107",
+            "0108B39E77C4B108BED981ED0E890E117C511CF072",
+            "0667ACEB38AF4E488C407433FFAE4F1C811638DF20",
+            "0024266E4EB5106D0A964D92C4860E2671DB9B6CC5",
+            "079F684DDF6684C5CD258B3890021B2386DFD19FC5",
+            "03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7",
+            2, nameSplitPattern);
+
+        add("X9.62 c2pnb163v3", "1.2.840.10045.3.0.3", B,
+            "080000000000000000000000000000000000000107",
+            "07A526C63D3E25A256A007699F5447E32AE456B50E",
+            "03F7061798EB99E238FD6F1BF95B48FEEB4854252B",
+            "02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB",
+            "05B935590C155E17EA48EB3FF3718B893DF59A05D0",
+            "03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309",
+            2, nameSplitPattern);
+
+        add("X9.62 c2pnb176w1", "1.2.840.10045.3.0.4", B,
+            "0100000000000000000000000000000000080000000007",
+            "E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B",
+            "5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2",
+            "8D16C2866798B600F9F08BB4A8E860F3298CE04A5798",
+            "6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C",
+            "00010092537397ECA4F6145799D62B0A19CE06FE26AD",
+            0xFF6E, nameSplitPattern);
+
+        add("X9.62 c2pnb208w1", "1.2.840.10045.3.0.10", B,
+            "010000000000000000000000000000000800000000000000000007",
+            "0000000000000000000000000000000000000000000000000000",
+            "C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E",
+            "89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A",
+            "0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3",
+            "000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D",
+            0xFE48, nameSplitPattern);
+
+        add("X9.62 c2pnb272w1", "1.2.840.10045.3.0.16", B,
+            "010000000000000000000000000000000000000000000000000000010000000000000B",
+            "91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20",
+            "7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7",
+            "6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D",
+            "10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23",
+            "000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521",
+            0xFF06, nameSplitPattern);
+
+        add("X9.62 c2pnb304w1", "1.2.840.10045.3.0.17", B,
+            "010000000000000000000000000000000000000000000000000000000000000000000000000807",
+            "FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681",
+            "BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE",
+            "197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614",
+            "E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1B92C03B",
+            "000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D",
+            0xFE2E, nameSplitPattern);
+
+        add("X9.62 c2pnb368w1", "1.2.840.10045.3.0.19", B,
+            "0100000000000000000000000000000000000000000000000000000000000000000000002000000000000000000007",
+            "E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D",
+            "FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A",
+            "1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F",
+            "7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855ADAA81E2A0750B80FDA2310",
+            "00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967",
+            0xFF70, nameSplitPattern);
+*/
+
+        specCollection = Collections.unmodifiableCollection(oidMap.values());
+    }
+}
diff --git a/jdk/src/share/classes/sun/security/ec/ECDHKeyAgreement.java b/jdk/src/share/classes/sun/security/ec/ECDHKeyAgreement.java
index aa086a4..d65e3a0 100644
--- a/jdk/src/share/classes/sun/security/ec/ECDHKeyAgreement.java
+++ b/jdk/src/share/classes/sun/security/ec/ECDHKeyAgreement.java
@@ -32,6 +32,8 @@
 import javax.crypto.*;
 import javax.crypto.spec.*;
 
+import sun.security.util.ECUtil;
+
 /**
  * KeyAgreement implementation for ECDH.
  *
@@ -104,7 +106,7 @@
             publicValue = ((ECPublicKeyImpl)ecKey).getEncodedPublicValue();
         } else { // instanceof ECPublicKey
             publicValue =
-                ECParameters.encodePoint(ecKey.getW(), params.getCurve());
+                ECUtil.encodePoint(ecKey.getW(), params.getCurve());
         }
         int keyLenBits = params.getCurve().getField().getFieldSize();
         secretLen = (keyLenBits + 7) >> 3;
@@ -120,8 +122,8 @@
         }
 
         byte[] s = privateKey.getS().toByteArray();
-        byte[] encodedParams =
-            ECParameters.encodeParameters(privateKey.getParams()); // DER OID
+        byte[] encodedParams =                   // DER OID
+            ECUtil.encodeECParameterSpec(null, privateKey.getParams());
 
         try {
 
diff --git a/jdk/src/share/classes/sun/security/ec/ECDSASignature.java b/jdk/src/share/classes/sun/security/ec/ECDSASignature.java
index 64a36b1..c831259 100644
--- a/jdk/src/share/classes/sun/security/ec/ECDSASignature.java
+++ b/jdk/src/share/classes/sun/security/ec/ECDSASignature.java
@@ -275,7 +275,8 @@
     protected byte[] engineSign() throws SignatureException {
         byte[] s = privateKey.getS().toByteArray();
         ECParameterSpec params = privateKey.getParams();
-        byte[] encodedParams = ECParameters.encodeParameters(params); // DER OID
+        // DER OID
+        byte[] encodedParams = ECUtil.encodeECParameterSpec(null, params);
         int keySize = params.getCurve().getField().getFieldSize();
 
         // seed is twice the key size (in bytes) plus 1
@@ -301,12 +302,13 @@
 
         byte[] w;
         ECParameterSpec params = publicKey.getParams();
-        byte[] encodedParams = ECParameters.encodeParameters(params); // DER OID
+        // DER OID
+        byte[] encodedParams = ECUtil.encodeECParameterSpec(null, params);
 
         if (publicKey instanceof ECPublicKeyImpl) {
             w = ((ECPublicKeyImpl)publicKey).getEncodedPublicValue();
         } else { // instanceof ECPublicKey
-            w = ECParameters.encodePoint(publicKey.getW(), params.getCurve());
+            w = ECUtil.encodePoint(publicKey.getW(), params.getCurve());
         }
 
         try {
diff --git a/jdk/src/share/classes/sun/security/ec/ECKeyPairGenerator.java b/jdk/src/share/classes/sun/security/ec/ECKeyPairGenerator.java
index 046fb42..4cfda31 100644
--- a/jdk/src/share/classes/sun/security/ec/ECKeyPairGenerator.java
+++ b/jdk/src/share/classes/sun/security/ec/ECKeyPairGenerator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
 import sun.security.ec.ECPrivateKeyImpl;
 import sun.security.ec.ECPublicKeyImpl;
 import sun.security.jca.JCAUtil;
+import sun.security.util.ECUtil;
 
 /**
  * EC keypair generator.
@@ -72,7 +73,7 @@
     public void initialize(int keySize, SecureRandom random) {
 
         checkKeySize(keySize);
-        this.params = NamedCurve.getECParameterSpec(keySize);
+        this.params = ECUtil.getECParameterSpec(null, keySize);
         if (params == null) {
             throw new InvalidParameterException(
                 "No EC parameters available for key size " + keySize + " bits");
@@ -86,14 +87,15 @@
             throws InvalidAlgorithmParameterException {
 
         if (params instanceof ECParameterSpec) {
-            this.params = ECParameters.getNamedCurve((ECParameterSpec)params);
+            this.params = ECUtil.getECParameterSpec(null,
+                                                    (ECParameterSpec)params);
             if (this.params == null) {
                 throw new InvalidAlgorithmParameterException(
                     "Unsupported curve: " + params);
             }
         } else if (params instanceof ECGenParameterSpec) {
             String name = ((ECGenParameterSpec)params).getName();
-            this.params = NamedCurve.getECParameterSpec(name);
+            this.params = ECUtil.getECParameterSpec(null, name);
             if (this.params == null) {
                 throw new InvalidAlgorithmParameterException(
                     "Unknown curve name: " + name);
@@ -112,7 +114,7 @@
     public KeyPair generateKeyPair() {
 
         byte[] encodedParams =
-            ECParameters.encodeParameters((ECParameterSpec)params);
+            ECUtil.encodeECParameterSpec(null, (ECParameterSpec)params);
 
         // seed is twice the key size (in bytes) plus 1
         byte[] seed = new byte[(((keySize + 7) >> 3) + 1) * 2];
@@ -135,7 +137,7 @@
                 new ECPrivateKeyImpl(s, (ECParameterSpec)params);
 
             // handles[1] points to the native public key
-            ECPoint w = ECParameters.decodePoint(getEncodedBytes(handles[1]),
+            ECPoint w = ECUtil.decodePoint(getEncodedBytes(handles[1]),
                 ((ECParameterSpec)params).getCurve());
             PublicKey publicKey =
                 new ECPublicKeyImpl(w, (ECParameterSpec)params);
diff --git a/jdk/src/share/classes/sun/security/ec/ECParameters.java b/jdk/src/share/classes/sun/security/ec/ECParameters.java
index 62031c9..512f6c5 100644
--- a/jdk/src/share/classes/sun/security/ec/ECParameters.java
+++ b/jdk/src/share/classes/sun/security/ec/ECParameters.java
@@ -26,7 +26,6 @@
 package sun.security.ec;
 
 import java.io.IOException;
-import java.math.BigInteger;
 
 import java.security.*;
 import java.security.spec.*;
@@ -77,128 +76,75 @@
  */
 public final class ECParameters extends AlgorithmParametersSpi {
 
+    // used by ECPublicKeyImpl and ECPrivateKeyImpl
+    static AlgorithmParameters getAlgorithmParameters(ECParameterSpec spec)
+            throws InvalidKeyException {
+        try {
+            AlgorithmParameters params =
+                AlgorithmParameters.getInstance("EC", "SunEC");
+            params.init(spec);
+            return params;
+        } catch (GeneralSecurityException e) {
+            throw new InvalidKeyException("EC parameters error", e);
+        }
+    }
+
+    /*
+     * The parameters these AlgorithmParameters object represents.
+     * Currently, it is always an instance of NamedCurve.
+     */
+    private NamedCurve namedCurve;
+
+    // A public constructor is required by AlgorithmParameters class.
     public ECParameters() {
         // empty
     }
 
-    // Used by SunPKCS11 and SunJSSE.
-    public static ECPoint decodePoint(byte[] data, EllipticCurve curve)
-            throws IOException {
-        if ((data.length == 0) || (data[0] != 4)) {
-            throw new IOException("Only uncompressed point format supported");
+    // AlgorithmParameterSpi methods
+
+    protected void engineInit(AlgorithmParameterSpec paramSpec)
+            throws InvalidParameterSpecException {
+
+        if (paramSpec == null) {
+            throw new InvalidParameterSpecException
+                ("paramSpec must not be null");
         }
-        // Per ANSI X9.62, an encoded point is a 1 byte type followed by
-        // ceiling(log base 2 field-size / 8) bytes of x and the same of y.
-        int n = (data.length - 1) / 2;
-        if (n != ((curve.getField().getFieldSize() + 7 ) >> 3)) {
-            throw new IOException("Point does not match field size");
+
+        if (paramSpec instanceof NamedCurve) {
+            namedCurve = (NamedCurve)paramSpec;
+            return;
         }
-        byte[] xb = new byte[n];
-        byte[] yb = new byte[n];
-        System.arraycopy(data, 1, xb, 0, n);
-        System.arraycopy(data, n + 1, yb, 0, n);
-        return new ECPoint(new BigInteger(1, xb), new BigInteger(1, yb));
+
+        if (paramSpec instanceof ECParameterSpec) {
+            namedCurve = CurveDB.lookup((ECParameterSpec)paramSpec);
+        } else if (paramSpec instanceof ECGenParameterSpec) {
+            String name = ((ECGenParameterSpec)paramSpec).getName();
+            namedCurve = CurveDB.lookup(name);
+        } else if (paramSpec instanceof ECKeySizeParameterSpec) {
+            int keySize = ((ECKeySizeParameterSpec)paramSpec).getKeySize();
+            namedCurve = CurveDB.lookup(keySize);
+        } else {
+            throw new InvalidParameterSpecException
+                ("Only ECParameterSpec and ECGenParameterSpec supported");
+        }
+
+        if (namedCurve == null) {
+            throw new InvalidParameterSpecException(
+                "Not a supported curve: " + paramSpec);
+        }
     }
 
-    // Used by SunPKCS11 and SunJSSE.
-    public static byte[] encodePoint(ECPoint point, EllipticCurve curve) {
-        // get field size in bytes (rounding up)
-        int n = (curve.getField().getFieldSize() + 7) >> 3;
-        byte[] xb = trimZeroes(point.getAffineX().toByteArray());
-        byte[] yb = trimZeroes(point.getAffineY().toByteArray());
-        if ((xb.length > n) || (yb.length > n)) {
-            throw new RuntimeException
-                ("Point coordinates do not match field size");
-        }
-        byte[] b = new byte[1 + (n << 1)];
-        b[0] = 4; // uncompressed
-        System.arraycopy(xb, 0, b, n - xb.length + 1, xb.length);
-        System.arraycopy(yb, 0, b, b.length - yb.length, yb.length);
-        return b;
-    }
-
-    // Copied from the SunPKCS11 code - should be moved to a common location.
-    // trim leading (most significant) zeroes from the result
-    static byte[] trimZeroes(byte[] b) {
-        int i = 0;
-        while ((i < b.length - 1) && (b[i] == 0)) {
-            i++;
-        }
-        if (i == 0) {
-            return b;
-        }
-        byte[] t = new byte[b.length - i];
-        System.arraycopy(b, i, t, 0, t.length);
-        return t;
-    }
-
-    // Convert the given ECParameterSpec object to a NamedCurve object.
-    // If params does not represent a known named curve, return null.
-    // Used by SunPKCS11.
-    public static NamedCurve getNamedCurve(ECParameterSpec params) {
-        if ((params instanceof NamedCurve) || (params == null)) {
-            return (NamedCurve)params;
-        }
-        // This is a hack to allow SunJSSE to work with 3rd party crypto
-        // providers for ECC and not just SunPKCS11.
-        // This can go away once we decide how to expose curve names in the
-        // public API.
-        // Note that it assumes that the 3rd party provider encodes named
-        // curves using the short form, not explicitly. If it did that, then
-        // the SunJSSE TLS ECC extensions are wrong, which could lead to
-        // interoperability problems.
-        int fieldSize = params.getCurve().getField().getFieldSize();
-        for (ECParameterSpec namedCurve : NamedCurve.knownECParameterSpecs()) {
-            // ECParameterSpec does not define equals, so check all the
-            // components ourselves.
-            // Quick field size check first
-            if (namedCurve.getCurve().getField().getFieldSize() != fieldSize) {
-                continue;
-            }
-            if (namedCurve.getCurve().equals(params.getCurve()) == false) {
-                continue;
-            }
-            if (namedCurve.getGenerator().equals(params.getGenerator()) == false) {
-                continue;
-            }
-            if (namedCurve.getOrder().equals(params.getOrder()) == false) {
-                continue;
-            }
-            if (namedCurve.getCofactor() != params.getCofactor()) {
-                continue;
-            }
-            // everything matches our named curve, return it
-            return (NamedCurve)namedCurve;
-        }
-        // no match found
-        return null;
-    }
-
-    // Used by SunJSSE.
-    public static String getCurveName(ECParameterSpec params) {
-        NamedCurve curve = getNamedCurve(params);
-        return (curve == null) ? null : curve.getObjectIdentifier().toString();
-    }
-
-    // Used by SunPKCS11.
-    public static byte[] encodeParameters(ECParameterSpec params) {
-        NamedCurve curve = getNamedCurve(params);
-        if (curve == null) {
-            throw new RuntimeException("Not a known named curve: " + params);
-        }
-        return curve.getEncoded();
-    }
-
-    // Used by SunPKCS11.
-    public static ECParameterSpec decodeParameters(byte[] params) throws IOException {
+    protected void engineInit(byte[] params) throws IOException {
         DerValue encodedParams = new DerValue(params);
         if (encodedParams.tag == DerValue.tag_ObjectId) {
             ObjectIdentifier oid = encodedParams.getOID();
-            ECParameterSpec spec = NamedCurve.getECParameterSpec(oid);
+            NamedCurve spec = CurveDB.lookup(oid.toString());
             if (spec == null) {
                 throw new IOException("Unknown named curve: " + oid);
             }
-            return spec;
+
+            namedCurve = spec;
+            return;
         }
 
         throw new IOException("Only named ECParameters supported");
@@ -208,7 +154,8 @@
 
 /*
         if (encodedParams.tag != DerValue.tag_Sequence) {
-            throw new IOException("Unsupported EC parameters, tag: " + encodedParams.tag);
+            throw new IOException("Unsupported EC parameters, tag: " +
+                encodedParams.tag);
         }
 
         encodedParams.data.reset();
@@ -217,7 +164,8 @@
 
         int version = in.getInteger();
         if (version != 1) {
-            throw new IOException("Unsupported EC parameters version: " + version);
+            throw new IOException("Unsupported EC parameters version: " +
+               version);
         }
         ECField field = parseField(in);
         EllipticCurve curve = parseCurve(in, field);
@@ -242,110 +190,49 @@
 */
     }
 
-/*
-    private static final ObjectIdentifier fieldTypePrime =
-        ObjectIdentifier.newInternal(new int[] {1, 2, 840, 10045, 1, 1});
-
-    private static final ObjectIdentifier fieldTypeChar2 =
-        ObjectIdentifier.newInternal(new int[] {1, 2, 840, 10045, 1, 2});
-
-    private static ECField parseField(DerInputStream in) throws IOException {
-        DerValue v = in.getDerValue();
-        ObjectIdentifier oid = v.data.getOID();
-        if (oid.equals(fieldTypePrime) == false) {
-            throw new IOException("Only prime fields supported: " + oid);
-        }
-        BigInteger fieldSize = v.data.getBigInteger();
-        return new ECFieldFp(fieldSize);
-    }
-
-    private static EllipticCurve parseCurve(DerInputStream in, ECField field)
+    protected void engineInit(byte[] params, String decodingMethod)
             throws IOException {
-        DerValue v = in.getDerValue();
-        byte[] ab = v.data.getOctetString();
-        byte[] bb = v.data.getOctetString();
-        return new EllipticCurve(field, new BigInteger(1, ab), new BigInteger(1, bb));
-    }
-
-    private static ECPoint parsePoint(DerInputStream in, EllipticCurve curve)
-            throws IOException {
-        byte[] data = in.getOctetString();
-        return decodePoint(data, curve);
-    }
-*/
-
-    // used by ECPublicKeyImpl and ECPrivateKeyImpl
-    static AlgorithmParameters getAlgorithmParameters(ECParameterSpec spec)
-            throws InvalidKeyException {
-        try {
-            AlgorithmParameters params =
-                AlgorithmParameters.getInstance("EC", "SunEC");
-            params.init(spec);
-            return params;
-        } catch (GeneralSecurityException e) {
-            throw new InvalidKeyException("EC parameters error", e);
-        }
-    }
-
-    // AlgorithmParameterSpi methods
-
-    // The parameters these AlgorithmParameters object represents.
-    // Currently, it is always an instance of NamedCurve.
-    private ECParameterSpec paramSpec;
-
-    protected void engineInit(AlgorithmParameterSpec paramSpec)
-            throws InvalidParameterSpecException {
-        if (paramSpec instanceof ECParameterSpec) {
-            this.paramSpec = getNamedCurve((ECParameterSpec)paramSpec);
-            if (this.paramSpec == null) {
-                throw new InvalidParameterSpecException
-                    ("Not a supported named curve: " + paramSpec);
-            }
-        } else if (paramSpec instanceof ECGenParameterSpec) {
-            String name = ((ECGenParameterSpec)paramSpec).getName();
-            ECParameterSpec spec = NamedCurve.getECParameterSpec(name);
-            if (spec == null) {
-                throw new InvalidParameterSpecException("Unknown curve: " + name);
-            }
-            this.paramSpec = spec;
-        } else if (paramSpec == null) {
-            throw new InvalidParameterSpecException
-                ("paramSpec must not be null");
-        } else {
-            throw new InvalidParameterSpecException
-                ("Only ECParameterSpec and ECGenParameterSpec supported");
-        }
-    }
-
-    protected void engineInit(byte[] params) throws IOException {
-        paramSpec = decodeParameters(params);
-    }
-
-    protected void engineInit(byte[] params, String decodingMethod) throws IOException {
         engineInit(params);
     }
 
-    protected <T extends AlgorithmParameterSpec> T engineGetParameterSpec(Class<T> spec)
+    protected <T extends AlgorithmParameterSpec> T
+            engineGetParameterSpec(Class<T> spec)
             throws InvalidParameterSpecException {
+
         if (spec.isAssignableFrom(ECParameterSpec.class)) {
-            return spec.cast(paramSpec);
-        } else if (spec.isAssignableFrom(ECGenParameterSpec.class)) {
-            return spec.cast(new ECGenParameterSpec(getCurveName(paramSpec)));
-        } else {
-            throw new InvalidParameterSpecException
-                ("Only ECParameterSpec and ECGenParameterSpec supported");
+            return spec.cast(namedCurve);
         }
+
+        if (spec.isAssignableFrom(ECGenParameterSpec.class)) {
+            // Ensure the name is the Object ID
+            String name = namedCurve.getObjectId();
+            return spec.cast(new ECGenParameterSpec(name));
+        }
+
+        if (spec.isAssignableFrom(ECKeySizeParameterSpec.class)) {
+            int keySize = namedCurve.getCurve().getField().getFieldSize();
+            return spec.cast(new ECKeySizeParameterSpec(keySize));
+        }
+
+        throw new InvalidParameterSpecException(
+            "Only ECParameterSpec and ECGenParameterSpec supported");
     }
 
     protected byte[] engineGetEncoded() throws IOException {
-        return encodeParameters(paramSpec);
+        return namedCurve.getEncoded();
     }
 
-    protected byte[] engineGetEncoded(String encodingMethod) throws IOException {
+    protected byte[] engineGetEncoded(String encodingMethod)
+            throws IOException {
         return engineGetEncoded();
     }
 
     protected String engineToString() {
-        return paramSpec.toString();
+        if (namedCurve == null) {
+            return "Not initialized";
+        }
+
+        return namedCurve.toString();
     }
 }
+
diff --git a/jdk/src/share/classes/sun/security/ec/ECPrivateKeyImpl.java b/jdk/src/share/classes/sun/security/ec/ECPrivateKeyImpl.java
index fb309d3..3bc90ce 100644
--- a/jdk/src/share/classes/sun/security/ec/ECPrivateKeyImpl.java
+++ b/jdk/src/share/classes/sun/security/ec/ECPrivateKeyImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -67,18 +67,17 @@
     private ECParameterSpec params;
 
     /**
-     * Construct a key from its encoding. Called by the ECKeyFactory and
-     * the SunPKCS11 code.
+     * Construct a key from its encoding. Called by the ECKeyFactory.
      */
-    public ECPrivateKeyImpl(byte[] encoded) throws InvalidKeyException {
+    ECPrivateKeyImpl(byte[] encoded) throws InvalidKeyException {
         decode(encoded);
     }
 
     /**
      * Construct a key from its components. Used by the
-     * KeyFactory and the SunPKCS11 code.
+     * KeyFactory.
      */
-    public ECPrivateKeyImpl(BigInteger s, ECParameterSpec params)
+    ECPrivateKeyImpl(BigInteger s, ECParameterSpec params)
             throws InvalidKeyException {
         this.s = s;
         this.params = params;
@@ -88,7 +87,7 @@
         try {
             DerOutputStream out = new DerOutputStream();
             out.putInteger(1); // version 1
-            byte[] privBytes = ECParameters.trimZeroes(s.toByteArray());
+            byte[] privBytes = ECUtil.trimZeroes(s.toByteArray());
             out.putOctetString(privBytes);
             DerValue val =
                 new DerValue(DerValue.tag_Sequence, out.toByteArray());
diff --git a/jdk/src/share/classes/sun/security/ec/ECPublicKeyImpl.java b/jdk/src/share/classes/sun/security/ec/ECPublicKeyImpl.java
index af70732..dee601c 100644
--- a/jdk/src/share/classes/sun/security/ec/ECPublicKeyImpl.java
+++ b/jdk/src/share/classes/sun/security/ec/ECPublicKeyImpl.java
@@ -49,23 +49,23 @@
 
     /**
      * Construct a key from its components. Used by the
-     * ECKeyFactory and SunPKCS11.
+     * ECKeyFactory.
      */
     @SuppressWarnings("deprecation")
-    public ECPublicKeyImpl(ECPoint w, ECParameterSpec params)
+    ECPublicKeyImpl(ECPoint w, ECParameterSpec params)
             throws InvalidKeyException {
         this.w = w;
         this.params = params;
         // generate the encoding
         algid = new AlgorithmId
             (AlgorithmId.EC_oid, ECParameters.getAlgorithmParameters(params));
-        key = ECParameters.encodePoint(w, params.getCurve());
+        key = ECUtil.encodePoint(w, params.getCurve());
     }
 
     /**
-     * Construct a key from its encoding. Used by RSAKeyFactory.
+     * Construct a key from its encoding.
      */
-    public ECPublicKeyImpl(byte[] encoded) throws InvalidKeyException {
+    ECPublicKeyImpl(byte[] encoded) throws InvalidKeyException {
         decode(encoded);
     }
 
@@ -104,7 +104,7 @@
 
         try {
             params = algParams.getParameterSpec(ECParameterSpec.class);
-            w = ECParameters.decodePoint(key, params.getCurve());
+            w = ECUtil.decodePoint(key, params.getCurve());
         } catch (IOException e) {
             throw new InvalidKeyException("Invalid EC key", e);
         } catch (InvalidParameterSpecException e) {
diff --git a/jdk/src/share/classes/sun/security/ec/NamedCurve.java b/jdk/src/share/classes/sun/security/ec/NamedCurve.java
index d655a98..ecb1d81 100644
--- a/jdk/src/share/classes/sun/security/ec/NamedCurve.java
+++ b/jdk/src/share/classes/sun/security/ec/NamedCurve.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,638 +27,60 @@
 
 import java.io.IOException;
 import java.math.BigInteger;
-import java.util.*;
-import java.util.regex.Pattern;
 
 import java.security.spec.*;
 
-import sun.security.util.ObjectIdentifier;
 import sun.security.util.DerOutputStream;
+import sun.security.util.ObjectIdentifier;
+
 
 /**
- * Repository for well-known Elliptic Curve parameters. It is used by both
- * the SunPKCS11 and SunJSSE code.
+ * Contains Elliptic Curve parameters.
  *
  * @since   1.6
  * @author  Andreas Sterbenz
  */
-public final class NamedCurve extends ECParameterSpec {
+class NamedCurve extends ECParameterSpec {
 
     // friendly name for toString() output
     private final String name;
 
     // well known OID
-    private final ObjectIdentifier oid;
+    private final String oid;
 
     // encoded form (as NamedCurve identified via OID)
     private final byte[] encoded;
 
-    private NamedCurve(String name, ObjectIdentifier oid, EllipticCurve curve,
-            ECPoint g, BigInteger n, int h) throws IOException {
+    NamedCurve(String name, String oid, EllipticCurve curve,
+            ECPoint g, BigInteger n, int h) {
         super(curve, g, n, h);
         this.name = name;
         this.oid = oid;
 
         DerOutputStream out = new DerOutputStream();
-        out.putOID(oid);
+
+        try {
+            out.putOID(new ObjectIdentifier(oid));
+        } catch (IOException e) {
+            throw new RuntimeException("Internal error", e);
+        }
+
         encoded = out.toByteArray();
     }
 
-    // Return a NamedCurve for the specified OID/name or null if unknown.
-    // Used by SunJSSE and SunPKCS11.
-    public static ECParameterSpec getECParameterSpec(String name) {
-        NamedCurve spec = oidMap.get(name);
-        return (spec != null) ? spec : nameMap.get(name);
-    }
-
-    // Return a NamedCurve for the specified OID or null if unknown.
-    static ECParameterSpec getECParameterSpec(ObjectIdentifier oid) {
-        return getECParameterSpec(oid.toString());
-    }
-
-    // Return EC parameters for the specified field size. If there are known
-    // NIST recommended parameters for the given length, they are returned.
-    // Otherwise, if there are multiple matches for the given size, an
-    // arbitrary one is returns.
-    // If no parameters are known, the method returns null.
-    // NOTE that this method returns both prime and binary curves.
-    // Used by SunPKCS11.
-    public static ECParameterSpec getECParameterSpec(int length) {
-        return lengthMap.get(length);
-    }
-
-    // Used by unit tests.
-    public static Collection<? extends ECParameterSpec> knownECParameterSpecs() {
-        return Collections.unmodifiableCollection(oidMap.values());
+    String getName() {
+        return name;
     }
 
     byte[] getEncoded() {
         return encoded.clone();
     }
 
-    ObjectIdentifier getObjectIdentifier() {
+    String getObjectId() {
         return oid;
     }
 
     public String toString() {
         return name + " (" + oid + ")";
     }
-
-    private static final Map<String,NamedCurve> oidMap =
-                                        new LinkedHashMap<String,NamedCurve>();
-    private static final Map<String,NamedCurve> nameMap =
-                                        new HashMap<String,NamedCurve>();
-    private static final Map<Integer,NamedCurve> lengthMap =
-                                        new HashMap<Integer,NamedCurve>();
-
-    private static BigInteger bi(String s) {
-        return new BigInteger(s, 16);
-    }
-
-    private static Pattern SPLIT_PATTERN = Pattern.compile(",|\\[|\\]");
-
-    private static void add(String name, String soid, int type, String sfield,
-            String a, String b, String x, String y, String n, int h) {
-        BigInteger p = bi(sfield);
-        ECField field;
-        if ((type == P) || (type == PD)) {
-            field = new ECFieldFp(p);
-        } else if ((type == B) || (type == BD)) {
-            field = new ECFieldF2m(p.bitLength() - 1, p);
-        } else {
-            throw new RuntimeException("Invalid type: " + type);
-        }
-
-        EllipticCurve curve = new EllipticCurve(field, bi(a), bi(b));
-        ECPoint g = new ECPoint(bi(x), bi(y));
-
-        try {
-            ObjectIdentifier oid = new ObjectIdentifier(soid);
-            NamedCurve params = new NamedCurve(name, oid, curve, g, bi(n), h);
-            if (oidMap.put(soid, params) != null) {
-                throw new RuntimeException("Duplication oid: " + soid);
-            }
-            String[] commonNames = SPLIT_PATTERN.split(name);
-            for (String commonName : commonNames) {
-                if (nameMap.put(commonName.trim(), params) != null) {
-                    throw new RuntimeException("Duplication name: " + commonName);
-                }
-            }
-            int len = field.getFieldSize();
-            if ((type == PD) || (type == BD) || (lengthMap.get(len) == null)) {
-                // add entry if none present for this field size or if
-                // the curve is marked as a default curve.
-                lengthMap.put(len, params);
-            }
-        } catch (IOException e) {
-            throw new RuntimeException("Internal error", e);
-        }
-    }
-
-    private final static int P  = 1; // prime curve
-    private final static int B  = 2; // binary curve
-    private final static int PD = 5; // prime curve, mark as default
-    private final static int BD = 6; // binary curve, mark as default
-
-    static {
-        /* SEC2 prime curves */
-        add("secp112r1", "1.3.132.0.6", P,
-            "DB7C2ABF62E35E668076BEAD208B",
-            "DB7C2ABF62E35E668076BEAD2088",
-            "659EF8BA043916EEDE8911702B22",
-            "09487239995A5EE76B55F9C2F098",
-            "A89CE5AF8724C0A23E0E0FF77500",
-            "DB7C2ABF62E35E7628DFAC6561C5",
-            1);
-
-        add("secp112r2", "1.3.132.0.7", P,
-            "DB7C2ABF62E35E668076BEAD208B",
-            "6127C24C05F38A0AAAF65C0EF02C",
-            "51DEF1815DB5ED74FCC34C85D709",
-            "4BA30AB5E892B4E1649DD0928643",
-            "adcd46f5882e3747def36e956e97",
-            "36DF0AAFD8B8D7597CA10520D04B",
-            4);
-
-        add("secp128r1", "1.3.132.0.28", P,
-            "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
-            "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC",
-            "E87579C11079F43DD824993C2CEE5ED3",
-            "161FF7528B899B2D0C28607CA52C5B86",
-            "CF5AC8395BAFEB13C02DA292DDED7A83",
-            "FFFFFFFE0000000075A30D1B9038A115",
-            1);
-
-        add("secp128r2", "1.3.132.0.29", P,
-            "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
-            "D6031998D1B3BBFEBF59CC9BBFF9AEE1",
-            "5EEEFCA380D02919DC2C6558BB6D8A5D",
-            "7B6AA5D85E572983E6FB32A7CDEBC140",
-            "27B6916A894D3AEE7106FE805FC34B44",
-            "3FFFFFFF7FFFFFFFBE0024720613B5A3",
-            4);
-
-        add("secp160k1", "1.3.132.0.9", P,
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
-            "0000000000000000000000000000000000000000",
-            "0000000000000000000000000000000000000007",
-            "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB",
-            "938CF935318FDCED6BC28286531733C3F03C4FEE",
-            "0100000000000000000001B8FA16DFAB9ACA16B6B3",
-            1);
-
-        add("secp160r1", "1.3.132.0.8", P,
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
-            "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
-            "4A96B5688EF573284664698968C38BB913CBFC82",
-            "23A628553168947D59DCC912042351377AC5FB32",
-            "0100000000000000000001F4C8F927AED3CA752257",
-            1);
-
-        add("secp160r2", "1.3.132.0.30", P,
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70",
-            "B4E134D3FB59EB8BAB57274904664D5AF50388BA",
-            "52DCB034293A117E1F4FF11B30F7199D3144CE6D",
-            "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E",
-            "0100000000000000000000351EE786A818F3A1A16B",
-            1);
-
-        add("secp192k1", "1.3.132.0.31", P,
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37",
-            "000000000000000000000000000000000000000000000000",
-            "000000000000000000000000000000000000000000000003",
-            "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D",
-            "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D",
-            "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D",
-            1);
-
-        add("secp192r1 [NIST P-192, X9.62 prime192v1]", "1.2.840.10045.3.1.1", PD,
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
-            "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
-            "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
-            "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
-            "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
-            1);
-
-        add("secp224k1", "1.3.132.0.32", P,
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D",
-            "00000000000000000000000000000000000000000000000000000000",
-            "00000000000000000000000000000000000000000000000000000005",
-            "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C",
-            "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5",
-            "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",
-            1);
-
-        add("secp224r1 [NIST P-224]", "1.3.132.0.33", PD,
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
-            "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
-            "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
-            "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
-            1);
-
-        add("secp256k1", "1.3.132.0.10", P,
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
-            "0000000000000000000000000000000000000000000000000000000000000000",
-            "0000000000000000000000000000000000000000000000000000000000000007",
-            "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
-            "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",
-            1);
-
-        add("secp256r1 [NIST P-256, X9.62 prime256v1]", "1.2.840.10045.3.1.7", PD,
-            "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
-            "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
-            "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
-            "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
-            "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
-            "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
-            1);
-
-        add("secp384r1 [NIST P-384]", "1.3.132.0.34", PD,
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
-            "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
-            "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
-            "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
-            1);
-
-        add("secp521r1 [NIST P-521]", "1.3.132.0.35", PD,
-            "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
-            "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
-            "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
-            "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
-            "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
-            "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
-            1);
-
-        /* ANSI X9.62 prime curves */
-        add("X9.62 prime192v2", "1.2.840.10045.3.1.2", P,
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
-            "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953",
-            "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A",
-            "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15",
-            "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31",
-            1);
-
-        add("X9.62 prime192v3", "1.2.840.10045.3.1.3", P,
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
-            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
-            "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916",
-            "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896",
-            "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0",
-            "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13",
-            1);
-
-        add("X9.62 prime239v1", "1.2.840.10045.3.1.4", P,
-            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
-            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
-            "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A",
-            "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF",
-            "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE",
-            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B",
-            1);
-
-        add("X9.62 prime239v2", "1.2.840.10045.3.1.5", P,
-            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
-            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
-            "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C",
-            "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7",
-            "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA",
-            "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063",
-            1);
-
-        add("X9.62 prime239v3", "1.2.840.10045.3.1.6", P,
-            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
-            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
-            "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E",
-            "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A",
-            "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3",
-            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551",
-            1);
-
-        /* SEC2 binary curves */
-        add("sect113r1", "1.3.132.0.4", B,
-            "020000000000000000000000000201",
-            "003088250CA6E7C7FE649CE85820F7",
-            "00E8BEE4D3E2260744188BE0E9C723",
-            "009D73616F35F4AB1407D73562C10F",
-            "00A52830277958EE84D1315ED31886",
-            "0100000000000000D9CCEC8A39E56F",
-            2);
-
-        add("sect113r2", "1.3.132.0.5", B,
-            "020000000000000000000000000201",
-            "00689918DBEC7E5A0DD6DFC0AA55C7",
-            "0095E9A9EC9B297BD4BF36E059184F",
-            "01A57A6A7B26CA5EF52FCDB8164797",
-            "00B3ADC94ED1FE674C06E695BABA1D",
-            "010000000000000108789B2496AF93",
-            2);
-
-        add("sect131r1", "1.3.132.0.22", B,
-            "080000000000000000000000000000010D",
-            "07A11B09A76B562144418FF3FF8C2570B8",
-            "0217C05610884B63B9C6C7291678F9D341",
-            "0081BAF91FDF9833C40F9C181343638399",
-            "078C6E7EA38C001F73C8134B1B4EF9E150",
-            "0400000000000000023123953A9464B54D",
-            2);
-
-        add("sect131r2", "1.3.132.0.23", B,
-            "080000000000000000000000000000010D",
-            "03E5A88919D7CAFCBF415F07C2176573B2",
-            "04B8266A46C55657AC734CE38F018F2192",
-            "0356DCD8F2F95031AD652D23951BB366A8",
-            "0648F06D867940A5366D9E265DE9EB240F",
-            "0400000000000000016954A233049BA98F",
-            2);
-
-        add("sect163k1 [NIST K-163]", "1.3.132.0.1", BD,
-            "0800000000000000000000000000000000000000C9",
-            "000000000000000000000000000000000000000001",
-            "000000000000000000000000000000000000000001",
-            "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
-            "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
-            "04000000000000000000020108A2E0CC0D99F8A5EF",
-            2);
-
-        add("sect163r1", "1.3.132.0.2", B,
-            "0800000000000000000000000000000000000000C9",
-            "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2",
-            "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9",
-            "0369979697AB43897789566789567F787A7876A654",
-            "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883",
-            "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B",
-            2);
-
-        add("sect163r2 [NIST B-163]", "1.3.132.0.15", BD,
-            "0800000000000000000000000000000000000000C9",
-            "000000000000000000000000000000000000000001",
-            "020A601907B8C953CA1481EB10512F78744A3205FD",
-            "03F0EBA16286A2D57EA0991168D4994637E8343E36",
-            "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
-            "040000000000000000000292FE77E70C12A4234C33",
-            2);
-
-        add("sect193r1", "1.3.132.0.24", B,
-            "02000000000000000000000000000000000000000000008001",
-            "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01",
-            "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814",
-            "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1",
-            "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05",
-            "01000000000000000000000000C7F34A778F443ACC920EBA49",
-            2);
-
-        add("sect193r2", "1.3.132.0.25", B,
-            "02000000000000000000000000000000000000000000008001",
-            "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B",
-            "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE",
-            "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F",
-            "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C",
-            "010000000000000000000000015AAB561B005413CCD4EE99D5",
-            2);
-
-        add("sect233k1 [NIST K-233]", "1.3.132.0.26", BD,
-            "020000000000000000000000000000000000000004000000000000000001",
-            "000000000000000000000000000000000000000000000000000000000000",
-            "000000000000000000000000000000000000000000000000000000000001",
-            "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
-            "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
-            "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
-            4);
-
-        add("sect233r1 [NIST B-233]", "1.3.132.0.27", B,
-            "020000000000000000000000000000000000000004000000000000000001",
-            "000000000000000000000000000000000000000000000000000000000001",
-            "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
-            "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
-            "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
-            "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
-            2);
-
-        add("sect239k1", "1.3.132.0.3", B,
-            "800000000000000000004000000000000000000000000000000000000001",
-            "000000000000000000000000000000000000000000000000000000000000",
-            "000000000000000000000000000000000000000000000000000000000001",
-            "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC",
-            "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA",
-            "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5",
-            4);
-
-        add("sect283k1 [NIST K-283]", "1.3.132.0.16", BD,
-            "0800000000000000000000000000000000000000000000000000000000000000000010A1",
-            "000000000000000000000000000000000000000000000000000000000000000000000000",
-            "000000000000000000000000000000000000000000000000000000000000000000000001",
-            "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
-            "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
-            "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
-            4);
-
-        add("sect283r1 [NIST B-283]", "1.3.132.0.17", B,
-            "0800000000000000000000000000000000000000000000000000000000000000000010A1",
-            "000000000000000000000000000000000000000000000000000000000000000000000001",
-            "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
-            "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
-            "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
-            "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
-            2);
-
-        add("sect409k1 [NIST K-409]", "1.3.132.0.36", BD,
-            "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
-            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
-            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
-            "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
-            "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
-            "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
-            4);
-
-        add("sect409r1 [NIST B-409]", "1.3.132.0.37", B,
-            "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
-            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
-            "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
-            "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
-            "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
-            "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
-            2);
-
-        add("sect571k1 [NIST K-571]", "1.3.132.0.38", BD,
-            "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
-            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
-            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
-            "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
-            "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
-            "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
-            4);
-
-        add("sect571r1 [NIST B-571]", "1.3.132.0.39", B,
-            "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
-            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
-            "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
-            "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
-            "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
-            "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
-            2);
-
-        /* ANSI X9.62 binary curves */
-        add("X9.62 c2tnb191v1", "1.2.840.10045.3.0.5", B,
-            "800000000000000000000000000000000000000000000201",
-            "2866537B676752636A68F56554E12640276B649EF7526267",
-            "2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC",
-            "36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D",
-            "765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB",
-            "40000000000000000000000004A20E90C39067C893BBB9A5",
-            2);
-
-        add("X9.62 c2tnb191v2", "1.2.840.10045.3.0.6", B,
-            "800000000000000000000000000000000000000000000201",
-            "401028774D7777C7B7666D1366EA432071274F89FF01E718",
-            "0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01",
-            "3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10",
-            "17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A",
-            "20000000000000000000000050508CB89F652824E06B8173",
-            4);
-
-        add("X9.62 c2tnb191v3", "1.2.840.10045.3.0.7", B,
-            "800000000000000000000000000000000000000000000201",
-            "6C01074756099122221056911C77D77E77A777E7E7E77FCB",
-            "71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8",
-            "375D4CE24FDE434489DE8746E71786015009E66E38A926DD",
-            "545A39176196575D985999366E6AD34CE0A77CD7127B06BE",
-            "155555555555555555555555610C0B196812BFB6288A3EA3",
-            6);
-
-        add("X9.62 c2tnb239v1", "1.2.840.10045.3.0.11", B,
-            "800000000000000000000000000000000000000000000000001000000001",
-            "32010857077C5431123A46B808906756F543423E8D27877578125778AC76",
-            "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16",
-            "57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D",
-            "61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305",
-            "2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447",
-            4);
-
-        add("X9.62 c2tnb239v2", "1.2.840.10045.3.0.12", B,
-            "800000000000000000000000000000000000000000000000001000000001",
-            "4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F",
-            "5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B",
-            "28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205",
-            "5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833",
-            "1555555555555555555555555555553C6F2885259C31E3FCDF154624522D",
-            6);
-
-        add("X9.62 c2tnb239v3", "1.2.840.10045.3.0.13", B,
-            "800000000000000000000000000000000000000000000000001000000001",
-            "01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F",
-            "6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40",
-            "70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92",
-            "2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461",
-            "0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF",
-            0xA);
-
-        add("X9.62 c2tnb359v1", "1.2.840.10045.3.0.18", B,
-            "800000000000000000000000000000000000000000000000000000000000000000000000100000000000000001",
-            "5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557",
-            "2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988",
-            "3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097",
-            "53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E4AE2DE211305A407104BD",
-            "01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B",
-            0x4C);
-
-        add("X9.62 c2tnb431r1", "1.2.840.10045.3.0.20", B,
-            "800000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000001",
-            "1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F",
-            "10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618",
-            "120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7",
-            "20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760",
-            "0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91",
-            0x2760);
-
-        /* ANSI X9.62 binary curves from the 1998 standard but forbidden
-         * in the 2005 version of the standard.
-         * We don't register them but leave them here for the time being in
-         * case we need to support them after all.
-         */
-/*
-        add("X9.62 c2pnb163v1", "1.2.840.10045.3.0.1", B,
-            "080000000000000000000000000000000000000107",
-            "072546B5435234A422E0789675F432C89435DE5242",
-            "00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9",
-            "07AF69989546103D79329FCC3D74880F33BBE803CB",
-            "01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F",
-            "0400000000000000000001E60FC8821CC74DAEAFC1",
-            2);
-
-        add("X9.62 c2pnb163v2", "1.2.840.10045.3.0.2", B,
-            "080000000000000000000000000000000000000107",
-            "0108B39E77C4B108BED981ED0E890E117C511CF072",
-            "0667ACEB38AF4E488C407433FFAE4F1C811638DF20",
-            "0024266E4EB5106D0A964D92C4860E2671DB9B6CC5",
-            "079F684DDF6684C5CD258B3890021B2386DFD19FC5",
-            "03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7",
-            2);
-
-        add("X9.62 c2pnb163v3", "1.2.840.10045.3.0.3", B,
-            "080000000000000000000000000000000000000107",
-            "07A526C63D3E25A256A007699F5447E32AE456B50E",
-            "03F7061798EB99E238FD6F1BF95B48FEEB4854252B",
-            "02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB",
-            "05B935590C155E17EA48EB3FF3718B893DF59A05D0",
-            "03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309",
-            2);
-
-        add("X9.62 c2pnb176w1", "1.2.840.10045.3.0.4", B,
-            "0100000000000000000000000000000000080000000007",
-            "E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B",
-            "5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2",
-            "8D16C2866798B600F9F08BB4A8E860F3298CE04A5798",
-            "6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C",
-            "00010092537397ECA4F6145799D62B0A19CE06FE26AD",
-            0xFF6E);
-
-        add("X9.62 c2pnb208w1", "1.2.840.10045.3.0.10", B,
-            "010000000000000000000000000000000800000000000000000007",
-            "0000000000000000000000000000000000000000000000000000",
-            "C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E",
-            "89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A",
-            "0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3",
-            "000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D",
-            0xFE48);
-
-        add("X9.62 c2pnb272w1", "1.2.840.10045.3.0.16", B,
-            "010000000000000000000000000000000000000000000000000000010000000000000B",
-            "91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20",
-            "7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7",
-            "6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D",
-            "10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23",
-            "000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521",
-            0xFF06);
-
-        add("X9.62 c2pnb304w1", "1.2.840.10045.3.0.17", B,
-            "010000000000000000000000000000000000000000000000000000000000000000000000000807",
-            "FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681",
-            "BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE",
-            "197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614",
-            "E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1B92C03B",
-            "000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D",
-            0xFE2E);
-
-        add("X9.62 c2pnb368w1", "1.2.840.10045.3.0.19", B,
-            "0100000000000000000000000000000000000000000000000000000000000000000000002000000000000000000007",
-            "E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D",
-            "FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A",
-            "1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F",
-            "7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855ADAA81E2A0750B80FDA2310",
-            "00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967",
-            0xFF70);
-*/
-
-        SPLIT_PATTERN = null;
-    }
-
 }
diff --git a/jdk/src/share/classes/sun/security/ec/SunECEntries.java b/jdk/src/share/classes/sun/security/ec/SunECEntries.java
index fe810ee..9552f8e 100644
--- a/jdk/src/share/classes/sun/security/ec/SunECEntries.java
+++ b/jdk/src/share/classes/sun/security/ec/SunECEntries.java
@@ -25,8 +25,11 @@
 
 package sun.security.ec;
 
+import java.util.Collection;
 import java.util.Map;
 
+import java.util.regex.Pattern;
+
 /**
  * Defines the entries of the SunEC provider.
  *
@@ -60,64 +63,33 @@
 
         map.put("AlgorithmParameters.EC ImplementedIn", "Software");
 
-        map.put("AlgorithmParameters.EC SupportedCurves",
+        // "AlgorithmParameters.EC SupportedCurves" prop used by unit test
+        boolean firstCurve = true;
+        StringBuilder names = new StringBuilder();
+        Pattern nameSplitPattern = Pattern.compile(CurveDB.SPLIT_PATTERN);
 
-            // A list comprising lists of curve names and object identifiers.
-            // '[' ( <curve-name> ',' )+ <curve-object-identifier> ']' '|'
+        Collection<? extends NamedCurve> supportedCurves =
+            CurveDB.getSupportedCurves();
+        for (NamedCurve namedCurve : supportedCurves) {
+            if (!firstCurve) {
+                names.append("|");
+            } else {
+                firstCurve = false;
+            }
 
-            // SEC 2 prime curves
-            "[secp112r1,1.3.132.0.6]|" +
-            "[secp112r2,1.3.132.0.7]|" +
-            "[secp128r1,1.3.132.0.28]|" +
-            "[secp128r2,1.3.132.0.29]|" +
-            "[secp160k1,1.3.132.0.9]|" +
-            "[secp160r1,1.3.132.0.8]|" +
-            "[secp160r2,1.3.132.0.30]|" +
-            "[secp192k1,1.3.132.0.31]|" +
-            "[secp192r1,NIST P-192,X9.62 prime192v1,1.2.840.10045.3.1.1]|" +
-            "[secp224k1,1.3.132.0.32]|" +
-            "[secp224r1,NIST P-224,1.3.132.0.33]|" +
-            "[secp256k1,1.3.132.0.10]|" +
-            "[secp256r1,NIST P-256,X9.62 prime256v1,1.2.840.10045.3.1.7]|" +
-            "[secp384r1,NIST P-384,1.3.132.0.34]|" +
-            "[secp521r1,NIST P-521,1.3.132.0.35]|" +
+            names.append("[");
 
-            // ANSI X9.62 prime curves
-            "[X9.62 prime192v2,1.2.840.10045.3.1.2]|" +
-            "[X9.62 prime192v3,1.2.840.10045.3.1.3]|" +
-            "[X9.62 prime239v1,1.2.840.10045.3.1.4]|" +
-            "[X9.62 prime239v2,1.2.840.10045.3.1.5]|" +
-            "[X9.62 prime239v3,1.2.840.10045.3.1.6]|" +
+            String[] commonNames = nameSplitPattern.split(namedCurve.getName());
+            for (String commonName : commonNames) {
+                names.append(commonName.trim());
+                names.append(",");
+            }
 
-            // SEC 2 binary curves
-            "[sect113r1,1.3.132.0.4]|" +
-            "[sect113r2,1.3.132.0.5]|" +
-            "[sect131r1,1.3.132.0.22]|" +
-            "[sect131r2,1.3.132.0.23]|" +
-            "[sect163k1,NIST K-163,1.3.132.0.1]|" +
-            "[sect163r1,1.3.132.0.2]|" +
-            "[sect163r2,NIST B-163,1.3.132.0.15]|" +
-            "[sect193r1,1.3.132.0.24]|" +
-            "[sect193r2,1.3.132.0.25]|" +
-            "[sect233k1,NIST K-233,1.3.132.0.26]|" +
-            "[sect233r1,NIST B-233,1.3.132.0.27]|" +
-            "[sect239k1,1.3.132.0.3]|" +
-            "[sect283k1,NIST K-283,1.3.132.0.16]|" +
-            "[sect283r1,NIST B-283,1.3.132.0.17]|" +
-            "[sect409k1,NIST K-409,1.3.132.0.36]|" +
-            "[sect409r1,NIST B-409,1.3.132.0.37]|" +
-            "[sect571k1,NIST K-571,1.3.132.0.38]|" +
-            "[sect571r1,NIST B-571,1.3.132.0.39]|" +
+            names.append(namedCurve.getObjectId());
+            names.append("]");
+        }
 
-            // ANSI X9.62 binary curves
-            "[X9.62 c2tnb191v1,1.2.840.10045.3.0.5]|" +
-            "[X9.62 c2tnb191v2,1.2.840.10045.3.0.6]|" +
-            "[X9.62 c2tnb191v3,1.2.840.10045.3.0.7]|" +
-            "[X9.62 c2tnb239v1,1.2.840.10045.3.0.11]|" +
-            "[X9.62 c2tnb239v2,1.2.840.10045.3.0.12]|" +
-            "[X9.62 c2tnb239v3,1.2.840.10045.3.0.13]|" +
-            "[X9.62 c2tnb359v1,1.2.840.10045.3.0.18]|" +
-            "[X9.62 c2tnb431r1,1.2.840.10045.3.0.20]");
+        map.put("AlgorithmParameters.EC SupportedCurves", names.toString());
 
         /*
          * Register the algorithms below only when the full ECC implementation
diff --git a/jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java b/jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java
index 8a60b8b..b88f722 100644
--- a/jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java
+++ b/jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java
@@ -48,6 +48,7 @@
                     public Boolean run() {
                             String osname = System.getProperty("os.name");
                             if (osname.startsWith("SunOS") ||
+                                osname.contains("OS X") ||
                                 osname.startsWith("Linux")) {
                                 return new Boolean(System.getProperty
                                     (USE_NATIVE_PROP));
diff --git a/jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java b/jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java
index 1cbc040..b0e81aa 100644
--- a/jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java
+++ b/jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java
@@ -90,6 +90,11 @@
                                     "libgssapi_krb5.so",
                                     "libgssapi_krb5.so.2",
                                 };
+                            } else if (osname.contains("OS X")) {
+                                gssLibs = new String[]{
+                                    "libgssapi_krb5.dylib",
+                                    "/usr/lib/sasl2/libgssapiv2.2.so",
+                               };
                             }
                         } else {
                             gssLibs = new String[]{ defaultLib };
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/crypto/EType.java b/jdk/src/share/classes/sun/security/krb5/internal/crypto/EType.java
index 1dcf108..91d0c2f 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/crypto/EType.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/EType.java
@@ -55,11 +55,11 @@
     }
 
     public static void initStatic() {
-        boolean allowed = true;
+        boolean allowed = false;
         try {
             Config cfg = Config.getInstance();
             String temp = cfg.get("libdefaults", "allow_weak_crypto");
-            if (temp != null && temp.equals("false")) allowed = false;
+            if (temp != null && temp.equals("true")) allowed = true;
         } catch (Exception exc) {
             if (DEBUG) {
                 System.out.println ("Exception in getting allow_weak_crypto, " +
diff --git a/jdk/src/share/classes/sun/security/pkcs11/Config.java b/jdk/src/share/classes/sun/security/pkcs11/Config.java
index 88fce08..4613719 100644
--- a/jdk/src/share/classes/sun/security/pkcs11/Config.java
+++ b/jdk/src/share/classes/sun/security/pkcs11/Config.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -643,9 +643,7 @@
     //
 
     private String parseLibrary(String keyword) throws IOException {
-        checkDup(keyword);
-        parseEquals();
-        String lib = parseLine();
+        String lib = parseStringEntry(keyword);
         lib = expand(lib);
         int i = lib.indexOf("/$ISA/");
         if (i != -1) {
diff --git a/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java b/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java
index 44121fb..6fe59f8 100644
--- a/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -460,7 +460,7 @@
         }
 
         int result = inLen + bytesBuffered;
-        if (blockSize != 0) {
+        if (blockSize != 0 && blockMode != MODE_CTR) {
             // minus the number of bytes in the last incomplete block.
             result -= (result & (blockSize - 1));
         }
diff --git a/jdk/src/share/classes/sun/security/pkcs11/P11ECKeyFactory.java b/jdk/src/share/classes/sun/security/pkcs11/P11ECKeyFactory.java
index a4c48e7..d12daef 100644
--- a/jdk/src/share/classes/sun/security/pkcs11/P11ECKeyFactory.java
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11ECKeyFactory.java
@@ -32,15 +32,12 @@
 import java.security.interfaces.*;
 import java.security.spec.*;
 
-import sun.security.ec.ECPublicKeyImpl;
-import sun.security.ec.ECParameters;
-import sun.security.ec.NamedCurve;
-
 import static sun.security.pkcs11.TemplateManager.*;
 import sun.security.pkcs11.wrapper.*;
 import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
 
 import sun.security.util.DerValue;
+import sun.security.util.ECUtil;
 
 /**
  * EC KeyFactory implemenation.
@@ -49,46 +46,56 @@
  * @since   1.6
  */
 final class P11ECKeyFactory extends P11KeyFactory {
+    private static Provider sunECprovider;
+
+    private static Provider getSunECProvider() {
+        if (sunECprovider == null) {
+            sunECprovider = Security.getProvider("SunEC");
+            if (sunECprovider == null) {
+                throw new RuntimeException("Cannot load SunEC provider");
+            }
+        }
+
+        return sunECprovider;
+    }
 
     P11ECKeyFactory(Token token, String algorithm) {
         super(token, algorithm);
     }
 
     static ECParameterSpec getECParameterSpec(String name) {
-        return NamedCurve.getECParameterSpec(name);
+        return ECUtil.getECParameterSpec(getSunECProvider(), name);
     }
 
     static ECParameterSpec getECParameterSpec(int keySize) {
-        return NamedCurve.getECParameterSpec(keySize);
+        return ECUtil.getECParameterSpec(getSunECProvider(), keySize);
     }
 
     // Check that spec is a known supported curve and convert it to our
     // ECParameterSpec subclass. If not possible, return null.
     static ECParameterSpec getECParameterSpec(ECParameterSpec spec) {
-        return ECParameters.getNamedCurve(spec);
+        return ECUtil.getECParameterSpec(getSunECProvider(), spec);
     }
 
     static ECParameterSpec decodeParameters(byte[] params) throws IOException {
-        return ECParameters.decodeParameters(params);
+        return ECUtil.getECParameterSpec(getSunECProvider(), params);
     }
 
     static byte[] encodeParameters(ECParameterSpec params) {
-        return ECParameters.encodeParameters(params);
+        return ECUtil.encodeECParameterSpec(getSunECProvider(), params);
     }
 
     static ECPoint decodePoint(byte[] encoded, EllipticCurve curve) throws IOException {
-        return ECParameters.decodePoint(encoded, curve);
+        return ECUtil.decodePoint(encoded, curve);
     }
 
     // Used by ECDH KeyAgreement
     static byte[] getEncodedPublicValue(PublicKey key) throws InvalidKeyException {
-        if (key instanceof ECPublicKeyImpl) {
-            return ((ECPublicKeyImpl)key).getEncodedPublicValue();
-        } else if (key instanceof ECPublicKey) {
+        if (key instanceof ECPublicKey) {
             ECPublicKey ecKey = (ECPublicKey)key;
             ECPoint w = ecKey.getW();
             ECParameterSpec params = ecKey.getParams();
-            return ECParameters.encodePoint(w, params.getCurve());
+            return ECUtil.encodePoint(w, params.getCurve());
         } else {
             // should never occur
             throw new InvalidKeyException
@@ -107,7 +114,13 @@
             } else if ("X.509".equals(key.getFormat())) {
                 // let Sun provider parse for us, then recurse
                 byte[] encoded = key.getEncoded();
-                key = new sun.security.ec.ECPublicKeyImpl(encoded);
+
+                try {
+                    key = ECUtil.decodeX509ECPublicKey(encoded);
+                } catch (InvalidKeySpecException ikse) {
+                    throw new InvalidKeyException(ikse);
+                }
+
                 return implTranslatePublicKey(key);
             } else {
                 throw new InvalidKeyException("PublicKey must be instance "
@@ -130,7 +143,13 @@
             } else if ("PKCS#8".equals(key.getFormat())) {
                 // let Sun provider parse for us, then recurse
                 byte[] encoded = key.getEncoded();
-                key = new sun.security.ec.ECPrivateKeyImpl(encoded);
+
+                try {
+                    key = ECUtil.decodePKCS8ECPrivateKey(encoded);
+                } catch (InvalidKeySpecException ikse) {
+                    throw new InvalidKeyException(ikse);
+                }
+
                 return implTranslatePrivateKey(key);
             } else {
                 throw new InvalidKeyException("PrivateKey must be instance "
@@ -148,7 +167,7 @@
         if (keySpec instanceof X509EncodedKeySpec) {
             try {
                 byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded();
-                PublicKey key = new sun.security.ec.ECPublicKeyImpl(encoded);
+                PublicKey key = ECUtil.decodeX509ECPublicKey(encoded);
                 return implTranslatePublicKey(key);
             } catch (InvalidKeyException e) {
                 throw new InvalidKeySpecException
@@ -178,7 +197,7 @@
         if (keySpec instanceof PKCS8EncodedKeySpec) {
             try {
                 byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded();
-                PrivateKey key = new sun.security.ec.ECPrivateKeyImpl(encoded);
+                PrivateKey key = ECUtil.decodePKCS8ECPrivateKey(encoded);
                 return implTranslatePrivateKey(key);
             } catch (GeneralSecurityException e) {
                 throw new InvalidKeySpecException
@@ -201,10 +220,12 @@
         }
     }
 
-    private PublicKey generatePublic(ECPoint point, ECParameterSpec params) throws PKCS11Exception {
-        byte[] encodedParams = ECParameters.encodeParameters(params);
+    private PublicKey generatePublic(ECPoint point, ECParameterSpec params)
+            throws PKCS11Exception {
+        byte[] encodedParams =
+            ECUtil.encodeECParameterSpec(getSunECProvider(), params);
         byte[] encodedPoint =
-            ECParameters.encodePoint(point, params.getCurve());
+            ECUtil.encodePoint(point, params.getCurve());
 
         // Check whether the X9.63 encoding of an EC point shall be wrapped
         // in an ASN.1 OCTET STRING
@@ -238,8 +259,10 @@
         }
     }
 
-    private PrivateKey generatePrivate(BigInteger s, ECParameterSpec params) throws PKCS11Exception {
-        byte[] encodedParams = ECParameters.encodeParameters(params);
+    private PrivateKey generatePrivate(BigInteger s, ECParameterSpec params)
+            throws PKCS11Exception {
+        byte[] encodedParams =
+            ECUtil.encodeECParameterSpec(getSunECProvider(), params);
         CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
             new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
             new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_EC),
@@ -304,7 +327,7 @@
     }
 
     KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {
-        return KeyFactory.getInstance("EC", "SunEC");
+        return KeyFactory.getInstance("EC", getSunECProvider());
     }
 
 }
diff --git a/jdk/src/share/classes/sun/security/pkcs11/P11Key.java b/jdk/src/share/classes/sun/security/pkcs11/P11Key.java
index acc35f2..dd0ec5f 100644
--- a/jdk/src/share/classes/sun/security/pkcs11/P11Key.java
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11Key.java
@@ -47,6 +47,7 @@
 
 import sun.security.util.DerValue;
 import sun.security.util.Length;
+import sun.security.util.ECUtil;
 
 /**
  * Key implementation classes.
@@ -984,9 +985,9 @@
             if (encoded == null) {
                 fetchValues();
                 try {
-                    Key key = new sun.security.ec.ECPrivateKeyImpl(s, params);
+                    Key key = ECUtil.generateECPrivateKey(s, params);
                     encoded = key.getEncoded();
-                } catch (InvalidKeyException e) {
+                } catch (InvalidKeySpecException e) {
                     throw new ProviderException(e);
                 }
             }
@@ -1064,9 +1065,8 @@
             if (encoded == null) {
                 fetchValues();
                 try {
-                    Key key = new sun.security.ec.ECPublicKeyImpl(w, params);
-                    encoded = key.getEncoded();
-                } catch (InvalidKeyException e) {
+                    return ECUtil.x509EncodeECPublicKey(w, params);
+                } catch (InvalidKeySpecException e) {
                     throw new ProviderException(e);
                 }
             }
diff --git a/jdk/src/share/classes/sun/security/pkcs11/P11KeyStore.java b/jdk/src/share/classes/sun/security/pkcs11/P11KeyStore.java
index cbca68f3..5f31003 100644
--- a/jdk/src/share/classes/sun/security/pkcs11/P11KeyStore.java
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11KeyStore.java
@@ -65,6 +65,7 @@
 
 import sun.security.util.Debug;
 import sun.security.util.DerValue;
+import sun.security.util.ECUtil;
 
 import sun.security.ec.ECParameters;
 
@@ -1351,7 +1352,8 @@
             token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
             byte[] encodedParams = attrs[0].getByteArray();
             try {
-                ECParameterSpec params = ECParameters.decodeParameters(encodedParams);
+                ECParameterSpec params =
+                    ECUtil.getECParameterSpec(null, encodedParams);
                 keyLength = params.getCurve().getField().getFieldSize();
             } catch (IOException e) {
                 // we do not want to accept key with unsupported parameters
@@ -1726,7 +1728,8 @@
                 idAttrs[0] = new CK_ATTRIBUTE(CKA_ID, alias);
             }
 
-            byte[] encodedParams = ECParameters.encodeParameters(ecKey.getParams());
+            byte[] encodedParams =
+                ECUtil.encodeECParameterSpec(null, ecKey.getParams());
             attrs = new CK_ATTRIBUTE[] {
                 ATTR_TOKEN_TRUE,
                 ATTR_CLASS_PKEY,
@@ -1901,7 +1904,7 @@
             ECPublicKey ecPub = (ECPublicKey)publicKey;
             ECPoint point = ecPub.getW();
             ECParameterSpec params = ecPub.getParams();
-            byte[] encodedPoint = ECParameters.encodePoint(point, params.getCurve());
+            byte[] encodedPoint = ECUtil.encodePoint(point, params.getCurve());
             if (id) {
                 attrs[0] = new CK_ATTRIBUTE(CKA_ID, sha1(encodedPoint));
             }
diff --git a/jdk/src/share/classes/sun/security/pkcs11/wrapper/PKCS11.java b/jdk/src/share/classes/sun/security/pkcs11/wrapper/PKCS11.java
index 0ada894..74199cd 100644
--- a/jdk/src/share/classes/sun/security/pkcs11/wrapper/PKCS11.java
+++ b/jdk/src/share/classes/sun/security/pkcs11/wrapper/PKCS11.java
@@ -1528,7 +1528,7 @@
      *
      * @exception Throwable If finalization fails.
      */
-    public void finalize() throws Throwable {
+    protected void finalize() throws Throwable {
         disconnect();
     }
 
diff --git a/jdk/src/share/classes/sun/security/ssl/JsseJce.java b/jdk/src/share/classes/sun/security/ssl/JsseJce.java
index 250cc0d..d128f2e 100644
--- a/jdk/src/share/classes/sun/security/ssl/JsseJce.java
+++ b/jdk/src/share/classes/sun/security/ssl/JsseJce.java
@@ -41,8 +41,7 @@
 import sun.security.jca.Providers;
 import sun.security.jca.ProviderList;
 
-import sun.security.ec.ECParameters;
-import sun.security.ec.NamedCurve;
+import sun.security.util.ECUtil;
 
 import static sun.security.ssl.SunJSSE.cryptoProvider;
 
@@ -383,20 +382,20 @@
     }
 
     static ECParameterSpec getECParameterSpec(String namedCurveOid) {
-        return NamedCurve.getECParameterSpec(namedCurveOid);
+        return ECUtil.getECParameterSpec(cryptoProvider, namedCurveOid);
     }
 
     static String getNamedCurveOid(ECParameterSpec params) {
-        return ECParameters.getCurveName(params);
+        return ECUtil.getCurveName(cryptoProvider, params);
     }
 
     static ECPoint decodePoint(byte[] encoded, EllipticCurve curve)
             throws java.io.IOException {
-        return ECParameters.decodePoint(encoded, curve);
+        return ECUtil.decodePoint(encoded, curve);
     }
 
     static byte[] encodePoint(ECPoint point, EllipticCurve curve) {
-        return ECParameters.encodePoint(point, curve);
+        return ECUtil.encodePoint(point, curve);
     }
 
     // In FIPS mode, set thread local providers; otherwise a no-op.
diff --git a/jdk/src/share/classes/sun/security/ssl/SSLSessionImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLSessionImpl.java
index 8c6ef2c..6cb4170 100644
--- a/jdk/src/share/classes/sun/security/ssl/SSLSessionImpl.java
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSessionImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -822,7 +822,7 @@
      * them are removed.
      */
     @Override
-    public void finalize() {
+    protected void finalize() throws Throwable {
         String[] names = getValueNames();
         for (int i = 0; i < names.length; i++) {
             removeValue(names[i]);
diff --git a/jdk/src/share/classes/sun/security/util/ECKeySizeParameterSpec.java b/jdk/src/share/classes/sun/security/util/ECKeySizeParameterSpec.java
new file mode 100644
index 0000000..58c31b8
--- /dev/null
+++ b/jdk/src/share/classes/sun/security/util/ECKeySizeParameterSpec.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.security.util;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+import sun.security.util.ObjectIdentifier;
+
+/**
+ * This immutable class is used when randomly generating a key pair and the
+ * consumer only specifies the length of the key and therefore a curve for that
+ * key size must be picked from a the list of supported curves using this spec.
+ *
+ * @see AlgorithmParameterSpec
+ * @see ECGenParameterSpec
+ */
+public class ECKeySizeParameterSpec implements AlgorithmParameterSpec {
+
+    private int keySize;
+
+    /**
+     * Creates a parameter specification for EC curve
+     * generation using a standard (or predefined) key size
+     * <code>keySize</code> in order to generate the corresponding
+     * (precomputed) elliptic curve.
+     * <p>
+     * Note, if the curve of the specified length is not supported,
+     * <code>AlgorithmParameters.init</code> will throw an exception.
+     *
+     * @param keySize the key size of the curve to lookup
+     */
+    public ECKeySizeParameterSpec(int keySize) {
+        this.keySize = keySize;
+    }
+
+    /**
+     * Returns the key size of this spec.
+     *
+     * @return the standard or predefined key size.
+     */
+    public int getKeySize() {
+        return keySize;
+    }
+}
diff --git a/jdk/src/share/classes/sun/security/util/ECUtil.java b/jdk/src/share/classes/sun/security/util/ECUtil.java
new file mode 100644
index 0000000..84cb64b
--- /dev/null
+++ b/jdk/src/share/classes/sun/security/util/ECUtil.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.io.IOException;
+
+import java.math.BigInteger;
+
+import java.security.*;
+
+import java.security.interfaces.*;
+
+import java.security.spec.*;
+
+import java.util.Arrays;
+
+import sun.security.x509.X509Key;
+
+public class ECUtil {
+
+    // Used by SunPKCS11 and SunJSSE.
+    public static ECPoint decodePoint(byte[] data, EllipticCurve curve)
+            throws IOException {
+        if ((data.length == 0) || (data[0] != 4)) {
+            throw new IOException("Only uncompressed point format supported");
+        }
+        // Per ANSI X9.62, an encoded point is a 1 byte type followed by
+        // ceiling(log base 2 field-size / 8) bytes of x and the same of y.
+        int n = (data.length - 1) / 2;
+        if (n != ((curve.getField().getFieldSize() + 7 ) >> 3)) {
+            throw new IOException("Point does not match field size");
+        }
+
+        byte[] xb = Arrays.copyOfRange(data, 1, 1 + n);
+        byte[] yb = Arrays.copyOfRange(data, n + 1, n + 1 + n);
+
+        return new ECPoint(new BigInteger(1, xb), new BigInteger(1, yb));
+    }
+
+    // Used by SunPKCS11 and SunJSSE.
+    public static byte[] encodePoint(ECPoint point, EllipticCurve curve) {
+        // get field size in bytes (rounding up)
+        int n = (curve.getField().getFieldSize() + 7) >> 3;
+        byte[] xb = trimZeroes(point.getAffineX().toByteArray());
+        byte[] yb = trimZeroes(point.getAffineY().toByteArray());
+        if ((xb.length > n) || (yb.length > n)) {
+            throw new RuntimeException
+                ("Point coordinates do not match field size");
+        }
+        byte[] b = new byte[1 + (n << 1)];
+        b[0] = 4; // uncompressed
+        System.arraycopy(xb, 0, b, n - xb.length + 1, xb.length);
+        System.arraycopy(yb, 0, b, b.length - yb.length, yb.length);
+        return b;
+    }
+
+    public static byte[] trimZeroes(byte[] b) {
+        int i = 0;
+        while ((i < b.length - 1) && (b[i] == 0)) {
+            i++;
+        }
+        if (i == 0) {
+            return b;
+        }
+
+        return Arrays.copyOfRange(b, i, b.length);
+    }
+
+    private static KeyFactory getKeyFactory() {
+        try {
+            return KeyFactory.getInstance("EC", "SunEC");
+        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static ECPublicKey decodeX509ECPublicKey(byte[] encoded)
+            throws InvalidKeySpecException {
+        KeyFactory keyFactory = getKeyFactory();
+        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded);
+
+        return (ECPublicKey)keyFactory.generatePublic(keySpec);
+    }
+
+    public static byte[] x509EncodeECPublicKey(ECPoint w,
+            ECParameterSpec params) throws InvalidKeySpecException {
+        KeyFactory keyFactory = getKeyFactory();
+        ECPublicKeySpec keySpec = new ECPublicKeySpec(w, params);
+        X509Key key = (X509Key)keyFactory.generatePublic(keySpec);
+
+        return key.getEncoded();
+    }
+
+    public static ECPrivateKey decodePKCS8ECPrivateKey(byte[] encoded)
+            throws InvalidKeySpecException {
+        KeyFactory keyFactory = getKeyFactory();
+        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
+
+        return (ECPrivateKey)keyFactory.generatePrivate(keySpec);
+    }
+
+    public static ECPrivateKey generateECPrivateKey(BigInteger s,
+            ECParameterSpec params) throws InvalidKeySpecException {
+        KeyFactory keyFactory = getKeyFactory();
+        ECPrivateKeySpec keySpec = new ECPrivateKeySpec(s, params);
+
+        return (ECPrivateKey)keyFactory.generatePrivate(keySpec);
+    }
+
+    private static AlgorithmParameters getECParameters(Provider p) {
+        try {
+            if (p != null) {
+                return AlgorithmParameters.getInstance("EC", p);
+            }
+
+            return AlgorithmParameters.getInstance("EC");
+        } catch (NoSuchAlgorithmException nsae) {
+            throw new RuntimeException(nsae);
+        }
+    }
+
+    public static byte[] encodeECParameterSpec(Provider p,
+                                               ECParameterSpec spec) {
+        AlgorithmParameters parameters = getECParameters(p);
+
+        try {
+            parameters.init(spec);
+        } catch (InvalidParameterSpecException ipse) {
+            throw new RuntimeException("Not a known named curve: " + spec);
+        }
+
+        try {
+            return parameters.getEncoded();
+        } catch (IOException ioe) {
+            // it is a bug if this should happen
+            throw new RuntimeException(ioe);
+        }
+    }
+
+    public static ECParameterSpec getECParameterSpec(Provider p,
+                                                     ECParameterSpec spec) {
+        AlgorithmParameters parameters = getECParameters(p);
+
+        try {
+            parameters.init(spec);
+            return parameters.getParameterSpec(ECParameterSpec.class);
+        } catch (InvalidParameterSpecException ipse) {
+            return null;
+        }
+    }
+
+    public static ECParameterSpec getECParameterSpec(Provider p,
+                                                     byte[] params)
+            throws IOException {
+        AlgorithmParameters parameters = getECParameters(p);
+
+        parameters.init(params);
+
+        try {
+            return parameters.getParameterSpec(ECParameterSpec.class);
+        } catch (InvalidParameterSpecException ipse) {
+            return null;
+        }
+    }
+
+    public static ECParameterSpec getECParameterSpec(Provider p, String name) {
+        AlgorithmParameters parameters = getECParameters(p);
+
+        try {
+            parameters.init(new ECGenParameterSpec(name));
+            return parameters.getParameterSpec(ECParameterSpec.class);
+        } catch (InvalidParameterSpecException ipse) {
+            return null;
+        }
+    }
+
+    public static ECParameterSpec getECParameterSpec(Provider p, int keySize) {
+        AlgorithmParameters parameters = getECParameters(p);
+
+        try {
+            parameters.init(new ECKeySizeParameterSpec(keySize));
+            return parameters.getParameterSpec(ECParameterSpec.class);
+        } catch (InvalidParameterSpecException ipse) {
+            return null;
+        }
+
+    }
+
+    public static String getCurveName(Provider p, ECParameterSpec spec) {
+        ECGenParameterSpec nameSpec;
+        AlgorithmParameters parameters = getECParameters(p);
+
+        try {
+            parameters.init(spec);
+            nameSpec = parameters.getParameterSpec(ECGenParameterSpec.class);
+        } catch (InvalidParameterSpecException ipse) {
+            return null;
+        }
+
+        if (nameSpec == null) {
+            return null;
+        }
+
+        return nameSpec.getName();
+    }
+
+    private ECUtil() {}
+}
diff --git a/jdk/src/share/classes/sun/swing/JLightweightFrame.java b/jdk/src/share/classes/sun/swing/JLightweightFrame.java
index 162186f..a9ac437 100644
--- a/jdk/src/share/classes/sun/swing/JLightweightFrame.java
+++ b/jdk/src/share/classes/sun/swing/JLightweightFrame.java
@@ -35,6 +35,7 @@
 import java.awt.Rectangle;
 import java.awt.image.BufferedImage;
 import java.awt.image.DataBufferInt;
+import java.security.AccessController;
 
 import javax.swing.JLayeredPane;
 import javax.swing.JPanel;
@@ -43,6 +44,7 @@
 import javax.swing.RootPaneContainer;
 
 import sun.awt.LightweightFrame;
+import sun.security.action.GetPropertyAction;
 
 /**
  * The frame serves as a lightweight container which paints its content
@@ -66,11 +68,27 @@
     private BufferedImage bbImage;
 
     /**
+     * {@code copyBufferEnabled}, true by default, defines the following strategy.
+     * A duplicating (copy) buffer is created for the original pixel buffer.
+     * The copy buffer is synchronized with the original buffer every time the
+     * latter changes. {@code JLightweightFrame} passes the copy buffer array
+     * to the {@link LightweightContent#imageBufferReset} method. The code spot
+     * which synchronizes two buffers becomes the only critical section guarded
+     * by the lock (managed with the {@link LightweightContent#paintLock()},
+     * {@link LightweightContent#paintUnlock()} methods).
+     */
+    private boolean copyBufferEnabled;
+    private int[] copyBuffer;
+
+    /**
      * Constructs a new, initially invisible {@code JLightweightFrame}
      * instance.
      */
     public JLightweightFrame() {
         super();
+        copyBufferEnabled = "true".equals(AccessController.
+            doPrivileged(new GetPropertyAction("jlf.copyBufferEnabled", "true")));
+
         add(rootPane, BorderLayout.CENTER);
         setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
         if (getGraphicsConfiguration().isTranslucencyCapable()) {
@@ -124,16 +142,37 @@
         if (content != null) content.focusUngrabbed();
     }
 
+    private void syncCopyBuffer(boolean reset, int x, int y, int w, int h) {
+        content.paintLock();
+        try {
+            int[] srcBuffer = ((DataBufferInt)bbImage.getRaster().getDataBuffer()).getData();
+            if (reset) {
+                copyBuffer = new int[srcBuffer.length];
+            }
+            int linestride = bbImage.getWidth();
+
+            for (int i=0; i<h; i++) {
+                int from = (y + i) * linestride + x;
+                System.arraycopy(srcBuffer, from, copyBuffer, from, w);
+            }
+        } finally {
+            content.paintUnlock();
+        }
+    }
+
     private void initInterior() {
         contentPane = new JPanel() {
             @Override
             public void paint(Graphics g) {
-                content.paintLock();
+                if (!copyBufferEnabled) {
+                    content.paintLock();
+                }
                 try {
                     super.paint(g);
 
                     final Rectangle clip = g.getClipBounds() != null ?
-                            g.getClipBounds() : new Rectangle(0, 0, contentPane.getWidth(), contentPane.getHeight());
+                            g.getClipBounds() :
+                            new Rectangle(0, 0, contentPane.getWidth(), contentPane.getHeight());
 
                     clip.x = Math.max(0, clip.x);
                     clip.y = Math.max(0, clip.y);
@@ -143,11 +182,16 @@
                     EventQueue.invokeLater(new Runnable() {
                         @Override
                         public void run() {
+                            if (copyBufferEnabled) {
+                                syncCopyBuffer(false, clip.x, clip.y, clip.width, clip.height);
+                            }
                             content.imageUpdated(clip.x, clip.y, clip.width, clip.height);
                         }
                     });
                 } finally {
-                    content.paintUnlock();
+                    if (!copyBufferEnabled) {
+                        content.paintUnlock();
+                    }
                 }
             }
             @Override
@@ -167,8 +211,9 @@
         if (width == 0 || height == 0) {
             return;
         }
-
-        content.paintLock();
+        if (!copyBufferEnabled) {
+            content.paintLock();
+        }
         try {
             if ((bbImage == null) || (width != bbImage.getWidth()) || (height != bbImage.getHeight())) {
                 boolean createBB = true;
@@ -204,14 +249,21 @@
                             oldBB.flush();
                         }
                     }
-                    DataBufferInt dataBuf = (DataBufferInt)bbImage.getRaster().getDataBuffer();
-                    content.imageBufferReset(dataBuf.getData(), 0, 0, width, height, bbImage.getWidth());
-                } else {
-                    content.imageReshaped(0, 0, width, height);
+                    int[] pixels = ((DataBufferInt)bbImage.getRaster().getDataBuffer()).getData();
+                    if (copyBufferEnabled) {
+                        syncCopyBuffer(true, 0, 0, width, height);
+                        pixels = copyBuffer;
+                    }
+                    content.imageBufferReset(pixels, 0, 0, width, height, bbImage.getWidth());
+                    return;
                 }
             }
+            content.imageReshaped(0, 0, width, height);
+
         } finally {
-            content.paintUnlock();
+            if (!copyBufferEnabled) {
+                content.paintUnlock();
+            }
         }
     }
 
diff --git a/jdk/src/share/classes/sun/util/calendar/LocalGregorianCalendar.java b/jdk/src/share/classes/sun/util/calendar/LocalGregorianCalendar.java
index aa0a73b..9a9b663 100644
--- a/jdk/src/share/classes/sun/util/calendar/LocalGregorianCalendar.java
+++ b/jdk/src/share/classes/sun/util/calendar/LocalGregorianCalendar.java
@@ -246,16 +246,16 @@
                 return false;
             }
             ldate.setNormalizedYear(era.getSinceDate().getYear() + ldate.getYear() - 1);
-            // If it's not the last Era, validate the date.
-            if (era != eras[eras.length - 1]) {
-                Date tmp = newCalendarDate(date.getZone());
-                tmp.setEra(era).setDate(date.getYear(), date.getMonth(), date.getDayOfMonth());
-                normalize(tmp);
-                if (tmp.getEra() != era) {
-                    return false;
-                }
+            Date tmp = newCalendarDate(date.getZone());
+            tmp.setEra(era).setDate(date.getYear(), date.getMonth(), date.getDayOfMonth());
+            normalize(tmp);
+            if (tmp.getEra() != era) {
+                return false;
             }
         } else {
+            if (date.getYear() >= eras[0].getSinceDate().getYear()) {
+                return false;
+            }
             ldate.setNormalizedYear(ldate.getYear());
         }
         return super.validate(ldate);
diff --git a/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java b/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java
index b003c2e..60cd919 100644
--- a/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java
+++ b/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java
@@ -585,12 +585,17 @@
                 dstSavings = (startRule.offsetAfter - startRule.offsetBefore) * 1000;
 
                 // Note: known mismatching -> Asia/Amman
+                //                            Asia/Gaza
+                //                            Asia/Hebron
                 // ZoneInfo :      startDayOfWeek=5     <= Thursday
                 //                 startTime=86400000   <= 24 hours
                 // This:           startDayOfWeek=6
                 //                 startTime=0
                 // Below is the workaround, it probably slows down everyone a little
-                if (params[2] == 6 && params[3] == 0 && zoneId.equals("Asia/Amman")) {
+                if (params[2] == 6 && params[3] == 0 &&
+                    (zoneId.equals("Asia/Amman") ||
+                     zoneId.equals("Asia/Gaza") ||
+                     zoneId.equals("Asia/Hebron"))) {
                     params[2] = 5;
                     params[3] = 86400000;
                 }
diff --git a/jdk/src/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java b/jdk/src/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java
index 8c279c1..c999780 100644
--- a/jdk/src/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java
+++ b/jdk/src/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -239,14 +239,25 @@
 
             for (int i = 1; i <= 4; i ++) {
                 names[i] = tznp.getDisplayName(id, i>=3, i%2, locale);
-                if (i >= 3 && names[i] == null) {
-                    names[i] = names[i-2];
+
+                if (names[i] == null) {
+                    switch (i) {
+                    case 1:
+                        // this id seems not localized by this provider
+                        return null;
+                    case 2:
+                    case 4:
+                        // If the display name for SHORT is not supplied,
+                        // copy the LONG name.
+                        names[i] = names[i-1];
+                        break;
+                    case 3:
+                        // If the display name for DST is not supplied,
+                        // copy the "standard" name.
+                        names[3] = names[1];
+                        break;
                 }
             }
-
-            if (names[1] == null) {
-                // this id seems not localized by this provider
-                names = null;
             }
 
             return names;
diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java
index 59af1d2..974fd26 100644
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java
@@ -365,7 +365,7 @@
             {"Africa/Porto-Novo", WAT},
             {"Africa/Sao_Tome", GMT},
             {"Africa/Timbuktu", GMT},
-            {"Africa/Tripoli", EET},
+            {"Africa/Tripoli", CET},
             {"Africa/Tunis", CET},
             {"Africa/Windhoek", WAT},
             {"America/Adak", HAST},
@@ -646,6 +646,10 @@
             {"Asia/Kashgar", CTT},
             {"Asia/Kathmandu", NPT},
             {"Asia/Katmandu", NPT},
+            {"Asia/Khandyga", new String[] {"Khandyga Time", "YAKT",
+                                            "Khandyga Summer Time", "YAKST",
+                                            "Khandyga Time", "YAKT"}},
+
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"Krasnoyarsk Time", "KRAT",
                                                "Krasnoyarsk Summer Time", "KRAST",
@@ -703,6 +707,9 @@
             {"Asia/Ulaanbaatar", ULAT},
             {"Asia/Ulan_Bator", ULAT},
             {"Asia/Urumqi", CTT},
+            {"Asia/Ust-Nera", new String[] {"Ust-Nera Time", "VLAT",
+                                            "Ust-Nera Summer Time", "VLAST",
+                                            "Ust-Nera Time", "VLAT"}},
             {"Asia/Vientiane", ICT},
             {"Asia/Vladivostok", new String[] {"Vladivostok Time", "VLAT",
                                                "Vladivostok Summer Time", "VLAST",
@@ -888,7 +895,7 @@
             {"Jamaica", EST},
             {"Japan", JST},
             {"Kwajalein", MHT},
-            {"Libya", EET},
+            {"Libya", CET},
             {"MET", new String[] {"Middle Europe Time", "MET",
                                   "Middle Europe Summer Time", "MEST",
                                   "Middle Europe Time", "MET"}},
diff --git a/jdk/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java b/jdk/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java
index ab1e367..8dc71d7 100644
--- a/jdk/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java
+++ b/jdk/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java
@@ -289,7 +289,7 @@
             {"Africa/Porto-Novo", WAT},
             {"Africa/Sao_Tome", GMT},
             {"Africa/Timbuktu", GMT},
-            {"Africa/Tripoli", EET},
+            {"Africa/Tripoli", CET},
             {"Africa/Tunis", CET},
             {"Africa/Windhoek", WAT},
             {"America/Adak", HAST},
@@ -535,6 +535,8 @@
             {"Asia/Kashgar", CTT},
             {"Asia/Kathmandu", NPT},
             {"Asia/Katmandu", NPT},
+            {"Asia/Khandyga", new String[] {"Khandyga Time", "YAKT",
+                                            "Khandyga Summer Time", "YAKST"}},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"Krasnojarsker Zeit", "KRAT",
                                                "Krasnojarsker Sommerzeit", "KRAST"}},
@@ -583,6 +585,8 @@
             {"Asia/Ulaanbaatar", ULAT},
             {"Asia/Ulan_Bator", ULAT},
             {"Asia/Urumqi", CTT},
+            {"Asia/Ust-Nera", new String[] {"Ust-Nera Time", "VLAT",
+                                            "Ust-Nera Summer Time", "VLAST"}},
             {"Asia/Vientiane", ICT},
             {"Asia/Vladivostok", new String[] {"Wladiwostok Zeit", "VLAT",
                                                "Wladiwostok Sommerzeit", "VLAST"}},
@@ -750,7 +754,7 @@
             {"Jamaica", EST},
             {"Japan", JST},
             {"Kwajalein", MHT},
-            {"Libya", EET},
+            {"Libya", CET},
             {"MET", new String[] {"Zentraleurop\u00e4ische Zeit", "MET",
                                   "Zentraleurop\u00e4ische Sommerzeit", "MEST"}},
             {"Mexico/BajaNorte", PST},
diff --git a/jdk/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java b/jdk/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java
index 7e4a41a..66e3e02 100644
--- a/jdk/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java
+++ b/jdk/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java
@@ -289,7 +289,7 @@
             {"Africa/Porto-Novo", WAT},
             {"Africa/Sao_Tome", GMT},
             {"Africa/Timbuktu", GMT},
-            {"Africa/Tripoli", EET},
+            {"Africa/Tripoli", CET},
             {"Africa/Tunis", CET},
             {"Africa/Windhoek", WAT},
             {"America/Adak", HAST},
@@ -535,6 +535,8 @@
             {"Asia/Kashgar", CTT},
             {"Asia/Kathmandu", NPT},
             {"Asia/Katmandu", NPT},
+            {"Asia/Khandyga", new String[] {"Khandyga Time", "YAKT",
+                                            "Khandyga Summer Time", "YAKST"}},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"Hora de Krasnoyarsk", "KRAT",
                                                "Hora de verano de Krasnoyarsk", "KRAST"}},
@@ -583,6 +585,8 @@
             {"Asia/Ulaanbaatar", ULAT},
             {"Asia/Ulan_Bator", ULAT},
             {"Asia/Urumqi", CTT},
+            {"Asia/Ust-Nera", new String[] {"Ust-Nera Time", "VLAT",
+                                            "Ust-Nera Summer Time", "VLAST"}},
             {"Asia/Vientiane", ICT},
             {"Asia/Vladivostok", new String[] {"Hora de Vladivostok", "VLAT",
                                                "Hora de verano de Vladivostok", "VLAST"}},
@@ -750,7 +754,7 @@
             {"Jamaica", EST},
             {"Japan", JST},
             {"Kwajalein", MHT},
-            {"Libya", EET},
+            {"Libya", CET},
             {"MET", new String[] {"Hora de Europa Central", "MET",
                                   "Hora de verano de Europa Central", "MEST"}},
             {"Mexico/BajaNorte", PST},
diff --git a/jdk/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java b/jdk/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java
index fc579bd..2d96081 100644
--- a/jdk/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java
+++ b/jdk/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java
@@ -289,7 +289,7 @@
             {"Africa/Porto-Novo", WAT},
             {"Africa/Sao_Tome", GMT},
             {"Africa/Timbuktu", GMT},
-            {"Africa/Tripoli", EET},
+            {"Africa/Tripoli", CET},
             {"Africa/Tunis", CET},
             {"Africa/Windhoek", WAT},
             {"America/Adak", HAST},
@@ -535,6 +535,8 @@
             {"Asia/Kashgar", CTT},
             {"Asia/Kathmandu", NPT},
             {"Asia/Katmandu", NPT},
+            {"Asia/Khandyga", new String[] {"Khandyga Time", "YAKT",
+                                            "Khandyga Summer Time", "YAKST"}},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"Heure de Krasno\u00efarsk", "KRAT",
                                                "Heure d'\u00e9t\u00e9 de Krasno\u00efarsk", "KRAST"}},
@@ -583,6 +585,8 @@
             {"Asia/Ulaanbaatar", ULAT},
             {"Asia/Ulan_Bator", ULAT},
             {"Asia/Urumqi", CTT},
+            {"Asia/Ust-Nera", new String[] {"Ust-Nera Time", "VLAT",
+                                            "Ust-Nera Summer Time", "VLAST"}},
             {"Asia/Vientiane", ICT},
             {"Asia/Vladivostok", new String[] {"Heure de Vladivostok", "VLAT",
                                                "Heure d'\u00e9t\u00e9 de Vladivostok", "VLAST"}},
@@ -750,7 +754,7 @@
             {"Jamaica", EST},
             {"Japan", JST},
             {"Kwajalein", MHT},
-            {"Libya", EET},
+            {"Libya", CET},
             {"MET", new String[] {"Heure de l'Europe centrale", "MET",
                                   "Heure d'\u00e9t\u00e9 de l'Europe centrale", "MEST"}},
             {"Mexico/BajaNorte", PST},
diff --git a/jdk/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java b/jdk/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java
index 12cf3cf..18b4344 100644
--- a/jdk/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java
+++ b/jdk/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java
@@ -289,7 +289,7 @@
             {"Africa/Porto-Novo", WAT},
             {"Africa/Sao_Tome", GMT},
             {"Africa/Timbuktu", GMT},
-            {"Africa/Tripoli", EET},
+            {"Africa/Tripoli", CET},
             {"Africa/Tunis", CET},
             {"Africa/Windhoek", WAT},
             {"America/Adak", HAST},
@@ -536,6 +536,8 @@
             {"Asia/Kathmandu", NPT},
             {"Asia/Katmandu", NPT},
             {"Asia/Kolkata", IST},
+            {"Asia/Khandyga", new String[] {"Khandyga Time", "YAKT",
+                                            "Khandyga Summer Time", "YAKST"}},
             {"Asia/Krasnoyarsk", new String[] {"Ora di Krasnojarsk", "KRAT",
                                                "Ora estiva di Krasnojarsk", "KRAST"}},
             {"Asia/Kuala_Lumpur", MYT},
@@ -583,6 +585,8 @@
             {"Asia/Ulaanbaatar", ULAT},
             {"Asia/Ulan_Bator", ULAT},
             {"Asia/Urumqi", CTT},
+            {"Asia/Ust-Nera", new String[] {"Ust-Nera Time", "VLAT",
+                                            "Ust-Nera Summer Time", "VLAST"}},
             {"Asia/Vientiane", ICT},
             {"Asia/Vladivostok", new String[] {"Ora di Vladivostok", "VLAT",
                                                "Ora estiva di Vladivostok", "VLAST"}},
@@ -750,7 +754,7 @@
             {"Jamaica", EST},
             {"Japan", JST},
             {"Kwajalein", MHT},
-            {"Libya", EET},
+            {"Libya", CET},
             {"MET", new String[] {"Ora dell'Europa centrale", "MET",
                                   "Ora estiva dell'Europa centrale", "MEST"}},
             {"Mexico/BajaNorte", PST},
diff --git a/jdk/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java b/jdk/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java
index 0c1e64a..5001fd2 100644
--- a/jdk/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java
+++ b/jdk/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java
@@ -289,7 +289,7 @@
             {"Africa/Porto-Novo", WAT},
             {"Africa/Sao_Tome", GMT},
             {"Africa/Timbuktu", GMT},
-            {"Africa/Tripoli", EET},
+            {"Africa/Tripoli", CET},
             {"Africa/Tunis", CET},
             {"Africa/Windhoek", WAT},
             {"America/Adak", HAST},
@@ -535,6 +535,8 @@
             {"Asia/Kashgar", CTT},
             {"Asia/Kathmandu", NPT},
             {"Asia/Katmandu", NPT},
+            {"Asia/Khandyga", new String[] {"Khandyga Time", "YAKT",
+                                            "Khandyga Summer Time", "YAKST"}},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"\u30af\u30e9\u30b9\u30ce\u30e4\u30eb\u30b9\u30af\u6642\u9593", "KRAT",
                                                "\u30af\u30e9\u30b9\u30ce\u30e4\u30eb\u30b9\u30af\u590f\u6642\u9593", "KRAST"}},
@@ -583,6 +585,8 @@
             {"Asia/Ulaanbaatar", ULAT},
             {"Asia/Ulan_Bator", ULAT},
             {"Asia/Urumqi", CTT},
+            {"Asia/Ust-Nera", new String[] {"Ust-Nera Time", "VLAT",
+                                            "Ust-Nera Summer Time", "VLAST"}},
             {"Asia/Vientiane", ICT},
             {"Asia/Vladivostok", new String[] {"\u30a6\u30e9\u30b8\u30aa\u30b9\u30c8\u30af\u6642\u9593", "VLAT",
                                                "\u30a6\u30e9\u30b8\u30aa\u30b9\u30c8\u30af\u590f\u6642\u9593", "VLAST"}},
@@ -750,7 +754,7 @@
             {"Jamaica", EST},
             {"Japan", JST},
             {"Kwajalein", MHT},
-            {"Libya", EET},
+            {"Libya", CET},
             {"MET", new String[] {"\u4e2d\u90e8\u30e8\u30fc\u30ed\u30c3\u30d1\u6642\u9593", "MET",
                                   "\u4e2d\u90e8\u30e8\u30fc\u30ed\u30c3\u30d1\u590f\u6642\u9593", "MEST"}},
             {"Mexico/BajaNorte", PST},
diff --git a/jdk/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java b/jdk/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java
index f449bf3..416a2c5 100644
--- a/jdk/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java
+++ b/jdk/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java
@@ -289,7 +289,7 @@
             {"Africa/Porto-Novo", WAT},
             {"Africa/Sao_Tome", GMT},
             {"Africa/Timbuktu", GMT},
-            {"Africa/Tripoli", EET},
+            {"Africa/Tripoli", CET},
             {"Africa/Tunis", CET},
             {"Africa/Windhoek", WAT},
             {"America/Adak", HAST},
@@ -535,6 +535,8 @@
             {"Asia/Kashgar", CTT},
             {"Asia/Kathmandu", NPT},
             {"Asia/Katmandu", NPT},
+            {"Asia/Khandyga", new String[] {"Khandyga Time", "YAKT",
+                                            "Khandyga Summer Time", "YAKST"}},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"\ud06c\ub77c\uc2a4\ub178\uc57c\ub974\uc2a4\ud06c \uc2dc\uac04", "KRAT",
                                                "\ud06c\ub77c\uc2a4\ub178\uc57c\ub974\uc2a4\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "KRAST"}},
@@ -583,6 +585,8 @@
             {"Asia/Ulaanbaatar", ULAT},
             {"Asia/Ulan_Bator", ULAT},
             {"Asia/Urumqi", CTT},
+            {"Asia/Ust-Nera", new String[] {"Ust-Nera Time", "VLAT",
+                                            "Ust-Nera Summer Time", "VLAST" }},
             {"Asia/Vientiane", ICT},
             {"Asia/Vladivostok", new String[] {"\ube14\ub77c\ub514\ubcf4\uc2a4\ud1a1 \uc2dc\uac04", "VLAT",
                                                "\ube14\ub77c\ub514\ubcf4\uc2a4\ud1a1 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "VLAST"}},
@@ -750,7 +754,7 @@
             {"Jamaica", EST},
             {"Japan", JST},
             {"Kwajalein", MHT},
-            {"Libya", EET},
+            {"Libya", CET},
             {"MET", new String[] {"\uc911\ubd80 \uc720\ub7fd \uc2dc\uac04", "MET",
                                   "\uc911\ubd80 \uc720\ub7fd \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MEST"}},
             {"Mexico/BajaNorte", PST},
diff --git a/jdk/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java b/jdk/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java
index 32d5783..124b8eb 100644
--- a/jdk/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java
+++ b/jdk/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java
@@ -289,7 +289,7 @@
             {"Africa/Porto-Novo", WAT},
             {"Africa/Sao_Tome", GMT},
             {"Africa/Timbuktu", GMT},
-            {"Africa/Tripoli", EET},
+            {"Africa/Tripoli", CET},
             {"Africa/Tunis", CET},
             {"Africa/Windhoek", WAT},
             {"America/Adak", HAST},
@@ -535,6 +535,8 @@
             {"Asia/Kashgar", CTT},
             {"Asia/Kathmandu", NPT},
             {"Asia/Katmandu", NPT},
+            {"Asia/Khandyga", new String[] {"Khandyga Time", "YAKT",
+                                            "Khandyga Summer Time", "YAKST"}},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"Fuso hor\u00e1rio de Krasnoyarsk", "KRAT",
                                                "Fuso hor\u00e1rio de ver\u00e3o de Krasnoyarsk", "KRAST"}},
@@ -583,6 +585,8 @@
             {"Asia/Ulaanbaatar", ULAT},
             {"Asia/Ulan_Bator", ULAT},
             {"Asia/Urumqi", CTT},
+            {"Asia/Ust-Nera", new String[] {"Ust-Nera Time", "VLAT",
+                                            "Ust-Nera Summer Time", "VLAST"}},
             {"Asia/Vientiane", ICT},
             {"Asia/Vladivostok", new String[] {"Fuso hor\u00e1rio de Vladivostok", "VLAT",
                                                "Fuso hor\u00e1rio de ver\u00e3o de Vladivostok", "VLAST"}},
@@ -750,7 +754,7 @@
             {"Jamaica", EST},
             {"Japan", JST},
             {"Kwajalein", MHT},
-            {"Libya", EET},
+            {"Libya", CET},
             {"MET", new String[] {"Fuso hor\u00e1rio da Europa M\u00e9dia", "MET",
                                   "Fuso hor\u00e1rio de ver\u00e3o da Europa M\u00e9dia", "MEST"}},
             {"Mexico/BajaNorte", PST},
diff --git a/jdk/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java b/jdk/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java
index 65b1979..0e54cea 100644
--- a/jdk/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java
+++ b/jdk/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java
@@ -289,7 +289,7 @@
             {"Africa/Porto-Novo", WAT},
             {"Africa/Sao_Tome", GMT},
             {"Africa/Timbuktu", GMT},
-            {"Africa/Tripoli", EET},
+            {"Africa/Tripoli", CET},
             {"Africa/Tunis", CET},
             {"Africa/Windhoek", WAT},
             {"America/Adak", HAST},
@@ -535,6 +535,8 @@
             {"Asia/Kashgar", CTT},
             {"Asia/Kathmandu", NPT},
             {"Asia/Katmandu", NPT},
+            {"Asia/Khandyga", new String[] {"Khandyga Time", "YAKT",
+                                            "Khandyga Summer Time", "YAKST"}},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"Krasnojarsk, normaltid", "KRAT",
                                                "Krasnojarsk, sommartid", "KRAST"}},
@@ -583,6 +585,8 @@
             {"Asia/Ulaanbaatar", ULAT},
             {"Asia/Ulan_Bator", ULAT},
             {"Asia/Urumqi", CTT},
+            {"Asia/Ust-Nera", new String[] {"Ust-Nera Time", "VLAT",
+                                            "Ust-Nera Summer Time", "VLAST"}},
             {"Asia/Vientiane", ICT},
             {"Asia/Vladivostok", new String[] {"Vladivostok, normaltid", "VLAT",
                                                "Vladivostok, sommartid", "VLAST"}},
@@ -750,7 +754,7 @@
             {"Jamaica", EST},
             {"Japan", JST},
             {"Kwajalein", MHT},
-            {"Libya", EET},
+            {"Libya", CET},
             {"MET", new String[] {"Mellaneuropeisk tid", "MET",
                                   "Mellaneuropeisk sommartid", "MEST"}},
             {"Mexico/BajaNorte", PST},
diff --git a/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java b/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java
index bd2333b..74777e3 100644
--- a/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java
+++ b/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java
@@ -289,7 +289,7 @@
             {"Africa/Porto-Novo", WAT},
             {"Africa/Sao_Tome", GMT},
             {"Africa/Timbuktu", GMT},
-            {"Africa/Tripoli", EET},
+            {"Africa/Tripoli", CET},
             {"Africa/Tunis", CET},
             {"Africa/Windhoek", WAT},
             {"America/Adak", HAST},
@@ -535,6 +535,8 @@
             {"Asia/Kashgar", CTT},
             {"Asia/Kathmandu", NPT},
             {"Asia/Katmandu", NPT},
+            {"Asia/Khandyga", new String[] {"Khandyga Time", "YAKT",
+                                            "Khandyga Summer Time", "YAKST"}},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"\u514b\u62c9\u65af\u8bfa\u4e9a\u5c14\u65af\u514b\u65f6\u95f4", "KRAT",
                                                "\u514b\u62c9\u65af\u8bfa\u4e9a\u5c14\u65af\u514b\u590f\u4ee4\u65f6", "KRAST"}},
@@ -583,6 +585,8 @@
             {"Asia/Ulaanbaatar", ULAT},
             {"Asia/Ulan_Bator", ULAT},
             {"Asia/Urumqi", CTT},
+            {"Asia/Ust-Nera", new String[] {"Ust-Nera Time", "VLAT",
+                                            "Ust-Nera Summer Time", "VLAST"}},
             {"Asia/Vientiane", ICT},
             {"Asia/Vladivostok", new String[] {"\u6d77\u53c2\u5d34\u65f6\u95f4", "VLAT",
                                                "\u6d77\u53c2\u5d34\u590f\u4ee4\u65f6", "VLAST"}},
@@ -750,7 +754,7 @@
             {"Jamaica", EST},
             {"Japan", JST},
             {"Kwajalein", MHT},
-            {"Libya", EET},
+            {"Libya", CET},
             {"MET", new String[] {"\u4e2d\u6b27\u65f6\u95f4", "MET",
                                   "\u4e2d\u6b27\u590f\u4ee4\u65f6", "MEST"}},
             {"Mexico/BajaNorte", PST},
diff --git a/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java b/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java
index 62b1a60..66de2c3 100644
--- a/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java
+++ b/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java
@@ -289,7 +289,7 @@
             {"Africa/Porto-Novo", WAT},
             {"Africa/Sao_Tome", GMT},
             {"Africa/Timbuktu", GMT},
-            {"Africa/Tripoli", EET},
+            {"Africa/Tripoli", CET},
             {"Africa/Tunis", CET},
             {"Africa/Windhoek", WAT},
             {"America/Adak", HAST},
@@ -535,6 +535,8 @@
             {"Asia/Kashgar", CTT},
             {"Asia/Kathmandu", NPT},
             {"Asia/Katmandu", NPT},
+            {"Asia/Khandyga", new String[] {"Khandyga Time", "YAKT",
+                                            "Khandyga Summer Time", "YAKST"}},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"\u514b\u62c9\u65af\u8afe\u4e9e\u723e\u65af\u514b\u6642\u9593", "KRAT",
                                                "\u514b\u62c9\u65af\u8afe\u4e9e\u723e\u65af\u514b\u590f\u4ee4\u6642\u9593", "KRAST"}},
@@ -584,6 +586,8 @@
             {"Asia/Ulaanbaatar", ULAT},
             {"Asia/Ulan_Bator", ULAT},
             {"Asia/Urumqi", CTT},
+            {"Asia/Ust-Nera", new String[] {"Ust-Nera Time", "VLAT",
+                                            "Ust-Nera Summer Time", "VLAST"}},
             {"Asia/Vientiane", ICT},
             {"Asia/Vladivostok", new String[] {"\u6d77\u53c3\u5d34\u6642\u9593", "VLAT",
                                                "\u6d77\u53c3\u5d34\u590f\u4ee4\u6642\u9593", "VLAST"}},
@@ -751,7 +755,7 @@
             {"Jamaica", EST},
             {"Japan", JST},
             {"Kwajalein", MHT},
-            {"Libya", EET},
+            {"Libya", CET},
             {"MET", new String[] {"\u4e2d\u6b50\u6642\u9593", "MET",
                                   "\u4e2d\u6b50\u590f\u4ee4\u6642\u9593", "MEST"}},
             {"Mexico/BajaNorte", PST},
diff --git a/jdk/src/share/native/com/sun/java/util/jar/pack/constants.h b/jdk/src/share/native/com/sun/java/util/jar/pack/constants.h
index 2f125e0..f1a1f73 100644
--- a/jdk/src/share/native/com/sun/java/util/jar/pack/constants.h
+++ b/jdk/src/share/native/com/sun/java/util/jar/pack/constants.h
@@ -133,6 +133,8 @@
     X_ATTR_Deprecated                  = 20,
     X_ATTR_RuntimeVisibleAnnotations   = 21,
     X_ATTR_RuntimeInvisibleAnnotations = 22,
+    X_ATTR_RuntimeVisibleTypeAnnotations   = 27,
+    X_ATTR_RuntimeInvisibleTypeAnnotations = 28,
     X_ATTR_OVERFLOW                    = 16,
     X_ATTR_LIMIT_NO_FLAGS_HI           = 32,
     X_ATTR_LIMIT_FLAGS_HI              = 63,
@@ -146,6 +148,8 @@
         F(X_ATTR_Deprecated,Deprecated) \
         F(X_ATTR_RuntimeVisibleAnnotations,RuntimeVisibleAnnotations) \
         F(X_ATTR_RuntimeInvisibleAnnotations,RuntimeInvisibleAnnotations) \
+        F(X_ATTR_RuntimeVisibleTypeAnnotations,RuntimeVisibleTypeAnnotations) \
+        F(X_ATTR_RuntimeInvisibleTypeAnnotations,RuntimeInvisibleTypeAnnotations) \
         /*F(X_ATTR_Synthetic,Synthetic)*/ \
           /*(end)*/
 #define CLASS_ATTR_DO(F) \
diff --git a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp
index 44ea898..f3dd2cc 100644
--- a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp
+++ b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp
@@ -1791,7 +1791,7 @@
     switch (*lp++) {
     case 'B': case 'H': case 'I': case 'V': // unsigned_int
     case 'S': // signed_int
-      --lp;  // reparse
+      --lp; // reparse
     case 'F':
       lp = parseIntLayout(lp, b, EK_INT);
       break;
@@ -2037,47 +2037,80 @@
     MDL0
     // annotations:
 #define MDL1 \
-    "[NH[(1)]]" \
-    "[RSHNH[RUH(1)]]"
+    "[NH[(1)]]"
     MDL1
-    // member_value:
-    "[TB"
-      "(66,67,73,83,90)[KIH]"
-      "(68)[KDH]"
-      "(70)[KFH]"
-      "(74)[KJH]"
-      "(99)[RSH]"
-      "(101)[RSHRUH]"
-      "(115)[RUH]"
-      "(91)[NH[(0)]]"
-      "(64)["
-        // nested annotation:
-        "RSH"
-        "NH[RUH(0)]"
-        "]"
-      "()[]"
+#define MDL2 \
+    "[RSHNH[RUH(1)]]"
+    MDL2
+    // element_value:
+#define MDL3 \
+    "[TB"                        \
+      "(66,67,73,83,90)[KIH]"    \
+      "(68)[KDH]"                \
+      "(70)[KFH]"                \
+      "(74)[KJH]"                \
+      "(99)[RSH]"                \
+      "(101)[RSHRUH]"            \
+      "(115)[RUH]"               \
+      "(91)[NH[(0)]]"            \
+      "(64)["                    \
+        /* nested annotation: */ \
+        "RSH"                    \
+        "NH[RUH(0)]"             \
+        "]"                      \
+      "()[]"                     \
     "]"
+    MDL3
     );
 
   const char* md_layout_P = md_layout;
   const char* md_layout_A = md_layout+strlen(MDL0);
-  const char* md_layout_V = md_layout+strlen(MDL0 MDL1);
+  const char* md_layout_V = md_layout+strlen(MDL0 MDL1 MDL2);
   assert(0 == strncmp(&md_layout_A[-3], ")]][", 4));
   assert(0 == strncmp(&md_layout_V[-3], ")]][", 4));
 
+const char* type_md_layout(
+    "[NH[(1)(2)(3)]]"
+    // target-type + target_info
+    "[TB"
+       "(0,1)[B]"
+       "(16)[FH]"
+       "(17,18)[BB]"
+       "(19,20,21)[]"
+       "(22)[B]"
+       "(23)[H]"
+       "(64,65)[NH[PHOHH]]"
+       "(66)[H]"
+       "(67,68,69,70)[PH]"
+       "(71,72,73,74,75)[PHB]"
+       "()[]]"
+    // target-path
+    "[NB[BB]]"
+    // annotation + element_value
+    MDL2
+    MDL3
+);
+
   for (i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
     attr_definitions& ad = attr_defs[i];
-    ad.defineLayout(X_ATTR_RuntimeVisibleAnnotations,
-                    "RuntimeVisibleAnnotations", md_layout_A);
-    ad.defineLayout(X_ATTR_RuntimeInvisibleAnnotations,
-                    "RuntimeInvisibleAnnotations", md_layout_A);
-    if (i != ATTR_CONTEXT_METHOD)  continue;
-    ad.defineLayout(METHOD_ATTR_RuntimeVisibleParameterAnnotations,
-                    "RuntimeVisibleParameterAnnotations", md_layout_P);
-    ad.defineLayout(METHOD_ATTR_RuntimeInvisibleParameterAnnotations,
-                    "RuntimeInvisibleParameterAnnotations", md_layout_P);
-    ad.defineLayout(METHOD_ATTR_AnnotationDefault,
-                    "AnnotationDefault", md_layout_V);
+    if (i != ATTR_CONTEXT_CODE) {
+      ad.defineLayout(X_ATTR_RuntimeVisibleAnnotations,
+                      "RuntimeVisibleAnnotations", md_layout_A);
+      ad.defineLayout(X_ATTR_RuntimeInvisibleAnnotations,
+                      "RuntimeInvisibleAnnotations", md_layout_A);
+      if (i == ATTR_CONTEXT_METHOD) {
+        ad.defineLayout(METHOD_ATTR_RuntimeVisibleParameterAnnotations,
+                        "RuntimeVisibleParameterAnnotations", md_layout_P);
+        ad.defineLayout(METHOD_ATTR_RuntimeInvisibleParameterAnnotations,
+                        "RuntimeInvisibleParameterAnnotations", md_layout_P);
+        ad.defineLayout(METHOD_ATTR_AnnotationDefault,
+                        "AnnotationDefault", md_layout_V);
+      }
+    }
+    ad.defineLayout(X_ATTR_RuntimeVisibleTypeAnnotations,
+                    "RuntimeVisibleTypeAnnotations", type_md_layout);
+    ad.defineLayout(X_ATTR_RuntimeInvisibleTypeAnnotations,
+                    "RuntimeInvisibleTypeAnnotations", type_md_layout);
   }
 
   attr_definition_headers.readData(attr_definition_count);
@@ -2433,6 +2466,7 @@
 
     ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
     ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
+    CHECK;
 
     count = ad.predefCount(CLASS_ATTR_InnerClasses);
     class_InnerClasses_N.readData(count);
@@ -2452,6 +2486,10 @@
     class_ClassFile_version_minor_H.readData(count);
     class_ClassFile_version_major_H.readData(count);
     CHECK;
+
+    ad.readBandData(X_ATTR_RuntimeVisibleTypeAnnotations);
+    ad.readBandData(X_ATTR_RuntimeInvisibleTypeAnnotations);
+    CHECK;
     break;
 
   case ATTR_CONTEXT_FIELD:
@@ -2467,6 +2505,10 @@
     ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
     ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
     CHECK;
+
+    ad.readBandData(X_ATTR_RuntimeVisibleTypeAnnotations);
+    ad.readBandData(X_ATTR_RuntimeInvisibleTypeAnnotations);
+    CHECK;
     break;
 
   case ATTR_CONTEXT_METHOD:
@@ -2497,6 +2539,11 @@
     method_MethodParameters_name_RUN.readData(count);
     method_MethodParameters_flag_FH.readData(count);
     CHECK;
+
+    ad.readBandData(X_ATTR_RuntimeVisibleTypeAnnotations);
+    ad.readBandData(X_ATTR_RuntimeInvisibleTypeAnnotations);
+    CHECK;
+
     break;
 
   case ATTR_CONTEXT_CODE:
@@ -2566,18 +2613,22 @@
 
     count = ad.predefCount(CODE_ATTR_LineNumberTable);
     code_LineNumberTable_N.readData(count);
+    CHECK;
     count = code_LineNumberTable_N.getIntTotal();
     code_LineNumberTable_bci_P.readData(count);
     code_LineNumberTable_line.readData(count);
+    CHECK;
 
     count = ad.predefCount(CODE_ATTR_LocalVariableTable);
     code_LocalVariableTable_N.readData(count);
+    CHECK;
     count = code_LocalVariableTable_N.getIntTotal();
     code_LocalVariableTable_bci_P.readData(count);
     code_LocalVariableTable_span_O.readData(count);
     code_LocalVariableTable_name_RU.readData(count);
     code_LocalVariableTable_type_RS.readData(count);
     code_LocalVariableTable_slot.readData(count);
+    CHECK;
 
     count = ad.predefCount(CODE_ATTR_LocalVariableTypeTable);
     code_LocalVariableTypeTable_N.readData(count);
@@ -2587,6 +2638,12 @@
     code_LocalVariableTypeTable_name_RU.readData(count);
     code_LocalVariableTypeTable_type_RS.readData(count);
     code_LocalVariableTypeTable_slot.readData(count);
+    CHECK;
+
+    ad.readBandData(X_ATTR_RuntimeVisibleTypeAnnotations);
+    ad.readBandData(X_ATTR_RuntimeInvisibleTypeAnnotations);
+    CHECK;
+
     break;
   }
 
@@ -5151,7 +5208,7 @@
 
 #ifndef PRODUCT
 int unpacker::printcr_if_verbose(int level, const char* fmt ...) {
-  if (verbose < level+10)  return 0;
+  if (verbose < level)  return 0;
   va_list vl;
   va_start(vl, fmt);
   char fmtbuf[300];
diff --git a/jdk/src/share/native/sun/security/jgss/wrapper/gssapi.h b/jdk/src/share/native/sun/security/jgss/wrapper/gssapi.h
index 50db92c..38440fb 100644
--- a/jdk/src/share/native/sun/security/jgss/wrapper/gssapi.h
+++ b/jdk/src/share/native/sun/security/jgss/wrapper/gssapi.h
@@ -32,10 +32,21 @@
 #ifndef _GSSAPI_H_
 #define _GSSAPI_H_
 
+#if defined(__MACH__) && defined(__APPLE__)
+#       include <TargetConditionals.h>
+#       if TARGET_RT_MAC_CFM
+#               error "Use KfM 4.0 SDK headers for CFM compilation."
+#       endif
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
 
+#if TARGET_OS_MAC
+#    pragma pack(push,2)
+#endif
+
 /*
  * First, include stddef.h to get size_t defined.
  */
@@ -671,6 +682,10 @@
         gss_name_t *            /* output_name */
 );
 
+#if TARGET_OS_MAC
+#    pragma pack(pop)
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/jdk/src/share/sample/scripting/scriptpad/src/com/sun/sample/scriptpad/Main.java b/jdk/src/share/sample/scripting/scriptpad/src/com/sun/sample/scriptpad/Main.java
index e720687..aaeb58d 100644
--- a/jdk/src/share/sample/scripting/scriptpad/src/com/sun/sample/scriptpad/Main.java
+++ b/jdk/src/share/sample/scripting/scriptpad/src/com/sun/sample/scriptpad/Main.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -75,7 +75,7 @@
          */
         InputStream is = Main.class.getResourceAsStream("/resources/" + name);
         // current script file name for better error messages
-        engine.put(ScriptEngine.NAME, name);
+        engine.put(ScriptEngine.FILENAME, name);
         // evaluate the script in the InputStream
         engine.eval(new InputStreamReader(is));
     }
diff --git a/jdk/src/share/sample/scripting/scriptpad/src/resources/Main.js b/jdk/src/share/sample/scripting/scriptpad/src/resources/Main.js
index 9d1e5fe..a1c332d 100644
--- a/jdk/src/share/sample/scripting/scriptpad/src/resources/Main.js
+++ b/jdk/src/share/sample/scripting/scriptpad/src/resources/Main.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,7 +37,6 @@
  * this sample code.
  */
 
-
 /*
  * This script can be loaded in jrunscript to start scriptpad.
  *
@@ -48,4 +47,3 @@
 load("gui.js");
 load("scriptpad.js");
 load("mm.js");
-
diff --git a/jdk/src/share/sample/scripting/scriptpad/src/resources/conc.js b/jdk/src/share/sample/scripting/scriptpad/src/resources/conc.js
index 1618b1d..7e56fad 100644
--- a/jdk/src/share/sample/scripting/scriptpad/src/resources/conc.js
+++ b/jdk/src/share/sample/scripting/scriptpad/src/resources/conc.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,15 +37,43 @@
  * this sample code.
  */
 
-
 /*
  * Concurrency utilities for JavaScript. These are based on
- * java.lang and java.util.concurrent API. The following functions 
+ * java.lang and java.util.concurrent API. The following functions
  * provide a simpler API for scripts. Instead of directly using java.lang
  * and java.util.concurrent classes, scripts can use functions and
- * objects exported from here. 
+ * objects exported from here.
  */
 
+// shortcut for j.u.c lock classes
+var Lock = java.util.concurrent.locks.ReentrantLock;
+var RWLock = java.util.concurrent.locks.ReentrantReadWriteLock;
+
+// check if there is a build in sync function, define one if missing
+if (typeof sync === "undefined") {
+    var sync = function(func, obj) {
+        if (arguments.length < 1 || arguments.length > 2 ) {
+            throw "sync(function [,object]) parameter count mismatch";
+        }
+
+        var syncobj = (arguments.length == 2 ? obj : this);
+
+        if (!syncobj._syncLock) {
+            syncobj._syncLock = new Lock();
+        }
+
+        return function() {
+            syncobj._syncLock.lock();
+            try {
+                func.apply(null, arguments);
+            } finally {
+                syncobj._syncLock.unlock();
+            }
+        };
+    };
+    sync.docString = "synchronize a function, optionally on an object";
+}
+
 /**
  * Wrapper for java.lang.Object.wait
  *
@@ -58,7 +86,6 @@
 }
 wait.docString = "convenient wrapper for java.lang.Object.wait method";
 
-
 /**
  * Wrapper for java.lang.Object.notify
  *
@@ -71,7 +98,6 @@
 }
 notify.docString = "convenient wrapper for java.lang.Object.notify method";
 
-
 /**
  * Wrapper for java.lang.Object.notifyAll
  *
@@ -84,7 +110,6 @@
 }
 notifyAll.docString = "convenient wrapper for java.lang.Object.notifyAll method";
 
-
 /**
  * Creates a java.lang.Runnable from a given script
  * function.
@@ -97,7 +122,7 @@
             func.apply(null, args);
         }
     }
-}
+};
 
 /**
  * Executes the function on a new Java Thread.
@@ -106,7 +131,7 @@
     var t = new java.lang.Thread(this.runnable.apply(this, arguments));
     t.start();
     return t;
-}
+};
 
 /**
  * Executes the function on a new Java daemon Thread.
@@ -116,7 +141,7 @@
     t.setDaemon(true);
     t.start();
     return t;
-}
+};
 
 /**
  * Creates a java.util.concurrent.Callable from a given script
@@ -128,7 +153,7 @@
     return new java.util.concurrent.Callable() {
           call: function() { return func.apply(null, args); }
     }
-}
+};
 
 /**
  * Registers the script function so that it will be called exit.
@@ -137,10 +162,10 @@
     var args = arguments;
     java.lang.Runtime.getRuntime().addShutdownHook(
          new java.lang.Thread(this.runnable.apply(this, args)));
-}
+};
 
 /**
- * Executes the function asynchronously.  
+ * Executes the function asynchronously.
  *
  * @return a java.util.concurrent.FutureTask
  */
@@ -152,13 +177,9 @@
     (function() { theExecutor.shutdown(); }).atexit();
     return function() {
         return theExecutor.submit(this.callable.apply(this, arguments));
-    }
+    };
 })();
 
-// shortcut for j.u.c lock classes
-var Lock = java.util.concurrent.locks.ReentrantLock;
-var RWLock = java.util.concurrent.locks.ReentrantReadWriteLock;
-
 /**
  * Executes a function after acquiring given lock. On return,
  * (normal or exceptional), lock is released.
@@ -179,7 +200,7 @@
     } finally {
         lock.unlock();
     }
-}
+};
 
 /**
  * Causes current thread to sleep for specified
@@ -193,30 +214,29 @@
 sleep.docString = "wrapper for java.lang.Thread.sleep method";
 
 /**
- * Schedules a task to be executed once in
- * every N milliseconds specified. 
+ * Schedules a task to be executed once in N milliseconds specified.
  *
  * @param callback function or expression to evaluate
  * @param interval in milliseconds to sleep
  * @return timeout ID (which is nothing but Thread instance)
  */
 function setTimeout(callback, interval) {
-    if (! (callback instanceof Function)) {
+    if (! (callback instanceof Function) && typeof callback !== "function") {
         callback = new Function(callback);
     }
 
     // start a new thread that sleeps given time
     // and calls callback in an infinite loop
     return (function() {
-         while (true) {
+         try {
              sleep(interval);
-             callback();
-         }
+         } catch (x) { }
+         callback();
     }).daemon();
 }
-setTimeout.docString = "calls given callback once after specified interval"
+setTimeout.docString = "calls given callback once after specified interval";
 
-/** 
+/**
  * Cancels a timeout set earlier.
  * @param tid timeout ID returned from setTimeout
  */
@@ -224,23 +244,62 @@
     // we just interrupt the timer thread
     tid.interrupt();
 }
+clearTimeout.docString = "interrupt a setTimeout timer";
 
 /**
- * Simple access to thread local storage. 
+ * Schedules a task to be executed once in
+ * every N milliseconds specified.
+ *
+ * @param callback function or expression to evaluate
+ * @param interval in milliseconds to sleep
+ * @return timeout ID (which is nothing but Thread instance)
+ */
+function setInterval(callback, interval) {
+    if (! (callback instanceof Function) && typeof callback !== "function") {
+        callback = new Function(callback);
+    }
+
+    // start a new thread that sleeps given time
+    // and calls callback in an infinite loop
+    return (function() {
+         while (true) {
+             try {
+                 sleep(interval);
+             } catch (x) {
+                 break;
+             }
+             callback();
+         }
+    }).daemon();
+}
+setInterval.docString = "calls given callback every specified interval";
+
+/**
+ * Cancels a timeout set earlier.
+ * @param tid timeout ID returned from setTimeout
+ */
+function clearInterval(tid) {
+    // we just interrupt the timer thread
+    tid.interrupt();
+}
+clearInterval.docString = "interrupt a setInterval timer";
+
+/**
+ * Simple access to thread local storage.
  *
  * Script sample:
  *
  *  __thread.x = 44;
- *  function f() { 
- *      __thread.x = 'hello'; 
- *      print(__thread.x); 
+ *  function f() {
+ *      __thread.x = 'hello';
+ *      print(__thread.x);
  *  }
  *  f.thread();       // prints 'hello'
  * print(__thread.x); // prints 44 in main thread
  */
 var __thread = (function () {
     var map = new Object();
-    return new JSAdapter() {
+    return new JSAdapter({
         __has__: function(name) {
             return map[name] != undefined;
         },
@@ -263,8 +322,8 @@
         __delete__: function(name) {
             if (map[name] != undefined) {
                 map[name].set(null);
-            }            
+            }
         }
-    }
+    });
 })();
 
diff --git a/jdk/src/share/sample/scripting/scriptpad/src/resources/gui.js b/jdk/src/share/sample/scripting/scriptpad/src/resources/gui.js
index 950f64c0..7882d2a 100644
--- a/jdk/src/share/sample/scripting/scriptpad/src/resources/gui.js
+++ b/jdk/src/share/sample/scripting/scriptpad/src/resources/gui.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,16 +37,15 @@
  * this sample code.
  */
 
-
 /*
- * Few user interface utilities. 
+ * Few user interface utilities.
  */
 
 if (this.window === undefined) {
     this.window = null;
 }
 
-/** 
+/**
  * Swing invokeLater - invokes given function in AWT event thread
  */
 Function.prototype.invokeLater = function() {
@@ -54,13 +53,13 @@
     var func = this;
     var args = arguments;
     SwingUtilities.invokeLater(new java.lang.Runnable() {
-                       run: function() { 
+                       run: function() {
                            func.apply(func, args);
                        }
                   });
-}
+};
 
-/** 
+/**
  * Swing invokeAndWait - invokes given function in AWT event thread
  * and waits for it's completion
  */
@@ -69,11 +68,11 @@
     var func = this;
     var args = arguments;
     SwingUtilities.invokeAndWait(new java.lang.Runnable() {
-                       run: function() { 
+                       run: function() {
                            func.apply(func, args);
                        }
                   });
-}
+};
 
 /**
  * Am I running in AWT event dispatcher thread?
@@ -85,22 +84,24 @@
 isEventThread.docString = "returns whether the current thread is GUI thread";
 
 /**
- * Opens a file dialog box 
+ * Opens a file dialog box
  *
  * @param curDir current directory [optional]
  * @param save flag tells whether this is a save dialog or not
  * @return selected file or else null
  */
-function fileDialog(curDir, save) {   
+function fileDialog(curDir, save) {
     var result;
     function _fileDialog() {
         if (curDir == undefined) {
             curDir = new java.io.File(".");
         }
+
         var JFileChooser = javax.swing.JFileChooser;
-        var dialog = new JFileChooser(curDir);        
-        var res = save? dialog.showSaveDialog(window):
-                        dialog.showOpenDialog(window);
+        var dialog = new JFileChooser(curDir);
+        var res = save ? dialog.showSaveDialog(window):
+            dialog.showOpenDialog(window);
+
         if (res == JFileChooser.APPROVE_OPTION) {
            result = dialog.getSelectedFile();
         } else {
@@ -113,37 +114,41 @@
     } else {
         _fileDialog.invokeAndWait();
     }
+
     return result;
 }
 fileDialog.docString = "show a file dialog box";
 
 /**
- * Opens a color chooser dialog box 
+ * Opens a color chooser dialog box
  *
  * @param title of the dialog box [optional]
  * @param color default color [optional]
  * @return choosen color or default color
  */
-
 function colorDialog(title, color) {
     var result;
+
     function _colorDialog() {
         if (title == undefined) {
             title = "Choose Color";
         }
+
         if (color == undefined) {
             color = java.awt.Color.BLACK;
         }
+
         var chooser = new javax.swing.JColorChooser();
         var res = chooser.showDialog(window, title, color);
-        result = res? res : color;
-    }     
+        result = res ? res : color;
+    }
 
     if (isEventThread()) {
         _colorDialog();
     } else {
         _colorDialog.invokeAndWait();
     }
+
     return result;
 }
 colorDialog.docString = "shows a color chooser dialog box";
@@ -156,15 +161,15 @@
  * @param msgType type of message box [constants in JOptionPane]
  */
 function msgBox(msg, title, msgType) {
-   
-    function _msgBox() { 
+    function _msgBox() {
         var JOptionPane = javax.swing.JOptionPane;
         if (msg === undefined) msg = "undefined";
         if (msg === null) msg = "null";
         if (title == undefined) title = msg;
-        if (msgType == undefined) type = JOptionPane.INFORMATION_MESSAGE;
+        if (msgType == undefined) msgType = JOptionPane.INFORMATION_MESSAGE;
         JOptionPane.showMessageDialog(window, msg, title, msgType);
     }
+
     if (isEventThread()) {
         _msgBox();
     } else {
@@ -172,13 +177,13 @@
     }
 }
 msgBox.docString = "shows MessageBox to the user";
- 
+
 /**
  * Shows an information alert box
  *
  * @param msg message to be shown
  * @param title title of message box [optional]
- */   
+ */
 function alert(msg, title) {
     var JOptionPane = javax.swing.JOptionPane;
     msgBox(msg, title, JOptionPane.INFORMATION_MESSAGE);
@@ -197,7 +202,6 @@
 }
 error.docString = "shows an error message box to the user";
 
-
 /**
  * Shows a warning alert box
  *
@@ -210,7 +214,6 @@
 }
 warn.docString = "shows a warning message box to the user";
 
-
 /**
  * Shows a prompt dialog box
  *
@@ -225,11 +228,13 @@
         if (answer == undefined) answer = "";
         result = JOptionPane.showInputDialog(window, question, answer);
     }
+
     if (isEventThread()) {
         _prompt();
     } else {
         _prompt.invokeAndWait();
     }
+
     return result;
 }
 prompt.docString = "shows a prompt box to the user and returns the answer";
@@ -244,30 +249,33 @@
 function confirm(msg, title) {
     var result;
     var JOptionPane = javax.swing.JOptionPane;
+
     function _confirm() {
         if (title == undefined) title = msg;
         var optionType = JOptionPane.YES_NO_OPTION;
         result = JOptionPane.showConfirmDialog(window, msg, title, optionType);
     }
+
     if (isEventThread()) {
         _confirm();
     } else {
         _confirm.invokeAndWait();
-    }     
+    }
+
     return result == JOptionPane.YES_OPTION;
 }
 confirm.docString = "shows a confirmation message box to the user";
 
 /**
- * Exit the process after confirmation from user 
- * 
+ * Exit the process after confirmation from user
+ *
  * @param exitCode return code to OS [optional]
  */
 function exit(exitCode) {
     if (exitCode == undefined) exitCode = 0;
     if (confirm("Do you really want to exit?")) {
         java.lang.System.exit(exitCode);
-    } 
+    }
 }
 exit.docString = "exits jconsole";
 
diff --git a/jdk/src/share/sample/scripting/scriptpad/src/resources/mm.js b/jdk/src/share/sample/scripting/scriptpad/src/resources/mm.js
index 1e6d230..2b75f24 100644
--- a/jdk/src/share/sample/scripting/scriptpad/src/resources/mm.js
+++ b/jdk/src/share/sample/scripting/scriptpad/src/resources/mm.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,10 +37,9 @@
  * this sample code.
  */
 
-
 /*
  * This is a collection of utilities for Monitoring
- * and management API. 
+ * and management API.
  *
  * File dependency:
  *    conc.js -> for concurrency utilities
@@ -71,14 +70,14 @@
 }
 jmxConnect.docString = "connects to the given host, port (specified as name:port)";
 
-function mbeanConnection() {    
-    if (mmConnection == null) {        
+function mbeanConnection() {
+    if (mmConnection == null) {
         throw "Not connected to MBeanServer yet!";
     }
 
     return mmConnection;
 }
-mbeanConnection.docString = "returns the current MBeanServer connection"
+mbeanConnection.docString = "returns the current MBeanServer connection";
 
 /**
  * Returns a platform MXBean proxy for given MXBean name and interface class
@@ -102,7 +101,6 @@
 }
 objectName.docString = "creates JMX ObjectName for a given String";
 
-
 /**
  * Creates a new (M&M) Attribute object
  *
@@ -146,7 +144,6 @@
 }
 queryNames.docString = "returns QueryNames using given ObjectName and optional query";
 
-
 /**
  * Queries with given ObjectName and QueryExp.
  * QueryExp may be null.
@@ -220,7 +217,6 @@
 }
 getMBeanAttribute.docString = "returns a single Attribute of given ObjectName";
 
-
 // sets MBean attributes
 function setMBeanAttributes(objName, attrList) {
     objName = objectName(objName);
@@ -237,7 +233,6 @@
 }
 setMBeanAttribute.docString = "sets a single Attribute of given ObjectName";
 
-
 // invokes an operation on given MBean
 function invokeMBean(objName, operation, params, signature) {
     objName = objectName(objName);
@@ -260,16 +255,17 @@
  * will be of type FutureTask. When you need value, call 'get' on it.
  */
 function mbean(objName, async) {
+    var index;
     objName = objectName(objName);
-    var info = mbeanInfo(objName);    
+    var info = mbeanInfo(objName);
     var attrs = info.attributes;
     var attrMap = new Object;
-    for (var index in attrs) {
+    for (index in attrs) {
         attrMap[attrs[index].name] = attrs[index];
     }
     var opers = info.operations;
     var operMap = new Object;
-    for (var index in opers) {
+    for (index in opers) {
         operMap[opers[index].name] = opers[index];
     }
 
@@ -288,9 +284,9 @@
         __get__: function (name) {
             if (isAttribute(name)) {
                 if (async) {
-                    return getMBeanAttribute.future(objName, name); 
+                    return getMBeanAttribute.future(objName, name);
                 } else {
-                    return getMBeanAttribute(objName, name); 
+                    return getMBeanAttribute(objName, name);
                 }
             } else if (isOperation(name)) {
                 var oper = operMap[name];
@@ -302,12 +298,12 @@
                         sigNames[index] = sigs[index].getType();
                     }
                     if (async) {
-                        return invokeMBean.future(objName, name, 
+                        return invokeMBean.future(objName, name,
                                                   params, sigNames);
                     } else {
                         return invokeMBean(objName, name, params, sigNames);
                     }
-                }
+                };
             } else {
                 return undefined;
             }
@@ -327,9 +323,9 @@
 }
 mbean.docString = "returns a conveninent script wrapper for a MBean of given ObjectName";
 
-if (this.application != undefined) {    
-    this.application.addTool("JMX Connect", 
-        // connect to a JMX MBean Server 
+if (this.application != undefined) {
+    this.application.addTool("JMX Connect",
+        // connect to a JMX MBean Server
         function () {
             var url = prompt("Connect to JMX server (host:port)");
             if (url != null) {
diff --git a/jdk/src/share/sample/scripting/scriptpad/src/resources/scriptpad.js b/jdk/src/share/sample/scripting/scriptpad/src/resources/scriptpad.js
index 4350704..807d05e 100644
--- a/jdk/src/share/sample/scripting/scriptpad/src/resources/scriptpad.js
+++ b/jdk/src/share/sample/scripting/scriptpad/src/resources/scriptpad.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,9 +37,8 @@
  * this sample code.
  */
 
-
 /*
- * This script creates a simple Notepad-like interface, which 
+ * This script creates a simple Notepad-like interface, which
  * serves as a simple script editor, runner.
  *
  * File dependency:
@@ -48,579 +47,583 @@
  */
 
 /*
+ * globalThis is used for actionHelpGlobals() and showFrame().
+ */
+var globalThis = this;
+
+/*
  * JavaImporter helps in avoiding pollution of JavaScript
  * global namespace. We can import multiple Java packages
  * with this and use the JavaImporter object with "with"
  * statement.
  */
 var guiPkgs = new JavaImporter(java.awt, java.awt.event,
-                         javax.swing, javax.swing.undo,
-                         javax.swing.event, javax.swing.text);
+                               javax.swing, javax.swing.undo,
+                               javax.swing.event, javax.swing.text);
 
-with (guiPkgs) {   
-
-     /*
-      * within this "with" statement all Java classes in
-      * packages defined in "guiPkgs" can be used as simple
-      * names instead of the fully qualified names.
-      */
-
-
-     // main entry point of the scriptpad application
-     function main() {
-        function createEditor() {
-            var c = new JTextArea();
-            c.setDragEnabled(true);
-            c.setFont(new Font("monospaced", Font.PLAIN, 12));
-            return c;
-        }
-
-        /*const*/ var titleSuffix = "- Scriptpad";
-        /*const*/ var defaultTitle = "Untitled" + titleSuffix;
-
-        // Scriptpad's main frame
-        var frame;
-        // Scriptpad's main editor
-        var editor;
-
-        // To track the current file name
-        var curFileName = null;
-
-        // To track whether the current document 
-        // has been modified or not
-        var docChanged = false;
-
-        // check and alert user for unsaved
-        // but modified document        
-        function checkDocChanged() {
-            if (docChanged) {
-                // ignore zero-content untitled document
-                if (curFileName == null &&
-                    editor.document.length == 0) {
-                    return;
-                }
-
-                if (confirm(
-                    "Do you want to save the changes?",
-                    "The document has changed")) {
-                    actionSave();
-                }
-            }
-        }
-
-        // set a document listener to track 
-        // whether that is modified or not
-        function setDocListener() {
-            var doc = editor.getDocument();
-            docChanged = false;
-            doc.addDocumentListener(new DocumentListener() {
-                    equals: function(o) { return this === o; },
-                    toString: function() { return "doc listener"; },
-                    changeUpdate: function() { docChanged = true; },
-                    insertUpdate: function() { docChanged = true; },
-                    removeUpdate: function() { docChanged = true; },
-                });
-        }
-
-        // menu action functions
-
-        // "File" menu 
-
-        // create a "new" document
-        function actionNew(){
-            checkDocChanged();
-            curFileName = null;
-            editor.setDocument(new PlainDocument());
-            setDocListener();
-            frame.setTitle(defaultTitle);
-            editor.revalidate();
-        }
-
-        // open an existing file
-        function actionOpen() {
-            checkDocChanged();
-            var f = fileDialog();
-            if (f == null) {
-                return;
-            }
-            if (f.isFile() && f.canRead()) {                
-                frame.setTitle(f.getName() + titleSuffix);
-                editor.setDocument(new PlainDocument());
-                var progress = new JProgressBar();
-                progress.setMinimum(0);
-                progress.setMaximum(f.length());
-                var doc = editor.getDocument();
-                var inp = new java.io.FileReader(f);
-                var buff = java.lang.reflect.Array.newInstance(
-                                java.lang.Character.TYPE, 4096);
-                var nch;
-                while ((nch = inp.read(buff, 0, buff.length)) != -1) {
-                    doc.insertString(doc.getLength(),
-                         new java.lang.String(buff, 0, nch), null);
-                    progress.setValue(progress.getValue() + nch);
-                }
-                inp.close();
-                curFileName = f.getAbsolutePath();
-                setDocListener();
-             } else {
-                error("Can not open file: " + f,
-                    "Error opening file: " + f);                    
-             }               
-        }
-
-        // open script from a URL
-        function actionOpenURL() {
-            checkDocChanged();
-            var url = prompt("Address:");
-            if (url == null) {
-                return;
-            }
-
-            try {
-                var u = new java.net.URL(url); 
-                editor.setDocument(new PlainDocument());
-                frame.setTitle(url + titleSuffix);
-                var progress = new JProgressBar();
-                progress.setMinimum(0);
-                progress.setIndeterminate(true);
-                var doc = editor.getDocument();
-                var inp = new java.io.InputStreamReader(u.openStream());
-                var buff = java.lang.reflect.Array.newInstance(
-                                java.lang.Character.TYPE, 4096);
-                var nch;
-                while ((nch = inp.read(buff, 0, buff.length)) != -1) {
-                    doc.insertString(doc.getLength(), 
-                          new java.lang.String(buff, 0, nch), null);
-                    progress.setValue(progress.getValue() + nch);
-                }    
-                curFileName = null;
-                setDocListener();
-            } catch (e) {
-                error("Error opening URL: " + e,
-                      "Can not open URL: " + url);
-            }   
-        } 
-
-        // factored out "save" function used by 
-        // save, save as menu actions
-        function save(file) {
-            var doc = editor.getDocument();
-            frame.setTitle(file.getName() + titleSuffix);
-            curFileName = file;
-            var progress = new JProgressBar();
-            progress.setMinimum(0);
-            progress.setMaximum(file.length());            
-            var out = new java.io.FileWriter(file);
-            var text = new Segment();
-            text.setPartialReturn(true);
-            var charsLeft = doc.getLength();
-            var offset = 0;
-            while (charsLeft > 0) {
-                doc.getText(offset, java.lang.Math.min(4096, charsLeft), text);
-                out.write(text.array, text.offset, text.count);
-                charsLeft -= text.count;
-                offset += text.count;
-                progress.setValue(offset);
-                java.lang.Thread.sleep(10);               
-            }
-            out.flush();
-            out.close();           
-            docChanged = false;           
-        }
-
-        // file-save as menu
-        function actionSaveAs() {
-            var ret = fileDialog(null, true);
-            if (ret == null) {
-                return;
-            }
-            save(ret);
-        }
-
-        // file-save menu
-        function actionSave() {            
-            if (curFileName) {
-                save(new java.io.File(curFileName));
-            } else {
-                actionSaveAs();
-            }
-        }
-
-        // exit from scriptpad
-        function actionExit() {
-            checkDocChanged();           
-            java.lang.System.exit(0);
-        }
-
-        // "Edit" menu 
-
-        // cut the currently selected text
-        function actionCut() {
-            editor.cut();
-        }
-
-        // copy the currently selected text to clipboard
-        function actionCopy() {
-            editor.copy();
-        }
-
-        // paste clipboard content to document
-        function actionPaste() {
-            editor.paste();
-        }
-
-        // select all the text in editor
-        function actionSelectAll() {
-            editor.selectAll();
-        }
-
-        // "Tools" menu 
-
-        // run the current document as JavaScript
-        function actionRun() {
-            var doc = editor.getDocument();
-            var script = doc.getText(0, doc.getLength());
-            var oldFile = engine.get(javax.script.ScriptEngine.FILENAME);
-            try {
-                if (this.engine == undefined) {
-                    var m = new javax.script.ScriptEngineManager();
-                    engine = m.getEngineByName("js");
-                }
-                engine.put(javax.script.ScriptEngine.FILENAME, frame.title);
-                engine.eval(script, context);
-            } catch (e) {  
-                error(e, "Script Error");
-                // e.rhinoException.printStackTrace();
-            } finally {
-                engine.put(javax.script.ScriptEngine.FILENAME, oldFile);
-            }
-        }
-
-        // "Examples" menu 
-
-        // show given script as new document
-        function showScript(title, str) { 
-            actionNew();
-            frame.setTitle("Example - " + title + titleSuffix);
-            var doc = editor.document;
-            doc.insertString(0, str, null);
-        }
-
-        // "hello world"
-        function actionHello() {
-            showScript(arguments.callee.title,
-                "alert('Hello, world');");
-        }
-        actionHello.title = "Hello, World";
-
-        // eval the "hello world"!
-        function actionEval() {
-            showScript(actionEval.title,
-                "eval(\"alert('Hello, world')\");");
-        }
-        actionEval.title = "Eval";
-
-        // show how to access Java static methods
-        function actionJavaStatic() {
-            showScript(arguments.callee.title,
-                "// Just use Java syntax\n" +
-                "var props = java.lang.System.getProperties();\n" +
-                "alert(props.get('os.name'));");
-        }
-        actionJavaStatic.title = "Java Static Calls";
-
-        // show how to access Java classes, methods
-        function actionJavaAccess() {
-            showScript(arguments.callee.title,
-                "// just use new JavaClass();\n" +
-                "var fr = new javax.swing.JFrame();\n" +
-                "// call all public methods as in Java\n" +
-                "fr.setTitle('hello');\n" +
-                "fr.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);\n" +
-                "fr.setSize(200, 200);\n" +
-                "fr.setVisible(true);");
-        }
-        actionJavaAccess.title = "Java Object Access";
-
-        // show how to use Java bean conventions
-        function actionJavaBean() {
-            showScript(arguments.callee.title,
-                "var fr = new javax.swing.JFrame();\n" +
-                "fr.setSize(200, 200);\n" +
-                "// access public get/set methods as fields\n" +
-                "fr.defaultCloseOperation = javax.swing.WindowConstants.DISPOSE_ON_CLOSE;\n" +
-                "fr.title = 'hello';\n" +
-                "fr.visible = true;"); 
-        }
-        actionJavaBean.title = "Java Beans";
-
-        // show how to implement Java interface
-        function actionJavaInterface() {
-            showScript(arguments.callee.title,
-                "// use Java anonymizer class-like syntax!\n" +
-                "var r = new java.lang.Runnable() {\n" +
-                "            run: function() {\n" +
-                "                    alert('hello');\n" +
-                "            }\n" +
-                "    };\n" +
-                "// use the above Runnable to create a Thread\n" +
-                "java.lang.Thread(r).start();\n" +
-                "// For simple one method interfaces, just pass script function\n" +
-                "java.lang.Thread(function() { alert('world'); }).start();");
-        }
-        actionJavaInterface.title = "Java Interfaces";
-
-        // show how to import Java classes, packages
-        function actionJavaImport() {
-            showScript(arguments.callee.title,
-                "// use Java-like import *...\n" +
-                "//    importPackage(java.io);\n" +
-                "// or import a specific class\n" +
-                "//    importClass(java.io.File);\n" +
-                "// or better - import just within a scope!\n" +
-                "var ioPkgs = JavaImporter(java.io);\n" +
-                "with (ioPkgs) { alert(new File('.').absolutePath); }");
-        }
-        actionJavaImport.title = "Java Import";
-
-        // "Help" menu 
-
-	/*
-         * Shows a one liner help message for each 
-         * global function. Note that this function 
-         * depends on docString meta-data for each 
-         * function.
-         */
-        function actionHelpGlobals() {
-            var names = new java.util.ArrayList();
-            for (var i in this) {
-                var func = this[i];
-                if (typeof(func) == "function" &&
-                   ("docString" in func)) {
-                    names.add(i);
-                }
-            }
-            java.util.Collections.sort(names);
-            var helpDoc = new java.lang.StringBuffer();
-            helpDoc.append("<table border='1'>");
-            var itr = names.iterator();
-            while (itr.hasNext()) {
-                var name = itr.next();
-                helpDoc.append("<tr><td>");
-                helpDoc.append(name);
-                helpDoc.append("</td><td>");
-                helpDoc.append(this[name].docString);
-                helpDoc.append("</td></tr>");                
-            }
-            helpDoc.append("</table>");
-
-            var helpEditor = new JEditorPane();
-            helpEditor.setContentType("text/html");            
-            helpEditor.setEditable(false);
-            helpEditor.setText(helpDoc.toString());
-
-            var scroller = new JScrollPane();
-            var port = scroller.getViewport();
-            port.add(helpEditor);
-
-            var helpFrame = new JFrame("Help - Global Functions");
-            helpFrame.getContentPane().add("Center", scroller);
-            helpFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
-            helpFrame.pack();
-            helpFrame.setSize(500, 600); 
-            helpFrame.setVisible(true);
-        }
-
-        // show a simple about message for scriptpad
-        function actionAbout() {
-            alert("Scriptpad\nVersion 1.0", "Scriptpad");
-        }
-
-        /*
-         * This data is used to construct menu bar.
-         * This way adding a menu is easier. Just add
-         * top level menu or add an item to an existing 
-         * menu. "action" should be a function that is
-         * called back on clicking the correponding menu.
-         */
-        var menuData = [
-            {
-              menu: "File",
-              items: [ 
-                  { name: "New",  action: actionNew , accel: KeyEvent.VK_N },
-                  { name: "Open...", action: actionOpen, accel: KeyEvent.VK_O },                         
-                  { name: "Open URL...", action: actionOpenURL, accel: KeyEvent.VK_U },
-                  { name: "Save", action: actionSave, accel: KeyEvent.VK_S },
-                  { name: "Save As...", action: actionSaveAs },
-                  { name: "-" },
-                  { name: "Exit", action: actionExit }
-                ]
-            },
-
-            {
-              menu: "Edit", 
-              items: [ 
-                  { name: "Cut", action: actionCut, accel: KeyEvent.VK_X },
-                  { name: "Copy", action: actionCopy, accel: KeyEvent.VK_C },                        
-                  { name: "Paste", action: actionPaste, accel: KeyEvent.VK_V },
-                  { name: "-" },
-                  { name: "Select All", action: actionSelectAll, accel: KeyEvent.VK_A }
-                ]
-            },
-           
-            { 
-              menu: "Tools", 
-              items: [                 
-                  { name: "Run", action: actionRun, accel: KeyEvent.VK_R },
-                ]
-            },
-
-            { 
-              menu: "Examples", 
-              items: [                 
-                  { name: actionHello.title, action: actionHello },
-                  { name: actionEval.title, action: actionEval },
-                  { name: actionJavaStatic.title, action: actionJavaStatic },
-                  { name: actionJavaAccess.title, action: actionJavaAccess },
-                  { name: actionJavaBean.title, action: actionJavaBean },
-                  { name: actionJavaInterface.title, action: actionJavaInterface },
-                  { name: actionJavaImport.title, action: actionJavaImport },
-               ]
-            },
-
-            { 
-              menu: "Help",  
-              items: [ 
-                  { name: "Global Functions", action: actionHelpGlobals },
-                  { name: "-" },
-                  { name: "About Scriptpad", action: actionAbout },
-                ]
-            }
-        ];
-
-
-        function setMenuAccelerator(mi, accel) {
-            var keyStroke = KeyStroke.getKeyStroke(accel,
-                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false);
-            mi.setAccelerator(keyStroke);
-        }
-        
-        // create a menubar using the above menu data
-        function createMenubar() {
-            var mb = new JMenuBar();
-            for (var m in menuData) {
-                var items = menuData[m].items;
-                var menu = new JMenu(menuData[m].menu);                
-                for (var i in items) {
-                    if (items[i].name.equals("-")) {
-                        menu.addSeparator();
-                    } else {
-                        var mi = new JMenuItem(items[i].name);
-                        var action = items[i].action;
-                        mi.addActionListener(action);
-                        var accel = items[i].accel;
-                        if (accel) {
-                            setMenuAccelerator(mi, accel);
-                        }
-                        menu.add(mi);
-                    }
-	        }                    
-	        mb.add(menu);
-            }
-            return mb;
-        }
-
-        // function to add a new menu item under "Tools" menu
-        function addTool(menuItem, action, accel) {
-            if (typeof(action) != "function") {
-                return;
-            }
-
-            var toolsIndex = -1;
-            // find the index of the "Tools" menu
-            for (var i in menuData) {
-                if (menuData[i].menu.equals("Tools")) {
-                    toolsIndex = i;
-                    break;
-                }
-            }
-            if (toolsIndex == -1) {
-                return;
-            }
-            var toolsMenu = frame.getJMenuBar().getMenu(toolsIndex);
-            var mi = new JMenuItem(menuItem);
-            mi.addActionListener(action);
-            if (accel) {
-                setMenuAccelerator(mi, accel);
-            }
-            toolsMenu.add(mi);
-        }
-
-
-        // create Scriptpad frame
-        function createFrame() {
-            frame = new JFrame();
-            frame.setTitle(defaultTitle);
-            frame.setBackground(Color.lightGray);
-            frame.getContentPane().setLayout(new BorderLayout());
-
-            // create notepad panel
-            var notepad = new JPanel();
-            notepad.setBorder(BorderFactory.createEtchedBorder());
-            notepad.setLayout(new BorderLayout());
-
-            // create editor
-            editor = createEditor();
-            var scroller = new JScrollPane();
-            var port = scroller.getViewport();
-            port.add(editor);
-
-            // add editor to notepad panel
-            var panel = new JPanel(); 
-            panel.setLayout(new BorderLayout());        
-            panel.add("Center", scroller);
-            notepad.add("Center", panel);
-
-            // add notepad panel to frame
-            frame.getContentPane().add("Center", notepad);
-
-            // set menu bar to frame and show the frame   
-            frame.setJMenuBar(createMenubar());
-            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-            frame.pack();
-            frame.setSize(500, 600);
-        }
-
-        // show Scriptpad frame
-        function showFrame() {
-            // set global variable by the name "window"
-            this.window = frame;     
-
-            // open new document
-            actionNew();
-
-            frame.setVisible(true);
-        }
-
-        // create and show Scriptpad frame
-        createFrame();
-        showFrame();
-
-        /*
-         * Application object has two fields "frame", "editor"
-         * which are current JFrame and editor and a method
-         * called "addTool" to add new menu item to "Tools" menu.
-         */
-        return {
-            frame: frame,
-            editor: editor,
-            addTool: addTool
-        };
+// main entry point of the scriptpad application
+var main = function() {
+    function createEditor() {
+        var c = new guiPkgs.JTextArea();
+        c.setDragEnabled(true);
+        c.setFont(new guiPkgs.Font("monospaced", guiPkgs.Font.PLAIN, 12));
+        return c;
     }
-}
+
+    /*const*/ var titleSuffix = "- Scriptpad";
+    /*const*/ var defaultTitle = "Untitled" + titleSuffix;
+
+    // Scriptpad's main frame
+    var frame;
+    // Scriptpad's main editor
+    var editor;
+
+    // To track the current file name
+    var curFileName = null;
+
+    // To track whether the current document
+    // has been modified or not
+    var docChanged = false;
+
+    // check and alert user for unsaved
+    // but modified document
+    function checkDocChanged() {
+        if (docChanged) {
+            // ignore zero-content untitled document
+            if (curFileName == null &&
+                editor.document.length == 0) {
+                return;
+            }
+
+            if (confirm("Do you want to save the changes?",
+                        "The document has changed")) {
+                actionSave();
+            }
+        }
+    }
+
+    // set a document listener to track
+    // whether that is modified or not
+    function setDocListener() {
+        var doc = editor.getDocument();
+        docChanged = false;
+        doc.addDocumentListener( new guiPkgs.DocumentListener() {
+                                     equals: function(o) {
+                                         return this === o; },
+                                     toString: function() {
+                                         return "doc listener"; },
+                                     changeUpdate: function() {
+                                         docChanged = true; },
+                                     insertUpdate: function() {
+                                         docChanged = true; },
+                                     removeUpdate: function() {
+                                         docChanged = true; }
+                                 });
+    }
+
+    // menu action functions
+
+    // "File" menu
+
+    // create a "new" document
+    function actionNew() {
+        checkDocChanged();
+        curFileName = null;
+        editor.setDocument(new guiPkgs.PlainDocument());
+        setDocListener();
+        frame.setTitle(defaultTitle);
+        editor.revalidate();
+    }
+
+    // open an existing file
+    function actionOpen() {
+        checkDocChanged();
+        var f = fileDialog();
+        if (f == null) {
+            return;
+        }
+
+        if (f.isFile() && f.canRead()) {
+            frame.setTitle(f.getName() + titleSuffix);
+            editor.setDocument(new guiPkgs.PlainDocument());
+            var progress = new guiPkgs.JProgressBar();
+            progress.setMinimum(0);
+            progress.setMaximum(f.length());
+            var doc = editor.getDocument();
+            var inp = new java.io.FileReader(f);
+            var buff = java.lang.reflect.Array.newInstance(
+                java.lang.Character.TYPE, 4096);
+            var nch;
+            while ((nch = inp.read(buff, 0, buff.length)) != -1) {
+                doc.insertString(doc.getLength(),
+                                 new java.lang.String(buff, 0, nch), null);
+                progress.setValue(progress.getValue() + nch);
+            }
+            inp.close();
+            curFileName = f.getAbsolutePath();
+            setDocListener();
+        } else {
+            error("Can not open file: " + f,
+                  "Error opening file: " + f);
+        }
+    }
+
+    // open script from a URL
+    function actionOpenURL() {
+        checkDocChanged();
+        var url = prompt("Address:");
+        if (url == null) {
+            return;
+        }
+
+        try {
+            var u = new java.net.URL(url);
+            editor.setDocument(new guiPkgs.PlainDocument());
+            frame.setTitle(url + titleSuffix);
+            var progress = new guiPkgs.JProgressBar();
+            progress.setMinimum(0);
+            progress.setIndeterminate(true);
+            var doc = editor.getDocument();
+            var inp = new java.io.InputStreamReader(u.openStream());
+            var buff = java.lang.reflect.Array.newInstance(
+                java.lang.Character.TYPE, 4096);
+            var nch;
+            while ((nch = inp.read(buff, 0, buff.length)) != -1) {
+                doc.insertString(doc.getLength(),
+                                 new java.lang.String(buff, 0, nch), null);
+                progress.setValue(progress.getValue() + nch);
+            }
+            curFileName = null;
+            setDocListener();
+        } catch (e) {
+            error("Error opening URL: " + e,
+                  "Can not open URL: " + url);
+        }
+    }
+
+    // factored out "save" function used by
+    // save, save as menu actions
+    function save(file) {
+        var doc = editor.getDocument();
+        frame.setTitle(file.getName() + titleSuffix);
+        curFileName = file;
+        var progress = new guiPkgs.JProgressBar();
+        progress.setMinimum(0);
+        progress.setMaximum(file.length());
+        var out = new java.io.FileWriter(file);
+        var text = new guiPkgs.Segment();
+        text.setPartialReturn(true);
+        var charsLeft = doc.getLength();
+        var offset = 0;
+        var min;
+
+        while (charsLeft > 0) {
+            doc.getText(offset, Math.min(4096, charsLeft), text);
+            out.write(text.array, text.offset, text.count);
+            charsLeft -= text.count;
+            offset += text.count;
+            progress.setValue(offset);
+            java.lang.Thread.sleep(10);
+        }
+
+        out.flush();
+        out.close();
+        docChanged = false;
+    }
+
+    // file-save as menu
+    function actionSaveAs() {
+        var ret = fileDialog(null, true);
+        if (ret == null) {
+            return;
+        }
+        save(ret);
+    }
+
+    // file-save menu
+    function actionSave() {
+        if (curFileName) {
+            save(new java.io.File(curFileName));
+        } else {
+            actionSaveAs();
+        }
+    }
+
+    // exit from scriptpad
+    function actionExit() {
+        checkDocChanged();
+        java.lang.System.exit(0);
+    }
+
+    // "Edit" menu
+
+    // cut the currently selected text
+    function actionCut() {
+        editor.cut();
+    }
+
+    // copy the currently selected text to clipboard
+    function actionCopy() {
+        editor.copy();
+    }
+
+    // paste clipboard content to document
+    function actionPaste() {
+        editor.paste();
+    }
+
+    // select all the text in editor
+    function actionSelectAll() {
+        editor.selectAll();
+    }
+
+    // "Tools" menu
+
+    // run the current document as JavaScript
+    function actionRun() {
+        var doc = editor.getDocument();
+        var script = doc.getText(0, doc.getLength());
+        var oldFile = engine.get(javax.script.ScriptEngine.FILENAME);
+        try {
+            if (engine == undefined) {
+                var m = new javax.script.ScriptEngineManager();
+                engine = m.getEngineByName("nashorn");
+            }
+            engine.put(javax.script.ScriptEngine.FILENAME, frame.title);
+            engine.eval(script, context);
+        } catch (e) {
+            error(e, "Script Error");
+            e.printStackTrace();
+        } finally {
+            engine.put(javax.script.ScriptEngine.FILENAME, oldFile);
+        }
+    }
+
+    // "Examples" menu
+
+    // show given script as new document
+    function showScript(title, str) {
+        actionNew();
+        frame.setTitle("Example - " + title + titleSuffix);
+        var doc = editor.document;
+        doc.insertString(0, str, null);
+    }
+
+    // "hello world"
+    function actionHello() {
+        showScript(actionEval.title,
+                   "alert('Hello, world');");
+    }
+    actionHello.title = "Hello, World";
+
+    // eval the "hello world"!
+    function actionEval() {
+        showScript(actionEval.title,
+                   "eval(\"alert('Hello, world')\");");
+    }
+    actionEval.title = "Eval";
+
+    // show how to access Java static methods
+    function actionJavaStatic() {
+        showScript(arguments.callee.title,
+                   "// Just use Java syntax\n" +
+                   "var props = java.lang.System.getProperties();\n" +
+                   "alert(props.get('os.name'));");
+    }
+    actionJavaStatic.title = "Java Static Calls";
+
+    // show how to access Java classes, methods
+    function actionJavaAccess() {
+        showScript(arguments.callee.title,
+                   "// just use new JavaClass();\n" +
+                   "var fr = new javax.swing.JFrame();\n" +
+                   "// call all public methods as in Java\n" +
+                   "fr.setTitle('hello');\n" +
+                   "fr.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);\n" +
+                   "fr.setSize(200, 200);\n" +
+                   "fr.setVisible(true);");
+    }
+    actionJavaAccess.title = "Java Object Access";
+
+    // show how to use Java bean conventions
+    function actionJavaBean() {
+        showScript(arguments.callee.title,
+                   "var fr = new javax.swing.JFrame();\n" +
+                   "fr.setSize(200, 200);\n" +
+                   "// access public get/set methods as fields\n" +
+                   "fr.defaultCloseOperation = javax.swing.WindowConstants.DISPOSE_ON_CLOSE;\n" +
+                   "fr.title = 'hello';\n" +
+                   "fr.visible = true;");
+    }
+    actionJavaBean.title = "Java Beans";
+
+    // show how to implement Java interface
+    function actionJavaInterface() {
+        showScript(arguments.callee.title,
+                   "// use Java anonymizer class-like syntax!\n" +
+                   "var r = new java.lang.Runnable() {\n" +
+                   "            run: function() {\n" +
+                   "                    alert('hello');\n" +
+                   "            }\n" +
+                   "    };\n" +
+                   "// use the above Runnable to create a Thread\n" +
+                   "new java.lang.Thread(r).start();\n" +
+                   "// For simple one method interfaces, just pass script function\n" +
+                   "new java.lang.Thread(function() { alert('world'); }).start();");
+    }
+    actionJavaInterface.title = "Java Interfaces";
+
+    // show how to import Java classes, packages
+    function actionJavaImport() {
+        showScript(arguments.callee.title,
+                   "// use Java-like import *...\n" +
+                   "//    importPackage(java.io);\n" +
+                   "// or import a specific class\n" +
+                   "//    importClass(java.io.File);\n" +
+                   "// or better - import just within a scope!\n" +
+                   "var ioPkgs = JavaImporter(java.io);\n" +
+                   "with (ioPkgs) { alert(new File('.').absolutePath); }");
+    }
+    actionJavaImport.title = "Java Import";
+
+    // "Help" menu
+
+    /*
+     * Shows a one liner help message for each
+     * global function. Note that this function
+     * depends on docString meta-data for each
+     * function.
+     */
+    function actionHelpGlobals() {
+        var names = new java.util.ArrayList();
+        for (var i in globalThis) {
+            var func = globalThis[i];
+            if (typeof(func) == "function" &&
+                ("docString" in func)) {
+                names.add(i);
+            }
+        }
+        java.util.Collections.sort(names);
+        var helpDoc = new java.lang.StringBuffer();
+        helpDoc.append("<table border='1'>");
+        var itr = names.iterator();
+        while (itr.hasNext()) {
+            var name = itr.next();
+            helpDoc.append("<tr><td>");
+            helpDoc.append(name);
+            helpDoc.append("</td><td>");
+            helpDoc.append(globalThis[name].docString);
+            helpDoc.append("</td></tr>");
+        }
+        helpDoc.append("</table>");
+
+        var helpEditor = new guiPkgs.JEditorPane();
+        helpEditor.setContentType("text/html");
+        helpEditor.setEditable(false);
+        helpEditor.setText(helpDoc.toString());
+
+        var scroller = new guiPkgs.JScrollPane();
+        var port = scroller.getViewport();
+        port.add(helpEditor);
+
+        var helpFrame = new guiPkgs.JFrame("Help - Global Functions");
+        helpFrame.getContentPane().add("Center", scroller);
+        helpFrame.setDefaultCloseOperation(guiPkgs.WindowConstants.DISPOSE_ON_CLOSE);
+        helpFrame.pack();
+        helpFrame.setSize(500, 600);
+        helpFrame.setVisible(true);
+    }
+
+    // show a simple about message for scriptpad
+    function actionAbout() {
+        alert("Scriptpad\nVersion 1.1", "Scriptpad");
+    }
+
+    /*
+     * This data is used to construct menu bar.
+     * This way adding a menu is easier. Just add
+     * top level menu or add an item to an existing
+     * menu. "action" should be a function that is
+     * called back on clicking the correponding menu.
+     */
+    var menuData = [
+        {
+            menu: "File",
+            items: [
+                { name: "New",  action: actionNew , accel: guiPkgs.KeyEvent.VK_N },
+                { name: "Open...", action: actionOpen, accel: guiPkgs.KeyEvent.VK_O },
+                { name: "Open URL...", action: actionOpenURL, accel: guiPkgs.KeyEvent.VK_U },
+                { name: "Save", action: actionSave, accel: guiPkgs.KeyEvent.VK_S },
+                { name: "Save As...", action: actionSaveAs },
+                { name: "-" },
+                { name: "Exit", action: actionExit, accel: guiPkgs.KeyEvent.VK_Q }
+            ]
+        },
+
+        {
+            menu: "Edit",
+            items: [
+                { name: "Cut", action: actionCut, accel: guiPkgs.KeyEvent.VK_X },
+                { name: "Copy", action: actionCopy, accel: guiPkgs.KeyEvent.VK_C },
+                { name: "Paste", action: actionPaste, accel: guiPkgs.KeyEvent.VK_V },
+                { name: "-" },
+                { name: "Select All", action: actionSelectAll, accel: guiPkgs.KeyEvent.VK_A }
+            ]
+        },
+
+        {
+            menu: "Tools",
+            items: [
+                { name: "Run", action: actionRun, accel: guiPkgs.KeyEvent.VK_R }
+            ]
+        },
+
+        {
+            menu: "Examples",
+            items: [
+                { name: actionHello.title, action: actionHello },
+                { name: actionEval.title, action: actionEval },
+                { name: actionJavaStatic.title, action: actionJavaStatic },
+                { name: actionJavaAccess.title, action: actionJavaAccess },
+                { name: actionJavaBean.title, action: actionJavaBean },
+                { name: actionJavaInterface.title, action: actionJavaInterface },
+                { name: actionJavaImport.title, action: actionJavaImport }
+            ]
+        },
+
+        {
+            menu: "Help",
+            items: [
+                { name: "Global Functions", action: actionHelpGlobals },
+                { name: "-" },
+                { name: "About Scriptpad", action: actionAbout }
+            ]
+        }
+    ];
+
+    function setMenuAccelerator(mi, accel) {
+        var keyStroke = guiPkgs.KeyStroke.getKeyStroke(accel,
+                                                       guiPkgs.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false);
+        mi.setAccelerator(keyStroke);
+    }
+
+    // create a menubar using the above menu data
+    function createMenubar() {
+        var mb = new guiPkgs.JMenuBar();
+        for (var m in menuData) {
+            var items = menuData[m].items;
+            var menu = new guiPkgs.JMenu(menuData[m].menu);
+
+            for (var i in items) {
+                if (items[i].name.equals("-")) {
+                    menu.addSeparator();
+                } else {
+                    var mi = new guiPkgs.JMenuItem(items[i].name);
+                    var action = items[i].action;
+                    mi.addActionListener(action);
+                    var accel = items[i].accel;
+                    if (accel) {
+                        setMenuAccelerator(mi, accel);
+                    }
+                    menu.add(mi);
+                }
+	        }
+
+	        mb.add(menu);
+        }
+
+        return mb;
+    }
+
+    // function to add a new menu item under "Tools" menu
+    function addTool(menuItem, action, accel) {
+        if (typeof(action) != "function") {
+            return;
+        }
+
+        var toolsIndex = -1;
+        // find the index of the "Tools" menu
+        for (var i in menuData) {
+            if (menuData[i].menu.equals("Tools")) {
+                toolsIndex = i;
+                break;
+            }
+        }
+        if (toolsIndex == -1) {
+            return;
+        }
+        var toolsMenu = frame.getJMenuBar().getMenu(toolsIndex);
+        var mi = new guiPkgs.JMenuItem(menuItem);
+        mi.addActionListener(action);
+        if (accel) {
+            setMenuAccelerator(mi, accel);
+        }
+        toolsMenu.add(mi);
+    }
+
+    // create Scriptpad frame
+    function createFrame() {
+        frame = new guiPkgs.JFrame();
+        frame.setTitle(defaultTitle);
+        frame.setBackground(guiPkgs.Color.lightGray);
+        frame.getContentPane().setLayout(new guiPkgs.BorderLayout());
+
+        // create notepad panel
+        var notepad = new guiPkgs.JPanel();
+        notepad.setBorder(guiPkgs.BorderFactory.createEtchedBorder());
+        notepad.setLayout(new guiPkgs.BorderLayout());
+
+        // create editor
+        editor = createEditor();
+        var scroller = new guiPkgs.JScrollPane();
+        var port = scroller.getViewport();
+        port.add(editor);
+
+        // add editor to notepad panel
+        var panel = new guiPkgs.JPanel();
+        panel.setLayout(new guiPkgs.BorderLayout());
+        panel.add("Center", scroller);
+        notepad.add("Center", panel);
+
+        // add notepad panel to frame
+        frame.getContentPane().add("Center", notepad);
+
+        // set menu bar to frame and show the frame
+        frame.setJMenuBar(createMenubar());
+        frame.setDefaultCloseOperation(guiPkgs.JFrame.EXIT_ON_CLOSE);
+        frame.pack();
+        frame.setSize(500, 600);
+    }
+
+    // show Scriptpad frame
+    function showFrame() {
+        // set global variable by the name "window"
+        globalThis.window = frame;
+
+        // open new document
+        actionNew();
+
+        frame.setVisible(true);
+    }
+
+    // create and show Scriptpad frame
+    createFrame();
+    showFrame();
+
+    /*
+     * Application object has two fields "frame", "editor"
+     * which are current JFrame and editor and a method
+     * called "addTool" to add new menu item to "Tools" menu.
+     */
+    return {
+        frame: frame,
+        editor: editor,
+        addTool: addTool
+    };
+};
 
 /*
- * Call the main and store Application object 
+ * Call the main and store Application object
  * in a global variable named "application".
  */
 var application = main();
@@ -657,4 +660,3 @@
 }
 
 loadUserInit();
-
diff --git a/jdk/src/share/sample/scripting/scriptpad/src/scripts/browse.js b/jdk/src/share/sample/scripting/scriptpad/src/scripts/browse.js
index 975e454..fbe50e1 100644
--- a/jdk/src/share/sample/scripting/scriptpad/src/scripts/browse.js
+++ b/jdk/src/share/sample/scripting/scriptpad/src/scripts/browse.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,33 +37,30 @@
  * this sample code.
  */
 
-
 /*
  * This function uses new Swing Desktop API in JDK 6.
  * To use this with scriptpad, open this in scriptpad
  * and use "Tools->Run Script" menu.
  */
 function browse() {
-    with (guiPkgs) {
-        var desktop = null;
-        // Before more Desktop API is used, first check 
-        // whether the API is supported by this particular 
-        // virtual machine (VM) on this particular host.
-        if (Desktop.isDesktopSupported()) {
-            desktop = Desktop.getDesktop();
-        } else {
-            alert("no desktop support");
-            return;
-        }
+    var desktop = null;
+    // Before more Desktop API is used, first check
+    // whether the API is supported by this particular
+    // virtual machine (VM) on this particular host.
+    if (java.awt.Desktop.isDesktopSupported()) {
+        desktop = java.awt.Desktop.getDesktop();
+    } else {
+        alert("no desktop support");
+        return;
+    }
 
-        if (desktop.isSupported(Desktop.Action.BROWSE)) {
-            var url = prompt("Address:");
-            if (url != null) {
-                desktop.browse(new java.net.URI(url));
-            }
-        } else {
-            alert("no browser support");
+    if (desktop.isSupported(java.awt.Desktop.Action.BROWSE)) {
+        var url = prompt("Address:");
+        if (url != null) {
+            desktop.browse(new java.net.URI(url));
         }
+    } else {
+        alert("no browser support");
     }
 }
 
@@ -71,4 +68,3 @@
     // add "Browse" menu item under "Tools" menu
     this.application.addTool("Browse", browse);
 }
-
diff --git a/jdk/src/share/sample/scripting/scriptpad/src/scripts/insertfile.js b/jdk/src/share/sample/scripting/scriptpad/src/scripts/insertfile.js
index b463e9a..07a7ac2 100644
--- a/jdk/src/share/sample/scripting/scriptpad/src/scripts/insertfile.js
+++ b/jdk/src/share/sample/scripting/scriptpad/src/scripts/insertfile.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,7 +37,6 @@
  * this sample code.
  */
 
-
 /*
  * This script adds "Insert File" mode menu item to "Tools" menu.
  * When selected, this menu shows a file dialog box and inserts
@@ -48,18 +47,22 @@
     application.addTool("Insert File...",
         function() {
             var file = fileDialog();
-            if (file) {               
+
+            if (file) {
                 var reader = new java.io.FileReader(file);
                 var arr = java.lang.reflect.Array.newInstance(
                       java.lang.Character.TYPE, 8*1024); // 8K at a time
                 var buf = new java.lang.StringBuffer();
                 var numChars;
+
                 while ((numChars = reader.read(arr, 0, arr.length)) > 0) {
                     buf.append(arr, 0, numChars);
                 }
+
                 var pos = application.editor.caretPosition;
                 var doc = application.editor.document;
+
                 doc.insertString(pos, buf.toString(), null);
            }
-        })
+        });
 }
diff --git a/jdk/src/share/sample/scripting/scriptpad/src/scripts/linewrap.js b/jdk/src/share/sample/scripting/scriptpad/src/scripts/linewrap.js
index e1ac50d..989473a 100644
--- a/jdk/src/share/sample/scripting/scriptpad/src/scripts/linewrap.js
+++ b/jdk/src/share/sample/scripting/scriptpad/src/scripts/linewrap.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,19 +37,15 @@
  * this sample code.
  */
 
-
 /*
  * This script adds "Line Wrap" mode menu item to "Tools" menu.
  * When selected, this menu toggles the current word wrap mode
  * of the editor.
  */
-with (guiPkgs) {
 
-    function toggleLineWrap() {
-        var wrap = application.editor.lineWrap;
-        application.editor.lineWrap = !wrap;
-    }
-
-    application.addTool("Line Wrap",  toggleLineWrap);
+function toggleLineWrap() {
+    var wrap = application.editor.lineWrap;
+    application.editor.lineWrap = !wrap;
 }
 
+application.addTool("Line Wrap",  toggleLineWrap);
diff --git a/jdk/src/share/sample/scripting/scriptpad/src/scripts/mail.js b/jdk/src/share/sample/scripting/scriptpad/src/scripts/mail.js
index 7104e29..cabe5c47 100644
--- a/jdk/src/share/sample/scripting/scriptpad/src/scripts/mail.js
+++ b/jdk/src/share/sample/scripting/scriptpad/src/scripts/mail.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,30 +37,27 @@
  * this sample code.
  */
 
-
 /*
  * This function uses new Swing Desktop API in JDK 6.
  * To use this with scriptpad, open this in scriptpad
  * and use "Tools->Run Script" menu.
  */
 function mail() {
-    with (guiPkgs) {
-        var desktop = null;
-        // Before more Desktop API is used, first check 
-        // whether the API is supported by this particular 
-        // virtual machine (VM) on this particular host.
-        if (Desktop.isDesktopSupported()) {
-            desktop = Desktop.getDesktop();
-        } else {
-            alert("no desktop support");
-            return;
-        }
+    var desktop = null;
+    // Before more Desktop API is used, first check
+    // whether the API is supported by this particular
+    // virtual machine (VM) on this particular host.
+    if (java.awt.Desktop.isDesktopSupported()) {
+        desktop = java.awt.Desktop.getDesktop();
+    } else {
+        alert("no desktop support");
+        return;
+    }
 
-        if (desktop.isSupported(Desktop.Action.MAIL)) {
-            var mailTo = prompt("Mail To:");
-            if (mailTo != null) {
-                desktop.mail(new java.net.URI("mailto", mailTo, null));
-            }
+    if (desktop.isSupported(java.awt.Desktop.Action.MAIL)) {
+        var mailTo = prompt("Mail To:");
+        if (mailTo != null) {
+            desktop.mail(new java.net.URI("mailto", mailTo, null));
         }
     }
 }
diff --git a/jdk/src/share/sample/scripting/scriptpad/src/scripts/memmonitor.js b/jdk/src/share/sample/scripting/scriptpad/src/scripts/memmonitor.js
index 7fac72f..0744e30 100644
--- a/jdk/src/share/sample/scripting/scriptpad/src/scripts/memmonitor.js
+++ b/jdk/src/share/sample/scripting/scriptpad/src/scripts/memmonitor.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,36 +37,37 @@
  * this sample code.
  */
 
-
 // this checker function runs asynchronously
 function memoryChecker(memoryBean, threshold, interval) {
     while (true) {
         var memUsage = memoryBean.HeapMemoryUsage;
         var usage = memUsage.get("used") / (1024 * 1024);
-        println(usage);
+
+        println("usage: " + usage);
+
         if (usage > threshold) {
             alert("Hey! heap usage threshold exceeded!");
             // after first alert just return.
             return;
         }
-        java.lang.Thread.currentThread().sleep(interval);
+
+        java.lang.Thread.sleep(interval);
     }
 }
 
-
 // add "Tools->Memory Monitor" menu item
 if (this.application != undefined) {
-    this.application.addTool("Memory Monitor", 
+    this.application.addTool("Memory Monitor",
         function () {
             // show threshold box with default of 50 MB
             var threshold = prompt("Threshold (mb)", 50);
+
             // show interval box with default of 1000 millisec.
             var interval = prompt("Sample Interval (ms):", 1000);
             var memoryBean = mbean("java.lang:type=Memory");
 
-            // ".future" makes the function to be called 
+            // ".future" makes the function to be called
             // asynchronously in a separate thread.
             memoryChecker.future(memoryBean, threshold, interval);
         });
 }
-
diff --git a/jdk/src/share/sample/scripting/scriptpad/src/scripts/memory.js b/jdk/src/share/sample/scripting/scriptpad/src/scripts/memory.js
index 53b8b35..b8252fb 100644
--- a/jdk/src/share/sample/scripting/scriptpad/src/scripts/memory.js
+++ b/jdk/src/share/sample/scripting/scriptpad/src/scripts/memory.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,7 +37,6 @@
  * this sample code.
  */
 
-
 /*
  * This script serves as a simple "monitored application".
  * Start this script using memory.bat or memory.sh in the
@@ -45,12 +44,11 @@
  */
 
 java.lang.System.out.print("Enter a number and press enter:");
-java.lang.System["in"].read();        
+var input = java.lang.System["in"].read();
 
 // allocate an integer array of "big enough" size!
 var a = java.lang.reflect.Array.newInstance(
-            java.lang.Integer.TYPE, 1024*1024);  
+    java.lang.Integer.TYPE, input * 1024 * 1024);
 
-// loop forever!
-while (true);
-
+// sleep some time...
+java.lang.Thread.sleep(10*60*1000);
diff --git a/jdk/src/share/sample/scripting/scriptpad/src/scripts/memory.sh b/jdk/src/share/sample/scripting/scriptpad/src/scripts/memory.sh
index d42370f..5477623 100644
--- a/jdk/src/share/sample/scripting/scriptpad/src/scripts/memory.sh
+++ b/jdk/src/share/sample/scripting/scriptpad/src/scripts/memory.sh
@@ -30,7 +30,3 @@
 #
 
 jrunscript -J-Dcom.sun.management.jmxremote.port=1090 -J-Dcom.sun.management.jmxremote.ssl=false -J-Dcom.sun.management.jmxremote.authenticate=false memory.js
-
-
-
-
diff --git a/jdk/src/share/sample/scripting/scriptpad/src/scripts/textcolor.js b/jdk/src/share/sample/scripting/scriptpad/src/scripts/textcolor.js
index 49f5dfb..b9d86cc 100644
--- a/jdk/src/share/sample/scripting/scriptpad/src/scripts/textcolor.js
+++ b/jdk/src/share/sample/scripting/scriptpad/src/scripts/textcolor.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,14 +37,13 @@
  * this sample code.
  */
 
-
 /*
  * This script adds "Selected Text Color" menu item to "Tools" menu.
  * When selected, this menu changes the "selected text" color.
  */
 if (this.application) {
     application.addTool("Selected Text Color...",
-        function() {          
+        function() {
             var color = application.editor.selectedTextColor;
             color = colorDialog("Selected Text Color", color);
             application.editor.selectedTextColor = color;
diff --git a/jdk/src/solaris/bin/jexec.c b/jdk/src/solaris/bin/jexec.c
index 2e478d8..a30617d 100644
--- a/jdk/src/solaris/bin/jexec.c
+++ b/jdk/src/solaris/bin/jexec.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -90,6 +90,8 @@
 static const char * BAD_EXEC_MSG     = "jexec failed";
 static const char * CRAZY_EXEC_MSG   = "missing args";
 static const char * MISSING_JAVA_MSG = "can't locate java";
+static const char * BAD_ARG_MSG      = "incorrect number of arguments";
+static const char * MEM_FAILED_MSG   = "memory allocation failed";
 #ifdef __linux__
 static const char * BAD_PATHNAME_MSG = "invalid path";
 static const char * BAD_FILE_MSG     = "invalid file";
@@ -156,6 +158,7 @@
     const char ** nargv = NULL;          /* new args array       */
     int           nargc = 0;             /* new args array count */
     int           argi  = 0;             /* index into old array */
+    size_t        alen  = 0;             /* length of new array */
 
     /* Make sure we have something to work with */
     if ((argc < 1) || (argv == NULL)) {
@@ -168,8 +171,14 @@
     if (getJavaPath(argv[argi++], java, RELATIVE_DEPTH) != 0) {
         errorExit(errno, MISSING_JAVA_MSG);
     }
-
-    nargv = (const char **) malloc((argc + 2) * (sizeof (const char *)));
+    alen = (argc + 2) * (sizeof (const char *));
+    if (alen <= 0 || alen > INT_MAX / sizeof(char *)) {
+        errorExit(errno, BAD_ARG_MSG);
+    }
+    nargv = (const char **) malloc(alen);
+    if (nargv == NULL) {
+        errorExit(errno, MEM_FAILED_MSG);
+    }
     nargv[nargc++] = java;
 
 #ifdef __linux__
diff --git a/jdk/src/solaris/classes/sun/font/XRGlyphCacheEntry.java b/jdk/src/solaris/classes/sun/font/XRGlyphCacheEntry.java
index 3ed0401..18ece2b 100644
--- a/jdk/src/solaris/classes/sun/font/XRGlyphCacheEntry.java
+++ b/jdk/src/solaris/classes/sun/font/XRGlyphCacheEntry.java
@@ -69,11 +69,28 @@
     }
 
     public static int getGlyphID(long glyphInfoPtr) {
-        return (int) StrikeCache.unsafe.getInt(glyphInfoPtr + StrikeCache.cacheCellOffset);
+        // We need to access the GlyphID with Unsafe.getAddress() because the
+        // corresponding field in the underlying C data-structure is of type
+        // 'void*' (see field 'cellInfo' of struct 'GlyphInfo'
+        // in src/share/native/sun/font/fontscalerdefs.h).
+        // On 64-bit Big-endian architectures it would be wrong to access this
+        // field with Unsafe.getInt().
+        return (int) StrikeCache.unsafe.getAddress(glyphInfoPtr +
+                                                   StrikeCache.cacheCellOffset);
     }
 
     public static void setGlyphID(long glyphInfoPtr, int id) {
-        StrikeCache.unsafe.putInt(glyphInfoPtr + StrikeCache.cacheCellOffset, id);
+        // We need to access the GlyphID with Unsafe.putAddress() because the
+        // corresponding field in the underlying C data-structure is of type
+        // 'void*' (see field 'cellInfo' of struct 'GlyphInfo' in
+        // src/share/native/sun/font/fontscalerdefs.h).
+        // On 64-bit Big-endian architectures it would be wrong to write this
+        // field with Unsafe.putInt() because it is also accessed from native
+        // code as a 'long'.
+        // See Java_sun_java2d_xr_XRBackendNative_XRAddGlyphsNative()
+        // in src/solaris/native/sun/java2d/x11/XRBackendNative.c
+        StrikeCache.unsafe.putAddress(glyphInfoPtr +
+                                      StrikeCache.cacheCellOffset, (long)id);
     }
 
     public int getGlyphID() {
@@ -105,12 +122,9 @@
     }
 
     public void writePixelData(ByteArrayOutputStream os, boolean uploadAsLCD) {
-        long pixelDataAddress;
-        if (StrikeCache.nativeAddressSize == 4) {
-            pixelDataAddress = 0xffffffff & StrikeCache.unsafe.getInt(glyphInfoPtr + StrikeCache.pixelDataOffset);
-        } else {
-            pixelDataAddress = StrikeCache.unsafe.getLong(glyphInfoPtr + StrikeCache.pixelDataOffset);
-        }
+        long pixelDataAddress =
+            StrikeCache.unsafe.getAddress(glyphInfoPtr +
+                                          StrikeCache.pixelDataOffset);
         if (pixelDataAddress == 0L) {
             return;
         }
diff --git a/jdk/src/solaris/native/java/net/NetworkInterface.c b/jdk/src/solaris/native/java/net/NetworkInterface.c
index af979b0..f887bbc 100644
--- a/jdk/src/solaris/native/java/net/NetworkInterface.c
+++ b/jdk/src/solaris/native/java/net/NetworkInterface.c
@@ -834,14 +834,19 @@
     }
 }
 
-netif *addif(JNIEnv *env, int sock, const char * if_name, netif *ifs, struct sockaddr* ifr_addrP, int family, short prefix) {
+netif *addif(JNIEnv *env, int sock, const char * if_name,
+             netif *ifs, struct sockaddr* ifr_addrP, int family,
+             short prefix)
+{
     netif *currif = ifs, *parent;
     netaddr *addrP;
 
 #ifdef LIFNAMSIZ
-    char name[LIFNAMSIZ],  vname[LIFNAMSIZ];
+    int ifnam_size = LIFNAMSIZ;
+    char name[LIFNAMSIZ], vname[LIFNAMSIZ];
 #else
-    char name[IFNAMSIZ],  vname[IFNAMSIZ];
+    int ifnam_size = IFNAMSIZ;
+    char name[IFNAMSIZ], vname[IFNAMSIZ];
 #endif
 
     char  *name_colonP;
@@ -857,7 +862,8 @@
      * currently doesn't have any concept of physical vs.
      * logical interfaces.
      */
-    strcpy(name, if_name);
+    strncpy(name, if_name, ifnam_size);
+    name[ifnam_size - 1] = '\0';
     *vname = 0;
 
     /*
@@ -934,9 +940,10 @@
      * insert it onto the list.
      */
     if (currif == NULL) {
-         CHECKED_MALLOC3(currif, netif *, sizeof(netif)+IFNAMSIZ );
+         CHECKED_MALLOC3(currif, netif *, sizeof(netif) + ifnam_size);
          currif->name = (char *) currif+sizeof(netif);
-         strcpy(currif->name, name);
+         strncpy(currif->name, name, ifnam_size);
+         currif->name[ifnam_size - 1] = '\0';
          currif->index = getIndex(sock, name);
          currif->addr = NULL;
          currif->childs = NULL;
@@ -969,9 +976,10 @@
         }
 
         if (currif == NULL) {
-            CHECKED_MALLOC3(currif, netif *, sizeof(netif)+ IFNAMSIZ );
+            CHECKED_MALLOC3(currif, netif *, sizeof(netif) + ifnam_size);
             currif->name = (char *) currif + sizeof(netif);
-            strcpy(currif->name, vname);
+            strncpy(currif->name, vname, ifnam_size);
+            currif->name[ifnam_size - 1] = '\0';
             currif->index = getIndex(sock, vname);
             currif->addr = NULL;
            /* Need to duplicate the addr entry? */
diff --git a/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c b/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c
index 0f8d0a8..3b38bba 100644
--- a/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c
+++ b/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c
@@ -742,7 +742,12 @@
     for (i=0; i < glyphCnt; i++) {
       GlyphInfo *jginfo = (GlyphInfo *) jlong_to_ptr(glyphInfoPtrs[i]);
 
-      gid[i] = (Glyph) (0x0ffffffffL & ((unsigned long)(jginfo->cellInfo)));
+      // 'jginfo->cellInfo' is of type 'void*'
+      // (see definition of 'GlyphInfo' in fontscalerdefs.h)
+      // 'Glyph' is typedefed to 'unsigned long'
+      // (see http://www.x.org/releases/X11R7.7/doc/libXrender/libXrender.txt)
+      // Maybe we should assert that (sizeof(void*) == sizeof(Glyph)) ?
+      gid[i] = (Glyph) (jginfo->cellInfo);
       xginfo[i].x = (-jginfo->topLeftX);
       xginfo[i].y = (-jginfo->topLeftY);
       xginfo[i].width = jginfo->width;
diff --git a/jdk/src/windows/classes/java/lang/ProcessImpl.java b/jdk/src/windows/classes/java/lang/ProcessImpl.java
index 90878af..de7a905 100644
--- a/jdk/src/windows/classes/java/lang/ProcessImpl.java
+++ b/jdk/src/windows/classes/java/lang/ProcessImpl.java
@@ -37,7 +37,10 @@
 import java.lang.ProcessBuilder.Redirect;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.ArrayList;
 import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /* This class is for the exclusive use of ProcessBuilder.start() to
  * create new processes.
@@ -145,6 +148,66 @@
 
     }
 
+    private static class LazyPattern {
+        // Escape-support version:
+        //    "(\")((?:\\\\\\1|.)+?)\\1|([^\\s\"]+)";
+        private static final Pattern PATTERN =
+            Pattern.compile("[^\\s\"]+|\"[^\"]*\"");
+    };
+
+    /* Parses the command string parameter into the executable name and
+     * program arguments.
+     *
+     * The command string is broken into tokens. The token separator is a space
+     * or quota character. The space inside quotation is not a token separator.
+     * There are no escape sequences.
+     */
+    private static String[] getTokensFromCommand(String command) {
+        ArrayList<String> matchList = new ArrayList<>(8);
+        Matcher regexMatcher = LazyPattern.PATTERN.matcher(command);
+        while (regexMatcher.find())
+            matchList.add(regexMatcher.group());
+        return matchList.toArray(new String[matchList.size()]);
+    }
+
+    private static String createCommandLine(boolean isCmdFile,
+                                     final String executablePath,
+                                     final String cmd[])
+    {
+        StringBuilder cmdbuf = new StringBuilder(80);
+
+        cmdbuf.append(executablePath);
+
+        for (int i = 1; i < cmd.length; ++i) {
+            cmdbuf.append(' ');
+            String s = cmd[i];
+            if (needsEscaping(isCmdFile, s)) {
+                cmdbuf.append('"');
+                cmdbuf.append(s);
+
+                // The code protects the [java.exe] and console command line
+                // parser, that interprets the [\"] combination as an escape
+                // sequence for the ["] char.
+                //     http://msdn.microsoft.com/en-us/library/17w5ykft.aspx
+                //
+                // If the argument is an FS path, doubling of the tail [\]
+                // char is not a problem for non-console applications.
+                //
+                // The [\"] sequence is not an escape sequence for the [cmd.exe]
+                // command line parser. The case of the [""] tail escape
+                // sequence could not be realized due to the argument validation
+                // procedure.
+                if (!isCmdFile && s.endsWith("\\")) {
+                    cmdbuf.append('\\');
+                }
+                cmdbuf.append('"');
+            } else {
+                cmdbuf.append(s);
+            }
+        }
+        return cmdbuf.toString();
+    }
+
     // We guarantee the only command file execution for implicit [cmd.exe] run.
     //    http://technet.microsoft.com/en-us/library/bb490954.aspx
     private static final char CMD_BAT_ESCAPE[] = {' ', '\t', '<', '>', '&', '|', '^'};
@@ -227,64 +290,89 @@
     }
 
 
+    private boolean isShellFile(String executablePath) {
+        String upPath = executablePath.toUpperCase();
+        return (upPath.endsWith(".CMD") || upPath.endsWith(".BAT"));
+    }
+
+    private String quoteString(String arg) {
+        StringBuilder argbuf = new StringBuilder(arg.length() + 2);
+        return argbuf.append('"').append(arg).append('"').toString();
+    }
+
+
     private long handle = 0;
     private OutputStream stdin_stream;
     private InputStream stdout_stream;
     private InputStream stderr_stream;
 
-    private ProcessImpl(final String cmd[],
+    private ProcessImpl(String cmd[],
                         final String envblock,
                         final String path,
                         final long[] stdHandles,
                         final boolean redirectErrorStream)
         throws IOException
     {
-        // The [executablePath] is not quoted for any case.
-        String executablePath = getExecutablePath(cmd[0]);
-
-        // We need to extend the argument verification procedure
-        // to guarantee the only command file execution for implicit [cmd.exe]
-        // run.
-        String upPath = executablePath.toUpperCase();
-        boolean isCmdFile = (upPath.endsWith(".CMD") || upPath.endsWith(".BAT"));
-
-        StringBuilder cmdbuf = new StringBuilder(80);
-
-        // Quotation protects from interpretation of the [path] argument as
-        // start of longer path with spaces. Quotation has no influence to
-        // [.exe] extension heuristic.
-        cmdbuf.append('"');
-        cmdbuf.append(executablePath);
-        cmdbuf.append('"');
-
-        for (int i = 1; i < cmd.length; i++) {
-            cmdbuf.append(' ');
-            String s = cmd[i];
-            if (needsEscaping(isCmdFile, s)) {
-                cmdbuf.append('"');
-                cmdbuf.append(s);
-
-                // The code protects the [java.exe] and console command line
-                // parser, that interprets the [\"] combination as an escape
-                // sequence for the ["] char.
-                //     http://msdn.microsoft.com/en-us/library/17w5ykft.aspx
-                //
-                // If the argument is an FS path, doubling of the tail [\]
-                // char is not a problem for non-console applications.
-                //
-                // The [\"] sequence is not an escape sequence for the [cmd.exe]
-                // command line parser. The case of the [""] tail escape
-                // sequence could not be realized due to the argument validation
-                // procedure.
-                if (!isCmdFile && s.endsWith("\\")) {
-                    cmdbuf.append('\\');
-                }
-                cmdbuf.append('"');
-            } else {
-                cmdbuf.append(s);
-            }
+        String cmdstr;
+        SecurityManager security = System.getSecurityManager();
+        boolean allowAmbigousCommands = false;
+        if (security == null) {
+            String value = System.getProperty("jdk.lang.Process.allowAmbigousCommands");
+            if (value != null)
+                allowAmbigousCommands = !"false".equalsIgnoreCase(value);
         }
-        String cmdstr = cmdbuf.toString();
+        if (allowAmbigousCommands) {
+            // Legacy mode.
+
+            // Normalize path if possible.
+            String executablePath = new File(cmd[0]).getPath();
+
+            // No worry about internal and unpaired ["] .
+            if (needsEscaping(false, executablePath) )
+                executablePath = quoteString(executablePath);
+
+            cmdstr = createCommandLine(
+                false, //legacy mode doesn't worry about extended verification
+                executablePath,
+                cmd);
+        } else {
+            String executablePath;
+            try {
+                executablePath = getExecutablePath(cmd[0]);
+            } catch (IllegalArgumentException e) {
+                // Workaround for the calls like
+                // Runtime.getRuntime().exec("\"C:\\Program Files\\foo\" bar")
+
+                // No chance to avoid CMD/BAT injection, except to do the work
+                // right from the beginning. Otherwise we have too many corner
+                // cases from
+                //    Runtime.getRuntime().exec(String[] cmd [, ...])
+                // calls with internal ["] and escape sequences.
+
+                // Restore original command line.
+                StringBuilder join = new StringBuilder();
+                // terminal space in command line is ok
+                for (String s : cmd)
+                    join.append(s).append(' ');
+
+                // Parse the command line again.
+                cmd = getTokensFromCommand(join.toString());
+                executablePath = getExecutablePath(cmd[0]);
+
+                // Check new executable name once more
+                if (security != null)
+                    security.checkExec(executablePath);
+            }
+
+            // Quotation protects from interpretation of the [path] argument as
+            // start of longer path with spaces. Quotation has no influence to
+            // [.exe] extension heuristic.
+            cmdstr = createCommandLine(
+                    // We need the extended verification procedure for CMD files.
+                    isShellFile(executablePath),
+                    quoteString(executablePath),
+                    cmd);
+        }
 
         handle = create(cmdstr, envblock, path,
                         stdHandles, redirectErrorStream);
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsFileCopy.java b/jdk/src/windows/classes/sun/nio/fs/WindowsFileCopy.java
index a8ffba1..0d975a3 100644
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileCopy.java
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileCopy.java
@@ -224,7 +224,7 @@
                 String linkTarget = WindowsLinkSupport.readLink(source);
                 int flags = SYMBOLIC_LINK_FLAG_DIRECTORY;
                 CreateSymbolicLink(targetPath,
-                                   addPrefixIfNeeded(linkTarget),
+                                   WindowsPath.addPrefixIfNeeded(linkTarget),
                                    flags);
             }
         } catch (WindowsException x) {
@@ -414,7 +414,7 @@
             } else {
                 String linkTarget = WindowsLinkSupport.readLink(source);
                 CreateSymbolicLink(targetPath,
-                                   addPrefixIfNeeded(linkTarget),
+                                   WindowsPath.addPrefixIfNeeded(linkTarget),
                                    SYMBOLIC_LINK_FLAG_DIRECTORY);
             }
         } catch (WindowsException x) {
@@ -502,18 +502,4 @@
             priv.drop();
         }
     }
-
-    /**
-     * Add long path prefix to path if required
-     */
-    private static String addPrefixIfNeeded(String path) {
-        if (path.length() > 248) {
-            if (path.startsWith("\\\\")) {
-                path = "\\\\?\\UNC" + path.substring(1, path.length());
-            } else {
-                path = "\\\\?\\" + path;
-            }
-        }
-        return path;
-    }
 }
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java b/jdk/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java
index 00bce62..ddc5b4b 100644
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java
@@ -231,7 +231,7 @@
             int end = (next == -1) ? path.length() : next;
             String search = sb.toString() + path.substring(curr, end);
             try {
-                FirstFile fileData = FindFirstFile(addLongPathPrefixIfNeeded(search));
+                FirstFile fileData = FindFirstFile(WindowsPath.addPrefixIfNeeded(search));
                 FindClose(fileData.handle());
 
                 // if a reparse point is encountered then we must return the
@@ -406,20 +406,6 @@
     }
 
     /**
-     * Add long path prefix to path if required.
-     */
-    private static String addLongPathPrefixIfNeeded(String path) {
-        if (path.length() > 248) {
-            if (path.startsWith("\\\\")) {
-                path = "\\\\?\\UNC" + path.substring(1, path.length());
-            } else {
-                path = "\\\\?\\" + path;
-            }
-        }
-        return path;
-    }
-
-    /**
      * Strip long path or symbolic link prefix from path
      */
     private static String stripPrefix(String path) {
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java b/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java
index e84db2a..ef597b3 100644
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java
@@ -283,7 +283,7 @@
 
     // Add long path prefix to path if required
     static String addPrefixIfNeeded(String path) {
-        if (path.length() > 248) {
+        if (path.length() > MAX_PATH) {
             if (path.startsWith("\\\\")) {
                 path = "\\\\?\\UNC" + path.substring(1, path.length());
             } else {
diff --git a/jdk/src/windows/native/sun/java2d/d3d/D3DBadHardware.h b/jdk/src/windows/native/sun/java2d/d3d/D3DBadHardware.h
index 5160b16..379a167 100644
--- a/jdk/src/windows/native/sun/java2d/d3d/D3DBadHardware.h
+++ b/jdk/src/windows/native/sun/java2d/d3d/D3DBadHardware.h
@@ -51,9 +51,105 @@
 
 static const ADAPTER_INFO badHardware[] = {
 
-    // any Intel chip
-    // Reason: workaround for 6620073, 6612195, 6620073
-    { 0x8086, ALL_DEVICEIDS, NO_VERSION, OS_ALL },
+    // Intel HD
+    // Clarkdale (Desktop) GMA HD Lines
+    { 0x8086, 0x0042, D_VERSION(6,14,10,5337), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x0042, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    // Arrandale (Mobile) GMA HD Lines
+    { 0x8086, 0x0046, D_VERSION(6,14,10,5337), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x0046, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    // Sandy Bridge GMA HD Lines
+    { 0x8086, 0x0102, D_VERSION(6,14,10,5337), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x0102, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    { 0x8086, 0x0106, D_VERSION(6,14,10,5337), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x0106, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    { 0x8086, 0x0112, D_VERSION(6,14,10,5337), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x0112, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    { 0x8086, 0x0116, D_VERSION(6,14,10,5337), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x0116, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    { 0x8086, 0x0122, D_VERSION(6,14,10,5337), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x0122, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    { 0x8086, 0x0126, D_VERSION(6,14,10,5337), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x0126, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    { 0x8086, 0x010A, D_VERSION(6,14,10,5337), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x010A, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+
+    // Reason: workaround for 6620073, 6612195
+    // Intel 740
+    { 0x8086, 0x7800, NO_VERSION, OS_ALL },
+    { 0x8086, 0x1240, NO_VERSION, OS_ALL },
+    { 0x8086, 0x7121, NO_VERSION, OS_ALL },
+    { 0x8086, 0x7123, NO_VERSION, OS_ALL },
+    { 0x8086, 0x7125, NO_VERSION, OS_ALL },
+    { 0x8086, 0x1132, NO_VERSION, OS_ALL },
+    // IEG
+    { 0x8086, 0x2562, NO_VERSION, OS_ALL },
+    { 0x8086, 0x3577, NO_VERSION, OS_ALL },
+    { 0x8086, 0x2572, NO_VERSION, OS_ALL },
+    { 0x8086, 0x3582, NO_VERSION, OS_ALL },
+    { 0x8086, 0x358E, NO_VERSION, OS_ALL },
+    // GMA
+    { 0x8086, 0x2582, NO_VERSION, OS_ALL },
+    { 0x8086, 0x2782, NO_VERSION, OS_ALL },
+    { 0x8086, 0x2592, NO_VERSION, OS_ALL },
+    { 0x8086, 0x2792, NO_VERSION, OS_ALL },
+    { 0x8086, 0x2772, NO_VERSION, OS_ALL },
+    { 0x8086, 0x2776, NO_VERSION, OS_ALL },
+    { 0x8086, 0x27A2, NO_VERSION, OS_ALL },
+    { 0x8086, 0x27A6, NO_VERSION, OS_ALL },
+    { 0x8086, 0x27AE, NO_VERSION, OS_ALL },
+    { 0x8086, 0x29D2, NO_VERSION, OS_ALL },
+    { 0x8086, 0x29D3, NO_VERSION, OS_ALL },
+    { 0x8086, 0x29B2, NO_VERSION, OS_ALL },
+    { 0x8086, 0x29B3, NO_VERSION, OS_ALL },
+    { 0x8086, 0x29C2, NO_VERSION, OS_ALL },
+    { 0x8086, 0x29C3, NO_VERSION, OS_ALL },
+    { 0x8086, 0xA001, NO_VERSION, OS_ALL },
+    { 0x8086, 0xA002, NO_VERSION, OS_ALL },
+    { 0x8086, 0xA011, NO_VERSION, OS_ALL },
+    { 0x8086, 0xA012, NO_VERSION, OS_ALL },
+    // GMA
+    { 0x8086, 0x2972, NO_VERSION, OS_ALL },
+    { 0x8086, 0x2973, NO_VERSION, OS_ALL },
+    { 0x8086, 0x2992, NO_VERSION, OS_ALL },
+    { 0x8086, 0x2993, NO_VERSION, OS_ALL },
+    { 0x8086, 0x29A2, NO_VERSION, OS_ALL },
+    { 0x8086, 0x29A3, NO_VERSION, OS_ALL },
+    { 0x8086, 0x2982, NO_VERSION, OS_ALL },
+    { 0x8086, 0x2983, NO_VERSION, OS_ALL },
+    { 0x8086, 0x2A02, NO_VERSION, OS_ALL },
+    { 0x8086, 0x2A03, NO_VERSION, OS_ALL },
+    { 0x8086, 0x2A12, NO_VERSION, OS_ALL },
+    { 0x8086, 0x2A13, NO_VERSION, OS_ALL },
+
+    // Eaglelake (Desktop) GMA 4500 Lines
+    { 0x8086, 0x2E42, D_VERSION(6,14,10,5303), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x2E42, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    { 0x8086, 0x2E43, D_VERSION(6,14,10,5303), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x2E43, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    { 0x8086, 0x2E92, D_VERSION(6,14,10,5303), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x2E92, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    { 0x8086, 0x2E93, D_VERSION(6,14,10,5303), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x2E93, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    { 0x8086, 0x2E12, D_VERSION(6,14,10,5303), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x2E12, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    { 0x8086, 0x2E13, D_VERSION(6,14,10,5303), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x2E13, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    // Eaglelake (Desktop) GMA X4500 Lines
+    { 0x8086, 0x2E32, D_VERSION(6,14,10,5303), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x2E32, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    { 0x8086, 0x2E33, D_VERSION(6,14,10,5303), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x2E33, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    { 0x8086, 0x2E22, D_VERSION(6,14,10,5303), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x2E22, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    // Eaglelake (Desktop) GMA X4500HD Lines
+    { 0x8086, 0x2E23, D_VERSION(6,14,10,5303), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x2E23, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    // Cantiga (Mobile) GMA 4500MHD Lines
+    { 0x8086, 0x2A42, D_VERSION(6,14,10,5303), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x2A42, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
+    { 0x8086, 0x2A43, D_VERSION(6,14,10,5303), OS_WINXP | OS_WINXP_64 },
+    { 0x8086, 0x2A43, D_VERSION(8,15,10,2302), OS_VISTA | OS_WINDOWS7 },
 
     // ATI Mobility Radeon X1600, X1400, X1450, X1300, X1350
     // Reason: workaround for 6613066, 6687166
diff --git a/jdk/test/Makefile b/jdk/test/Makefile
index 2edcc8f..51529b7 100644
--- a/jdk/test/Makefile
+++ b/jdk/test/Makefile
@@ -517,6 +517,7 @@
 	  javax/xml/soap \
 	  javax/xml/ws com/sun/internal/ws com/sun/org/glassfish \
 	  jdk/asm \
+	  jdk/lambda \
 	  com/sun/org/apache/xerces \
           com/sun/corba \
 	  com/sun/tracing \
diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt
index 68f7190..56967a8 100644
--- a/jdk/test/ProblemList.txt
+++ b/jdk/test/ProblemList.txt
@@ -131,9 +131,6 @@
 # 7067973
 java/lang/management/MemoryMXBean/CollectionUsageThreshold.java generic-all
 
-# 7148492
-java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java	generic-all
-
 # 7196801
 java/lang/management/MemoryMXBean/LowMemoryTest2.sh		generic-all
 
@@ -205,12 +202,17 @@
 # 7145658
 java/net/MulticastSocket/Test.java                               macosx-all
 
-#7143960
+# 7143960
 java/net/DatagramSocket/SendDatagramToBadAddress.java            macosx-all
 
-# 7150552
-sun/net/www/protocol/http/B6299712.java                         macosx-all
-java/net/CookieHandler/CookieManagerTest.java                   macosx-all
+# 8014720
+java/net/ResponseCache/B6181108.java                             generic-all
+
+# 8014723
+sun/misc/URLClassPath/ClassnameCharTest.java                     generic-all
+
+# 8014719
+sun/net/www/http/HttpClient/ProxyTest.java                       generic-all
 
 ############################################################################
 
diff --git a/jdk/test/com/sun/security/sasl/digest/AuthRealmChoices.java b/jdk/test/com/sun/security/sasl/digest/AuthRealmChoices.java
new file mode 100644
index 0000000..77422bd
--- /dev/null
+++ b/jdk/test/com/sun/security/sasl/digest/AuthRealmChoices.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8013855
+ * @run main AuthRealmChoices 1
+ * @run main AuthRealmChoices 2
+ * @summary DigestMD5Client has not checked RealmChoiceCallback value
+ */
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.sasl.*;
+
+public class AuthRealmChoices {
+    private static final String MECH = "DIGEST-MD5";
+    private static final String SERVER_FQDN = "machineX.imc.org";
+    private static final String PROTOCOL = "jmx";
+
+    private static final byte[] EMPTY = new byte[0];
+
+    public static void main(String[] args) throws Exception {
+
+        Map props = new HashMap();
+        props.put("com.sun.security.sasl.digest.realm",
+            "IMC.ORG foo.bar machineX");
+
+        SaslClient clnt = Sasl.createSaslClient(
+            new String[]{MECH}, null, PROTOCOL, SERVER_FQDN, null,
+                new CallbackHandler() {
+                    @Override
+                    public void handle(Callback[] callbacks)
+                            throws IOException, UnsupportedCallbackException {
+                        for (Callback cb: callbacks) {
+                            if (cb instanceof RealmChoiceCallback) {
+                                // Two tests:
+                                // 1. Set an index out of bound
+                                // 2. No index set at all
+                                if (args[0].equals("1")) {
+                                    ((RealmChoiceCallback)cb).setSelectedIndex(10);
+                                }
+                            }
+                        }
+                    }
+                });
+
+        SaslServer srv = Sasl.createSaslServer(MECH, PROTOCOL, SERVER_FQDN, props,
+            new CallbackHandler() {
+                @Override
+                public void handle(Callback[] callbacks)
+                        throws IOException, UnsupportedCallbackException {
+                    for (Callback cb: callbacks) {
+                        System.out.println(cb);
+                    }
+                }
+            });
+
+        byte[] challenge = srv.evaluateResponse(EMPTY);
+
+        try {
+            clnt.evaluateChallenge(challenge);
+            throw new Exception();
+        } catch (SaslException se) {
+            System.out.println(se);
+        }
+    }
+}
diff --git a/jdk/test/java/awt/LightweightDispatcher/LWDispatcherMemoryLeakTest.java b/jdk/test/java/awt/LightweightDispatcher/LWDispatcherMemoryLeakTest.java
new file mode 100644
index 0000000..706ae38
--- /dev/null
+++ b/jdk/test/java/awt/LightweightDispatcher/LWDispatcherMemoryLeakTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.AWTException;
+import java.awt.FlowLayout;
+import java.awt.Robot;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+import test.java.awt.regtesthelpers.Util;
+
+/*
+ @test
+ @bug 7079254
+ @summary Toolkit eventListener leaks memory
+ @library ../regtesthelpers
+ @build Util
+ @compile LWDispatcherMemoryLeakTest.java
+ @run main/othervm -Xmx10M LWDispatcherMemoryLeakTest
+ */
+public class LWDispatcherMemoryLeakTest {
+
+    private static JFrame frame;
+    private static WeakReference<JButton> button;
+    private static WeakReference<JPanel> p;
+
+    public static void init() throws Throwable {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame = new JFrame();
+                frame.setLayout(new FlowLayout());
+                button = new WeakReference<JButton>(new JButton("Text"));
+                p = new WeakReference<JPanel>(new JPanel(new FlowLayout()));
+                p.get().add(button.get());
+                frame.add(p.get());
+
+                frame.setBounds(500, 400, 200, 200);
+                frame.setVisible(true);
+            }
+        });
+
+        Util.waitTillShown(button.get());
+        Util.clickOnComp(button.get(), new Robot());
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame.remove(p.get());
+            }
+        });
+
+        Util.waitForIdle(null);
+        assertGC();
+    }
+
+    public static void assertGC() throws Throwable {
+        List<byte[]> alloc = new ArrayList<byte[]>();
+        int size = 10 * 1024;
+        while (true) {
+            try {
+                alloc.add(new byte[size]);
+            } catch (OutOfMemoryError err) {
+                break;
+            }
+        }
+        alloc = null;
+        if (button.get() != null) {
+            throw new Exception("Test failed: JButton was not collected");
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+        init();
+    }
+}
diff --git a/jdk/test/java/awt/TrayIcon/DragEventSource/DragEventSource.java b/jdk/test/java/awt/TrayIcon/DragEventSource/DragEventSource.java
index ddd0123..8a669c8 100644
--- a/jdk/test/java/awt/TrayIcon/DragEventSource/DragEventSource.java
+++ b/jdk/test/java/awt/TrayIcon/DragEventSource/DragEventSource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -64,6 +64,21 @@
     }
 
     private static void init() {
+
+        boolean isSupported = SystemTray.isSupported();
+        System.out.println("is SysTray Supported: " + isSupported);
+
+        if (!isSupported) {
+            String[] instructions =
+            {
+              "The test cannot be run because SystemTray is not supported.",
+              "Simply press PASS button."
+            };
+            Sysout.createDialog( );
+            Sysout.printInstructions( instructions );
+            return;
+        }
+
         String[] instructions =
         {
             "Use see a Frame with a button in it.",
@@ -79,8 +94,8 @@
 
         frame.setLayout(new FlowLayout());
         tray = SystemTray.getSystemTray();
-        boolean isSupported = tray.isSupported();
-        System.out.println("is SysTray Supported: " + isSupported);
+
+
         TrayIcon icons[] = tray.getTrayIcons();
         System.out.println(icons.length);
 
diff --git a/jdk/test/java/awt/datatransfer/HTMLDataFlavors/HTMLDataFlavorTest.java b/jdk/test/java/awt/datatransfer/HTMLDataFlavors/HTMLDataFlavorTest.java
index fa2206b..1fe616a 100644
--- a/jdk/test/java/awt/datatransfer/HTMLDataFlavors/HTMLDataFlavorTest.java
+++ b/jdk/test/java/awt/datatransfer/HTMLDataFlavors/HTMLDataFlavorTest.java
@@ -43,6 +43,11 @@
 
     public static void main(String[] args) throws IOException, UnsupportedFlavorException {
 
+        if (sun.awt.OSInfo.getOSType() != sun.awt.OSInfo.OSType.WINDOWS) {
+            System.err.println("This test is for MS Windows only. Considered passed.");
+            return;
+        }
+
         dataFlavors.put(DataFlavor.allHtmlFlavor, HtmlTransferable.ALL_HTML_AS_STRING);
         dataFlavors.put(DataFlavor.fragmentHtmlFlavor, HtmlTransferable.FRAGMENT_HTML_AS_STRING);
         dataFlavors.put(DataFlavor.selectionHtmlFlavor, HtmlTransferable.SELECTION_HTML_AS_STRING);
diff --git a/jdk/test/java/io/BufferedReader/Lines.java b/jdk/test/java/io/BufferedReader/Lines.java
new file mode 100644
index 0000000..2e83e1a
--- /dev/null
+++ b/jdk/test/java/io/BufferedReader/Lines.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8003258
+ * @run testng Lines
+ */
+
+import java.io.BufferedReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.LineNumberReader;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.stream.Stream;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+@Test(groups = "unit")
+public class Lines {
+    private static final Map<String, Integer> cases = new HashMap<>();
+
+    static {
+        cases.put("", 0);
+        cases.put("Line 1", 1);
+        cases.put("Line 1\n", 1);
+        cases.put("Line 1\n\n\n", 3);
+        cases.put("Line 1\nLine 2\nLine 3", 3);
+        cases.put("Line 1\nLine 2\nLine 3\n", 3);
+        cases.put("Line 1\n\nLine 3\n\nLine5", 5);
+    }
+
+    /**
+     * Helper Reader class which generate specified number of lines contents
+     * with each line will be "<code>Line &lt;line_number&gt;</code>".
+     *
+     * <p>This class also support to simulate {@link IOException} when read pass
+     * a specified line number.
+     */
+    private static class MockLineReader extends Reader {
+        final int line_count;
+        boolean closed = false;
+        int line_no = 0;
+        String line = null;
+        int pos = 0;
+        int inject_ioe_after_line;
+
+        MockLineReader(int cnt) {
+            this(cnt, cnt);
+        }
+
+        MockLineReader(int cnt, int inject_ioe) {
+            line_count = cnt;
+            inject_ioe_after_line = inject_ioe;
+        }
+
+        public void reset() {
+            synchronized(lock) {
+                line = null;
+                line_no = 0;
+                pos = 0;
+                closed = false;
+            }
+        }
+
+        public void inject_ioe() {
+            inject_ioe_after_line = line_no;
+        }
+
+        public int getLineNumber() {
+            synchronized(lock) {
+                return line_no;
+            }
+        }
+
+        @Override
+        public void close() {
+            closed = true;
+        }
+
+        @Override
+        public int read(char[] buf, int off, int len) throws IOException {
+            synchronized(lock) {
+                if (closed) {
+                    throw new IOException("Stream is closed.");
+                }
+
+                if (line == null) {
+                    if (line_count > line_no) {
+                        line_no += 1;
+                        if (line_no > inject_ioe_after_line) {
+                            throw new IOException("Failed to read line " + line_no);
+                        }
+                        line = "Line " + line_no + "\n";
+                        pos = 0;
+                    } else {
+                        return -1; // EOS reached
+                    }
+                }
+
+                int cnt = line.length() - pos;
+                assert(cnt != 0);
+                // try to fill with remaining
+                if (cnt >= len) {
+                    line.getChars(pos, pos + len, buf, off);
+                    pos += len;
+                    if (cnt == len) {
+                        assert(pos == line.length());
+                        line = null;
+                    }
+                    return len;
+                } else {
+                    line.getChars(pos, pos + cnt, buf, off);
+                    off += cnt;
+                    len -= cnt;
+                    line = null;
+                    /* hold for next read, so we won't IOE during fill buffer
+                    int more = read(buf, off, len);
+                    return (more == -1) ? cnt : cnt + more;
+                    */
+                    return cnt;
+                }
+            }
+        }
+    }
+
+    private static void verify(Map.Entry<String, Integer> e) {
+        final String data = e.getKey();
+        final int total_lines = e.getValue();
+        try (BufferedReader br = new BufferedReader(
+                                    new StringReader(data))) {
+            assertEquals(br.lines()
+                           .mapToInt(l -> 1).reduce(0, (x, y) -> x + y),
+                         total_lines,
+                         data + " should produce " + total_lines + " lines.");
+        } catch (IOException ioe) {
+            fail("Should not have any exception.");
+        }
+    }
+
+    public void testLinesBasic() {
+        // Basic test cases
+        cases.entrySet().stream().forEach(Lines::verify);
+        // Similar test, also verify MockLineReader is correct
+        for (int i = 0; i < 10; i++) {
+            try (BufferedReader br = new BufferedReader(new MockLineReader(i))) {
+                assertEquals(br.lines()
+                               .peek(l -> assertTrue(l.matches("^Line \\d+$")))
+                               .mapToInt(l -> 1).reduce(0, (x, y) -> x + y),
+                             i,
+                             "MockLineReader(" + i + ") should produce " + i + " lines.");
+            } catch (IOException ioe) {
+                fail("Unexpected IOException.");
+            }
+        }
+    }
+
+    public void testUncheckedIOException() throws IOException {
+        MockLineReader r = new MockLineReader(10, 3);
+        ArrayList<String> ar = new ArrayList<>();
+        try (BufferedReader br = new BufferedReader(r)) {
+            br.lines().limit(3L).forEach(ar::add);
+            assertEquals(ar.size(), 3, "Should be able to read 3 lines.");
+        } catch (UncheckedIOException uioe) {
+            fail("Unexpected UncheckedIOException");
+        }
+        r.reset();
+        try (BufferedReader br = new BufferedReader(r)) {
+            br.lines().forEach(ar::add);
+            fail("Should had thrown UncheckedIOException.");
+        } catch (UncheckedIOException uioe) {
+            assertEquals(r.getLineNumber(), 4, "should fail to read 4th line");
+            assertEquals(ar.size(), 6, "3 + 3 lines read");
+        }
+        for (int i = 0; i < ar.size(); i++) {
+            assertEquals(ar.get(i), "Line " + (i % 3 + 1));
+        }
+    }
+
+    public void testIterator() throws IOException {
+        MockLineReader r = new MockLineReader(6);
+        BufferedReader br = new BufferedReader(r);
+        String line = br.readLine();
+        assertEquals(r.getLineNumber(), 1, "Read one line");
+        Stream<String> s = br.lines();
+        Iterator<String> it = s.iterator();
+        // Ensure iterate with only next works
+        for (int i = 0; i < 5; i++) {
+            String str = it.next();
+            assertEquals(str, "Line " + (i + 2), "Addtional five lines");
+        }
+        // NoSuchElementException
+        try {
+            it.next();
+            fail("Should have run out of lines.");
+        } catch (NoSuchElementException nsse) {}
+    }
+
+    public void testPartialReadAndLineNo() throws IOException {
+        MockLineReader r = new MockLineReader(5);
+        LineNumberReader lr = new LineNumberReader(r);
+        char[] buf = new char[5];
+        lr.read(buf, 0, 5);
+        assertEquals(0, lr.getLineNumber(), "LineNumberReader start with line 0");
+        assertEquals(1, r.getLineNumber(), "MockLineReader start with line 1");
+        assertEquals(new String(buf), "Line ");
+        String l1 = lr.readLine();
+        assertEquals(l1, "1", "Remaining of the first line");
+        assertEquals(1, lr.getLineNumber(), "Line 1 is read");
+        assertEquals(1, r.getLineNumber(), "MockLineReader not yet go next line");
+        lr.read(buf, 0, 4);
+        assertEquals(1, lr.getLineNumber(), "In the middle of line 2");
+        assertEquals(new String(buf, 0, 4), "Line");
+        ArrayList<String> ar = lr.lines()
+             .peek(l -> assertEquals(lr.getLineNumber(), r.getLineNumber()))
+             .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
+        assertEquals(ar.get(0), " 2", "Remaining in the second line");
+        for (int i = 1; i < ar.size(); i++) {
+            assertEquals(ar.get(i), "Line " + (i + 2), "Rest are full lines");
+        }
+    }
+
+    public void testInterlacedRead() throws IOException {
+        MockLineReader r = new MockLineReader(10);
+        BufferedReader br = new BufferedReader(r);
+        char[] buf = new char[5];
+        Stream<String> s = br.lines();
+        Iterator<String> it = s.iterator();
+
+        br.read(buf);
+        assertEquals(new String(buf), "Line ");
+        assertEquals(it.next(), "1");
+        try {
+            s.iterator().next();
+            fail("Should failed on second attempt to get iterator from s");
+        } catch (IllegalStateException ise) {}
+        br.read(buf, 0, 2);
+        assertEquals(new String(buf, 0, 2), "Li");
+        // Get stream again should continue from where left
+        // Only read remaining of the line
+        br.lines().limit(1L).forEach(line -> assertEquals(line, "ne 2"));
+        br.read(buf, 0, 2);
+        assertEquals(new String(buf, 0, 2), "Li");
+        br.read(buf, 0, 2);
+        assertEquals(new String(buf, 0, 2), "ne");
+        assertEquals(it.next(), " 3");
+        // Line 4
+        br.readLine();
+        // interator pick
+        assertEquals(it.next(), "Line 5");
+        // Another stream instantiated by lines()
+        AtomicInteger line_no = new AtomicInteger(6);
+        br.lines().forEach(l -> assertEquals(l, "Line " + line_no.getAndIncrement()));
+        // Read after EOL
+        assertFalse(it.hasNext());
+    }
+}
diff --git a/jdk/test/java/io/File/NulFile.java b/jdk/test/java/io/File/NulFile.java
new file mode 100644
index 0000000..491f7e0
--- /dev/null
+++ b/jdk/test/java/io/File/NulFile.java
@@ -0,0 +1,625 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8003992
+ * @summary Test a file whose path name is embedded with NUL character, and
+ *          ensure it is handled correctly.
+ * @author Dan Xu
+ */
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.RandomAccessFile;
+import java.io.FileNotFoundException;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.nio.file.InvalidPathException;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectInputStream;
+
+public class NulFile {
+
+    private static final char CHAR_NUL = '\u0000';
+
+    private static final String ExceptionMsg = "Invalid file path";
+
+    public static void main(String[] args) {
+        testFile();
+        testFileInUnix();
+        testFileInWindows();
+        testTempFile();
+    }
+
+    private static void testFile() {
+        test(new File(new StringBuilder().append(CHAR_NUL).toString()));
+        test(new File(
+                new StringBuilder().append("").append(CHAR_NUL).toString()));
+        test(new File(
+                new StringBuilder().append(CHAR_NUL).append("").toString()));
+    }
+
+    private static void testFileInUnix() {
+        String osName = System.getProperty("os.name");
+        if (osName.startsWith("Windows"))
+            return;
+
+        String unixFile = "/";
+        test(unixFile);
+
+        unixFile = "//";
+        test(unixFile);
+
+        unixFile = "data/info";
+        test(unixFile);
+
+        unixFile = "/data/info";
+        test(unixFile);
+
+        unixFile = "//data//info";
+        test(unixFile);
+    }
+
+    private static void testFileInWindows() {
+        String osName = System.getProperty("os.name");
+        if (!osName.startsWith("Windows"))
+            return;
+
+        String windowsFile = "\\";
+        test(windowsFile);
+
+        windowsFile = "\\\\";
+        test(windowsFile);
+
+        windowsFile = "/";
+        test(windowsFile);
+
+        windowsFile = "//";
+        test(windowsFile);
+
+        windowsFile = "/\\";
+        test(windowsFile);
+
+        windowsFile = "\\/";
+        test(windowsFile);
+
+        windowsFile = "data\\info";
+        test(windowsFile);
+
+        windowsFile = "\\data\\info";
+        test(windowsFile);
+
+        windowsFile = "\\\\server\\data\\info";
+        test(windowsFile);
+
+        windowsFile = "z:data\\info";
+        test(windowsFile);
+
+        windowsFile = "z:\\data\\info";
+        test(windowsFile);
+    }
+
+    private static void test(final String name) {
+        int length = name.length();
+
+        for (int i = 0; i <= length; i++) {
+            StringBuilder sbName = new StringBuilder(name);
+            sbName.insert(i, CHAR_NUL);
+            String curName = sbName.toString();
+
+            // test File(String parent, String child)
+            File testFile = new File(curName, "child");
+            test(testFile);
+            testFile = new File("parent", curName);
+            test(testFile);
+
+            // test File(String pathname)
+            testFile = new File(curName);
+            test(testFile);
+
+            // test File(File parent, String child)
+            testFile = new File(new File(curName), "child");
+            test(testFile);
+            testFile = new File(new File("parent"), curName);
+            test(testFile);
+
+            // test FileInputStream
+            testFileInputStream(curName);
+
+            // test FileOutputStream
+            testFileOutputStream(curName);
+
+            // test RandomAccessFile
+            testRandomAccessFile(curName);
+        }
+    }
+
+    private static void testFileInputStream(final String str) {
+        boolean exceptionThrown = false;
+        FileInputStream is = null;
+        try {
+            is = new FileInputStream(str);
+        } catch (FileNotFoundException ex) {
+            if (ExceptionMsg.equals(ex.getMessage()))
+                exceptionThrown = true;
+        }
+        if (!exceptionThrown) {
+            throw new RuntimeException("FileInputStream constructor"
+                    + " should throw FileNotFoundException");
+        }
+        if (is != null) {
+            throw new RuntimeException("FileInputStream constructor"
+                    + " should fail");
+        }
+
+        exceptionThrown = false;
+        is = null;
+        try {
+            is = new FileInputStream(new File(str));
+        } catch (FileNotFoundException ex) {
+            if (ExceptionMsg.equals(ex.getMessage()))
+                exceptionThrown = true;
+        }
+        if (!exceptionThrown) {
+            throw new RuntimeException("FileInputStream constructor"
+                    + " should throw FileNotFoundException");
+        }
+        if (is != null) {
+            throw new RuntimeException("FileInputStream constructor"
+                    + " should fail");
+        }
+    }
+
+    private static void testFileOutputStream(final String str) {
+        boolean exceptionThrown = false;
+        FileOutputStream os = null;
+        try {
+            os = new FileOutputStream(str);
+        } catch (FileNotFoundException ex) {
+            if (ExceptionMsg.equals(ex.getMessage()))
+                exceptionThrown = true;
+        }
+        if (!exceptionThrown) {
+            throw new RuntimeException("FileOutputStream constructor"
+                    + " should throw FileNotFoundException");
+        }
+        if (os != null) {
+            throw new RuntimeException("FileOutputStream constructor"
+                    + " should fail");
+        }
+
+        exceptionThrown = false;
+        os = null;
+        try {
+            os = new FileOutputStream(new File(str));
+        } catch (FileNotFoundException ex) {
+            if (ExceptionMsg.equals(ex.getMessage()))
+                exceptionThrown = true;
+        }
+        if (!exceptionThrown) {
+            throw new RuntimeException("FileOutputStream constructor"
+                    + " should throw FileNotFoundException");
+        }
+        if (os != null) {
+            throw new RuntimeException("FileOutputStream constructor"
+                    + " should fail");
+        }
+    }
+
+    private static void testRandomAccessFile(final String str) {
+        boolean exceptionThrown = false;
+        RandomAccessFile raf = null;
+        String[] modes = {"r", "rw", "rws", "rwd"};
+
+        for (String mode : modes) {
+            try {
+                raf = new RandomAccessFile(str, mode);
+            } catch (FileNotFoundException ex) {
+                if (ExceptionMsg.equals(ex.getMessage()))
+                    exceptionThrown = true;
+            }
+            if (!exceptionThrown) {
+                throw new RuntimeException("RandomAccessFile constructor"
+                        + " should throw FileNotFoundException");
+            }
+            if (raf != null) {
+                throw new RuntimeException("RandomAccessFile constructor"
+                        + " should fail");
+            }
+
+            exceptionThrown = false;
+            raf = null;
+            try {
+                raf = new RandomAccessFile(new File(str), mode);
+            } catch (FileNotFoundException ex) {
+                if (ExceptionMsg.equals(ex.getMessage()))
+                    exceptionThrown = true;
+            }
+            if (!exceptionThrown) {
+                throw new RuntimeException("RandomAccessFile constructor"
+                        + " should throw FileNotFoundException");
+            }
+            if (raf != null) {
+                throw new RuntimeException("RandomAccessFile constructor"
+                        + " should fail");
+            }
+        }
+    }
+
+    private static void test(File testFile) {
+        test(testFile, false);
+        // test serialization
+        testSerialization(testFile);
+    }
+
+    @SuppressWarnings("deprecation")
+    private static void test(File testFile, boolean derived) {
+        boolean exceptionThrown = false;
+
+        if (testFile == null) {
+            throw new RuntimeException("test file should not be null.");
+        }
+
+        // getPath()
+        if (testFile.getPath().indexOf(CHAR_NUL) < 0) {
+            throw new RuntimeException(
+                    "File path should contain Nul character");
+        }
+        // getAbsolutePath()
+        if (testFile.getAbsolutePath().indexOf(CHAR_NUL) < 0) {
+            throw new RuntimeException(
+                    "File absolute path should contain Nul character");
+        }
+        // getAbsoluteFile()
+        File derivedAbsFile = testFile.getAbsoluteFile();
+        if (derived) {
+            if (derivedAbsFile.getPath().indexOf(CHAR_NUL) < 0) {
+                throw new RuntimeException(
+                        "Derived file path should also contain Nul character");
+            }
+        } else {
+            test(derivedAbsFile, true);
+        }
+        // getCanonicalPath()
+        try {
+            exceptionThrown = false;
+            testFile.getCanonicalPath();
+        } catch (IOException ex) {
+            if (ExceptionMsg.equals(ex.getMessage()))
+                exceptionThrown = true;
+        }
+        if (!exceptionThrown) {
+            throw new RuntimeException(
+                    "getCanonicalPath() should throw IOException with"
+                        + " message \"" + ExceptionMsg + "\"");
+        }
+        // getCanonicalFile()
+        try {
+            exceptionThrown = false;
+            testFile.getCanonicalFile();
+        } catch (IOException ex) {
+            if (ExceptionMsg.equals(ex.getMessage()))
+                exceptionThrown = true;
+        }
+        if (!exceptionThrown) {
+            throw new RuntimeException(
+                    "getCanonicalFile() should throw IOException with"
+                        + " message \"" + ExceptionMsg + "\"");
+        }
+        // toURL()
+        try {
+            exceptionThrown = false;
+            testFile.toURL();
+        } catch (MalformedURLException ex) {
+            if (ExceptionMsg.equals(ex.getMessage()))
+                exceptionThrown = true;
+        }
+        if (!exceptionThrown) {
+            throw new RuntimeException("toURL() should throw IOException with"
+                + " message \"" + ExceptionMsg + "\"");
+        }
+        // canRead()
+        if (testFile.canRead())
+            throw new RuntimeException("File should not be readable");
+        // canWrite()
+        if (testFile.canWrite())
+            throw new RuntimeException("File should not be writable");
+        // exists()
+        if (testFile.exists())
+            throw new RuntimeException("File should not be existed");
+        // isDirectory()
+        if (testFile.isDirectory())
+            throw new RuntimeException("File should not be a directory");
+        // isFile()
+        if (testFile.isFile())
+            throw new RuntimeException("File should not be a file");
+        // isHidden()
+        if (testFile.isHidden())
+            throw new RuntimeException("File should not be hidden");
+        // lastModified()
+        if (testFile.lastModified() != 0L)
+            throw new RuntimeException("File last modified time should be 0L");
+        // length()
+        if (testFile.length() != 0L)
+            throw new RuntimeException("File length should be 0L");
+        // createNewFile()
+        try {
+            exceptionThrown = false;
+            testFile.createNewFile();
+        } catch (IOException ex) {
+            if (ExceptionMsg.equals(ex.getMessage()))
+                exceptionThrown = true;
+        }
+        if (!exceptionThrown) {
+            throw new RuntimeException(
+                    "createNewFile() should throw IOException with"
+                        + " message \"" + ExceptionMsg + "\"");
+        }
+        // delete()
+        if (testFile.delete())
+            throw new RuntimeException("Delete operation should fail");
+        // list()
+        if (testFile.list() != null)
+            throw new RuntimeException("File list() should return null");
+        // list(FilenameFilter)
+        FilenameFilter fnFilter = new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+                return false;
+            }
+        };
+        if (testFile.list(fnFilter) != null) {
+            throw new RuntimeException("File list(FilenameFilter) should"
+                + " return null");
+        }
+        // listFiles()
+        if (testFile.listFiles() != null)
+            throw new RuntimeException("File listFiles() should return null");
+        // listFiles(FilenameFilter)
+        if (testFile.listFiles(fnFilter) != null) {
+            throw new RuntimeException("File listFiles(FilenameFilter)"
+                + " should return null");
+        }
+        // listFiles(FileFilter)
+        FileFilter fFilter = new FileFilter() {
+            @Override
+            public boolean accept(File file) {
+                return false;
+            }
+        };
+        if (testFile.listFiles(fFilter) != null) {
+            throw new RuntimeException("File listFiles(FileFilter)"
+                + " should return null");
+        }
+        // mkdir()
+        if (testFile.mkdir()) {
+            throw new RuntimeException("File should not be able to"
+                + " create directory");
+        }
+        // mkdirs()
+        if (testFile.mkdirs()) {
+            throw new RuntimeException("File should not be able to"
+                + " create directories");
+        }
+        // renameTo(File)
+        if (testFile.renameTo(new File("dest")))
+            throw new RuntimeException("File rename should fail");
+        if (new File("dest").renameTo(testFile))
+            throw new RuntimeException("File rename should fail");
+        try {
+            exceptionThrown = false;
+            testFile.renameTo(null);
+        } catch (NullPointerException ex) {
+            exceptionThrown = true;
+        }
+        if (!exceptionThrown) {
+            throw new RuntimeException("File rename should thrown NPE");
+        }
+        // setLastModified(long)
+        if (testFile.setLastModified(0L)) {
+            throw new RuntimeException("File should fail to set"
+                + " last modified time");
+        }
+        try {
+            exceptionThrown = false;
+            testFile.setLastModified(-1);
+        } catch (IllegalArgumentException ex) {
+            if ("Negative time".equals(ex.getMessage()))
+                exceptionThrown = true;
+        }
+        if (!exceptionThrown) {
+            throw new RuntimeException("File should fail to set"
+                + " last modified time with message \"Negative time\"");
+        }
+        // setReadOnly()
+        if (testFile.setReadOnly())
+            throw new RuntimeException("File should fail to set read-only");
+        // setWritable(boolean writable, boolean ownerOnly)
+        if (testFile.setWritable(true, true))
+            throw new RuntimeException("File should fail to set writable");
+        if (testFile.setWritable(true, false))
+            throw new RuntimeException("File should fail to set writable");
+        if (testFile.setWritable(false, true))
+            throw new RuntimeException("File should fail to set writable");
+        if (testFile.setWritable(false, false))
+            throw new RuntimeException("File should fail to set writable");
+        // setWritable(boolean writable)
+        if (testFile.setWritable(false))
+            throw new RuntimeException("File should fail to set writable");
+        if (testFile.setWritable(true))
+            throw new RuntimeException("File should fail to set writable");
+        // setReadable(boolean readable, boolean ownerOnly)
+        if (testFile.setReadable(true, true))
+            throw new RuntimeException("File should fail to set readable");
+        if (testFile.setReadable(true, false))
+            throw new RuntimeException("File should fail to set readable");
+        if (testFile.setReadable(false, true))
+            throw new RuntimeException("File should fail to set readable");
+        if (testFile.setReadable(false, false))
+            throw new RuntimeException("File should fail to set readable");
+        // setReadable(boolean readable)
+        if (testFile.setReadable(false))
+            throw new RuntimeException("File should fail to set readable");
+        if (testFile.setReadable(true))
+            throw new RuntimeException("File should fail to set readable");
+        // setExecutable(boolean executable, boolean ownerOnly)
+        if (testFile.setExecutable(true, true))
+            throw new RuntimeException("File should fail to set executable");
+        if (testFile.setExecutable(true, false))
+            throw new RuntimeException("File should fail to set executable");
+        if (testFile.setExecutable(false, true))
+            throw new RuntimeException("File should fail to set executable");
+        if (testFile.setExecutable(false, false))
+            throw new RuntimeException("File should fail to set executable");
+        // setExecutable(boolean executable)
+        if (testFile.setExecutable(false))
+            throw new RuntimeException("File should fail to set executable");
+        if (testFile.setExecutable(true))
+            throw new RuntimeException("File should fail to set executable");
+        // canExecute()
+        if (testFile.canExecute())
+            throw new RuntimeException("File should not be executable");
+        // getTotalSpace()
+        if (testFile.getTotalSpace() != 0L)
+            throw new RuntimeException("The total space should be 0L");
+        // getFreeSpace()
+        if (testFile.getFreeSpace() != 0L)
+            throw new RuntimeException("The free space should be 0L");
+        // getUsableSpace()
+        if (testFile.getUsableSpace() != 0L)
+            throw new RuntimeException("The usable space should be 0L");
+        // compareTo(File null)
+        try {
+            exceptionThrown = false;
+            testFile.compareTo(null);
+        } catch (NullPointerException ex) {
+            exceptionThrown = true;
+        }
+        if (!exceptionThrown) {
+            throw new RuntimeException("compareTo(null) should throw NPE");
+        }
+        // toString()
+        if (testFile.toString().indexOf(CHAR_NUL) < 0) {
+            throw new RuntimeException(
+                    "File path should contain Nul character");
+        }
+        // toPath()
+        try {
+            exceptionThrown = false;
+            testFile.toPath();
+        } catch (InvalidPathException ex) {
+            exceptionThrown = true;
+        }
+        if (!exceptionThrown) {
+            throw new RuntimeException("toPath() should throw"
+                + " InvalidPathException");
+        }
+    }
+
+    private static void testSerialization(File testFile) {
+        String path = testFile.getPath();
+        try {
+            // serialize test file
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+            oos.writeObject(testFile);
+            oos.close();
+            // deserialize test file
+            byte[] bytes = baos.toByteArray();
+            ByteArrayInputStream is = new ByteArrayInputStream(bytes);
+            ObjectInputStream ois = new ObjectInputStream(is);
+            File newFile = (File) ois.readObject();
+            // test
+            String newPath = newFile.getPath();
+            if (!path.equals(newPath)) {
+                throw new RuntimeException(
+                        "Serialization should not change file path");
+            }
+            test(newFile, false);
+        } catch (IOException | ClassNotFoundException ex) {
+            System.err.println("Exception happens in testSerialization");
+            System.err.println(ex.getMessage());
+        }
+    }
+
+    private static void testTempFile() {
+        final String[] names = {"x", "xx", "xxx", "xxxx"};
+        final String shortPrefix = "sp";
+        final String prefix = "prefix";
+        final String suffix = "suffix";
+        File tmpDir = new File("tmpDir");
+
+        for (String name : names) {
+            int length = name.length();
+            for (int i = 0; i <= length; i++) {
+                StringBuilder sbName = new StringBuilder(name);
+                sbName.insert(i, CHAR_NUL);
+                String curName = sbName.toString();
+
+                // test prefix
+                testCreateTempFile(curName, suffix, tmpDir);
+                // test suffix
+                testCreateTempFile(shortPrefix, curName, tmpDir);
+                testCreateTempFile(prefix, curName, tmpDir);
+                // test directory
+                testCreateTempFile(shortPrefix, suffix, new File(curName));
+                testCreateTempFile(prefix, suffix, new File(curName));
+            }
+        }
+    }
+
+    private static void testCreateTempFile(String prefix, String suffix,
+                                           File directory) {
+        // createTempFile(String prefix, String suffix, File directory)
+        boolean exceptionThrown = false;
+        boolean shortPrefix = (prefix.length() < 3);
+        if (shortPrefix) {
+            try {
+                File.createTempFile(prefix, suffix, directory);
+            } catch (IllegalArgumentException ex) {
+                if ("Prefix string too short".equals(ex.getMessage()))
+                    exceptionThrown = true;
+            } catch (IOException ioe) {
+                System.err.println("IOException happens in testCreateTempFile");
+                System.err.println(ioe.getMessage());
+            }
+        } else {
+            try {
+                File.createTempFile(prefix, suffix, directory);
+            } catch (IOException ex) {
+                if ("Unable to create temporary file".equals(ex.getMessage()))
+                    exceptionThrown = true;
+            }
+        }
+        if (!exceptionThrown) {
+            throw new RuntimeException("createTempFile() should throw"
+                    + (shortPrefix ? " IllegalArgumentException"
+                                   : " IOException"));
+        }
+    }
+}
diff --git a/jdk/test/java/lang/Math/DivModTests.java b/jdk/test/java/lang/Math/DivModTests.java
index 2cea8cb..fbd98e6 100644
--- a/jdk/test/java/lang/Math/DivModTests.java
+++ b/jdk/test/java/lang/Math/DivModTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -137,7 +137,8 @@
             int tmp = x / y;     // Force ArithmeticException for divide by zero
             double ff = x - Math.floor((double)x / (double)y) * y;
             int fr = (int)ff;
-            if (fr != result) {
+            boolean t = (fr == ((Integer)result));
+            if (!result.equals(fr)) {
                 fail("FAIL: Math.floorMod(%d, %d) = %s differs from Math.floor(x, y): %d%n", x, y, result, fr);
             }
         } catch (ArithmeticException ae) {
@@ -240,8 +241,8 @@
             resultD = resultD.multiply(yD);
             resultD = xD.subtract(resultD);
             long fr = resultD.longValue();
-            if (fr != result) {
-                fail("FAIL: Long.floorMod(%d, %d) = %d is different than BigDecimal result: %d%n",x, y, result, fr);
+            if (!result.equals(fr)) {
+                fail("FAIL: Long.floorMod(%d, %d) = %d is different than BigDecimal result: %d%n", x, y, result, fr);
 
             }
         } catch (ArithmeticException ae) {
diff --git a/jdk/test/java/lang/Runtime/exec/ExecCommand.java b/jdk/test/java/lang/Runtime/exec/ExecCommand.java
new file mode 100644
index 0000000..40f6173
--- /dev/null
+++ b/jdk/test/java/lang/Runtime/exec/ExecCommand.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/**
+ * @test
+ * @bug 8012453
+ * @run main/othervm ExecCommand
+ * @summary workaround for legacy applications with Runtime.getRuntime().exec(String command)
+ */
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.security.AccessControlException;
+
+public class ExecCommand {
+    static class SecurityMan extends SecurityManager {
+        public static String unquote(String str)
+        {
+            int length = (str == null)
+                ? 0
+                : str.length();
+
+            if (length > 1
+                && str.charAt(0) == '\"'
+                && str.charAt(length - 1) == '\"')
+            {
+               return str.substring(1, length - 1);
+            }
+            return str;
+        }
+
+        @Override public void checkExec(String cmd) {
+            String ncmd = (new File(unquote(cmd))).getPath();
+            if ( ncmd.equals(".\\Program")
+              || ncmd.equals("\".\\Program")
+              || ncmd.equals(".\\Program Files\\do.cmd")
+              || ncmd.equals(".\\Program.cmd"))
+            {
+                return;
+            }
+            super.checkExec(cmd);
+        }
+    }
+
+    // Parameters for the Runtime.exec calls
+    private static final String TEST_RTE_ARG[] = {
+        ".\\Program Files\\do.cmd",
+        "\".\\Program Files\\doNot.cmd\" arg",
+        "\".\\Program Files\\do.cmd\" arg",
+        // compatibility
+        "\".\\Program.cmd\" arg",
+        ".\\Program.cmd arg",
+    };
+
+    private static final String doCmdCopy[] = {
+        ".\\Program.cmd",
+        ".\\Program Files\\doNot.cmd",
+        ".\\Program Files\\do.cmd",
+    };
+
+    // Golden image for results
+    private static final String TEST_RTE_GI[][] = {
+                    //Pure system | Legacy mode | Legacy mode & SM
+        // [.\Program File\do.cmd]
+        new String[]{"IOException",  // [.\Program] not found
+                     "Success",
+                     "IOException"}, //SM - no legacy mode [.\Program] - OK
+
+        // [".\Program File\doNot.cmd" arg]
+        new String[]{"Success",
+                     "Success",
+                     "AccessControlException"}, //SM   - [".\Program] - OK,
+                                 //     [.\\Program Files\\doNot.cmd] - Fail
+
+        // [".\Program File\do.cmd" arg]
+        // AccessControlException
+        new String[]{"Success",
+                     "Success",
+                     "Success"}, //SM - [".\Program] - OK,
+                                 //     [.\\Program Files\\do.cmd] - OK
+
+        // compatibility
+        new String[]{"Success", "Success", "Success"}, //[".\Program.cmd"]
+        new String[]{"Success", "Success", "Success"}  //[.\Program.cmd]
+    };
+
+    public static void main(String[] _args) throws Exception {
+        if (!System.getProperty("os.name").startsWith("Windows")) {
+            return;
+        }
+
+        // tear up
+        try {
+            new File(".\\Program Files").mkdirs();
+            for (int i = 0; i < doCmdCopy.length; ++i) {
+                try (BufferedWriter outCmd = new BufferedWriter(
+                             new FileWriter(doCmdCopy[i]))) {
+                    outCmd.write("@echo %1");
+                }
+            }
+        } catch (IOException e) {
+            throw new Error(e.getMessage());
+        }
+
+        // action
+        for (int k = 0; k < 3; ++k) {
+            switch (k) {
+            case 1:
+                System.setProperty("jdk.lang.Process.allowAmbigousCommands", "");
+                break;
+            case 2:
+                System.setSecurityManager( new SecurityMan() );
+                break;
+            }
+            for (int i = 0; i < TEST_RTE_ARG.length; ++i) {
+                String outRes;
+                try {
+                    Process exec = Runtime.getRuntime().exec(TEST_RTE_ARG[i]);
+                    exec.waitFor();
+                    outRes = "Success";
+                } catch (IOException ioe) {
+                    outRes = "IOException: " + ioe.getMessage();
+                } catch (IllegalArgumentException iae) {
+                    outRes = "IllegalArgumentException: " + iae.getMessage();
+                } catch (AccessControlException se) {
+                    outRes = "AccessControlException: " + se.getMessage();
+                }
+
+                if (!outRes.startsWith(TEST_RTE_GI[i][k])) {
+                    throw new Error("Unexpected output! Step" + k + "" + i
+                                + " \nArgument: " + TEST_RTE_ARG[i]
+                                + "\nExpected: " + TEST_RTE_GI[i][k]
+                                + "\n  Output: " + outRes);
+                } else {
+                    System.out.println("RTE OK:" + TEST_RTE_ARG[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/jdk/test/java/lang/StringBuffer/ToStringCache.java b/jdk/test/java/lang/StringBuffer/ToStringCache.java
new file mode 100644
index 0000000..6259e27
--- /dev/null
+++ b/jdk/test/java/lang/StringBuffer/ToStringCache.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8013395
+ * @summary Test StringBuffer.toString caching
+ */
+
+public class ToStringCache {
+
+    // we can't test that we actually use a cached value (the benchmarks
+    // verify that) but we have to test that the cache is cleared when
+    // expected
+
+    public static void main(String[] args) throws Exception {
+        String original = "The original String";
+
+        StringBuffer sb = new StringBuffer(original);
+
+        String a = sb.toString();
+        checkEqual(a, original);
+
+        String b = sb.toString();
+        checkEqual(a, b);
+
+        // mutating methods
+
+        sb.setLength(12);
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.setCharAt(0, 'X');
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.append(new Character('X'));
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.append("More text");
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.append(sb);
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.append(new StringBuilder("Build"));
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.append(new StringBuilder("Build2"), 0, 1);
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.append(new char[] { 'a', 'b' });
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.append(true);
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.append('c');
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.append(23);
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.appendCodePoint(Character.codePointAt(new char[] { 'X'}, 0));
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.append(1L);
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.append(1.0f);
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.append(1.0d);
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.delete(0, 5);
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.deleteCharAt(0);
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.replace(0,2, "123");
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.insert(0, new char[] { 'a', 'b', 'c'}, 0, 3);
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.insert(0, new Object());
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.insert(0, "abc");
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.insert(0, new char[] { 'a', 'b', 'c' });
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.insert(0, new StringBuilder("Build"));
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.insert(0, new StringBuilder("Build"), 0, 1);
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.insert(0, false);
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.insert(0, 'X');
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.insert(0, 1);
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.insert(0, 1L);
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.insert(0, 1.0f);
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.insert(0, 1.0d);
+        b = sb.toString();
+        checkUnequal(a, b);
+        a = b;
+
+        sb.reverse();
+        b = sb.toString();
+        checkUnequal(a, b);
+
+        // non-mutating methods
+
+        // Reset to known value
+        sb = new StringBuffer(original);
+        a = sb.toString();
+        b = sb.toString();
+        checkEqual(a, b);
+
+        int l = sb.length();
+        b = sb.toString();
+        checkEqual(a, b);
+
+        int cap = sb.capacity();
+        b = sb.toString();
+        checkEqual(a, b);
+
+        sb.ensureCapacity(100);
+        b = sb.toString();
+        checkEqual(a, b);
+
+        sb.trimToSize();
+        b = sb.toString();
+        checkEqual(a, b);
+
+        char c = sb.charAt(1);
+        b = sb.toString();
+        checkEqual(a, b);
+
+        int cp = sb.codePointAt(1);
+        b = sb.toString();
+        checkEqual(a, b);
+
+        cp = sb.codePointBefore(2);
+        b = sb.toString();
+        checkEqual(a, b);
+
+        int count = sb.codePointCount(0,1);
+        b = sb.toString();
+        checkEqual(a, b);
+
+        count = sb.offsetByCodePoints(0, 1);
+        b = sb.toString();
+        checkEqual(a, b);
+
+        sb.getChars(0, 1, new char[2], 0);
+        b = sb.toString();
+        checkEqual(a, b);
+
+        String sub = sb.substring(0);
+        b = sb.toString();
+        checkEqual(a, b);
+
+        CharSequence cs = sb.subSequence(0,1);
+        b = sb.toString();
+        checkEqual(a, b);
+
+        sub = sb.substring(0, 3);
+        b = sb.toString();
+        checkEqual(a, b);
+
+        int index = sb.indexOf("rig");
+        b = sb.toString();
+        checkEqual(a, b);
+
+        index = sb.indexOf("rig", 2);
+        b = sb.toString();
+        checkEqual(a, b);
+
+        index = sb.lastIndexOf("rig");
+        b = sb.toString();
+        checkEqual(a, b);
+
+        index = sb.lastIndexOf("rig", 3);
+        b = sb.toString();
+        checkEqual(a, b);
+
+    }
+
+    private static void checkEqual(String s1, String s2) {
+        if (!s1.equals(s2))
+            throw new RuntimeException("Unmatched strings: s1 = "
+                                       + s1 + " s2 = " + s2);
+    }
+    private static void checkUnequal(String s1, String s2) {
+        if (s1.equals(s2))
+            throw new RuntimeException("Unexpected matched strings: " + s1);
+    }
+}
diff --git a/jdk/test/java/lang/Thread/GenerifyStackTraces.java b/jdk/test/java/lang/Thread/GenerifyStackTraces.java
index 6e26cd2..8fd63f7 100644
--- a/jdk/test/java/lang/Thread/GenerifyStackTraces.java
+++ b/jdk/test/java/lang/Thread/GenerifyStackTraces.java
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug     4919105
+ * @bug     4919105 8004177
  * @summary Generified basic unit test of Thread.getAllStackTraces()
  * @author  Mandy Chung
  */
@@ -33,7 +33,6 @@
 public class GenerifyStackTraces {
 
     private static Object go = new Object();
-    private static Object dumpObj = new Object();
     private static String[] methodNames = {"run", "A", "B", "C", "Done"};
     private static int DONE_DEPTH = 5;
     private static boolean testFailed = false;
@@ -48,19 +47,26 @@
         one = new ThreadOne();
         one.start();
 
-        Thread dt = new DumpThread();
-        dt.setDaemon(true);
+        DumpThread dt = new DumpThread();
         dt.start();
 
+        try {
+            one.join();
+        } finally {
+            dt.shutdown();
+        }
+
         if (testFailed) {
             throw new RuntimeException("Test Failed.");
         }
     }
 
     static class DumpThread extends Thread {
+        private volatile boolean finished = false;
+
         public void run() {
             int depth = 2;
-            while (true) {
+            while (!finished) {
                 // At each iterator, wait until ThreadOne blocks
                 // to wait for thread dump.
                 // Then dump stack trace and notify ThreadOne to continue.
@@ -75,6 +81,11 @@
                 }
             }
         }
+
+        public void shutdown() throws InterruptedException {
+            finished = true;
+            this.join();
+        }
     }
 
     static class ThreadOne extends Thread {
diff --git a/jdk/test/java/lang/Thread/StackTraces.java b/jdk/test/java/lang/Thread/StackTraces.java
deleted file mode 100644
index e7620b5..0000000
--- a/jdk/test/java/lang/Thread/StackTraces.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please 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     4593133
- * @summary Basic unit test of Thread.getStackTraces()
- * @author  Mandy Chung
- */
-
-import java.util.*;
-
-public class StackTraces {
-
-    private static Object go = new Object();
-    private static Object dumpObj = new Object();
-    private static String[] methodNames = {"run", "A", "B", "C", "Done"};
-    private static int DONE_DEPTH = 5;
-    private static boolean testFailed = false;
-
-    private static Thread one;
-    private static boolean trace = false;
-    public static void main(String[] args) throws Exception {
-        if (args.length > 0 && args[0].equals("trace")) {
-            trace = true;
-        }
-
-        one = new ThreadOne();
-        one.start();
-
-        Thread dt = new DumpThread();
-        dt.setDaemon(true);
-        dt.start();
-
-        if (testFailed) {
-            throw new RuntimeException("Test Failed.");
-        }
-    }
-
-    static class DumpThread extends Thread {
-        public void run() {
-            int depth = 2;
-            while (true) {
-                // At each iterator, wait until ThreadOne blocks
-                // to wait for thread dump.
-                // Then dump stack trace and notify ThreadOne to continue.
-                try {
-                    sleep(2000);
-                    dumpStacks(depth);
-                    depth++;
-                    finishDump();
-                } catch (Exception e) {
-                    e.printStackTrace();
-                    testFailed = true;
-                }
-            }
-        }
-    }
-
-    static class ThreadOne extends Thread {
-        public void run() {
-            A();
-        }
-        private void A() {
-            waitForDump();
-            B();
-        }
-        private void B() {
-            waitForDump();
-            C();
-        }
-        private void C() {
-            waitForDump();
-            Done();
-        }
-        private void Done() {
-            waitForDump();
-
-            // Get stack trace of current thread
-            StackTraceElement[] stack = getStackTrace();
-            try {
-                checkStack(this, stack, DONE_DEPTH);
-            } catch (Exception e) {
-                e.printStackTrace();
-                testFailed = true;
-            }
-        }
-
-    }
-
-
-    static private void waitForDump() {
-        synchronized(go) {
-            try {
-               go.wait();
-            } catch (Exception e) {
-               throw new RuntimeException("Unexpected exception" + e);
-            }
-        }
-    }
-
-    static private void finishDump() {
-        synchronized(go) {
-            try {
-               go.notifyAll();
-            } catch (Exception e) {
-               throw new RuntimeException("Unexpected exception" + e);
-            }
-        }
-    }
-
-    public static void dumpStacks(int depth) throws Exception {
-        // Get stack trace of another thread
-        StackTraceElement[] stack = one.getStackTrace();
-        checkStack(one, stack, depth);
-
-        // Get stack traces of all Threads
-        Map m = Thread.getAllStackTraces();
-        Set s = m.entrySet();
-        Iterator iter = s.iterator();
-
-        Map.Entry entry;
-        while (iter.hasNext()) {
-            entry = (Map.Entry) iter.next();
-            Thread t = (Thread) entry.getKey();
-            stack = (StackTraceElement[]) entry.getValue();
-            if (t == null || stack == null) {
-               throw new RuntimeException("Null thread or stacktrace returned");
-            }
-            if (t == one) {
-                checkStack(t, stack, depth);
-            }
-        }
-    }
-
-    private static void checkStack(Thread t, StackTraceElement[] stack,
-                                   int depth) throws Exception {
-        if (trace) {
-            printStack(t, stack);
-        }
-        int frame = stack.length - 1;
-        for (int i = 0; i < depth && frame >= 0; i++) {
-            if (! stack[frame].getMethodName().equals(methodNames[i])) {
-                throw new RuntimeException("Expected " + methodNames[i] +
-                                           " in frame " + frame + " but got " +
-                                           stack[frame].getMethodName());
-            }
-            frame--;
-        }
-    }
-
-    private static void printStack(Thread t, StackTraceElement[] stack) {
-        System.out.println(t +
-                           " stack: (length = " + stack.length + ")");
-        if (t != null) {
-            for (int j = 0; j < stack.length; j++) {
-                System.out.println(stack[j]);
-            }
-            System.out.println();
-        }
-    }
-}
diff --git a/jdk/test/java/lang/annotation/TypeAnnotationReflection.java b/jdk/test/java/lang/annotation/TypeAnnotationReflection.java
index b3aad97..6b4d167 100644
--- a/jdk/test/java/lang/annotation/TypeAnnotationReflection.java
+++ b/jdk/test/java/lang/annotation/TypeAnnotationReflection.java
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8004698
+ * @bug 8004698 8007073
  * @summary Unit test for type annotations
  */
 
@@ -48,6 +48,8 @@
         testParameterizedType();
         testNestedParameterizedType();
         testWildcardType();
+        testParameterTypes();
+        testParameterType();
     }
 
     private static void check(boolean b) {
@@ -359,6 +361,154 @@
         t = w.getAnnotatedLowerBounds();
         check(t.length == 1);
     }
+
+    private static void testParameterTypes() throws Exception {
+        // NO PARAMS
+        Method m = Params.class.getDeclaredMethod("noParams", (Class<?>[])null);
+        AnnotatedType[] t = m.getAnnotatedParameterTypes();
+        check(t.length == 0);
+
+        // ONLY ANNOTATED PARAM TYPES
+        Class[] argsArr = {String.class, String.class, String.class};
+        m = Params.class.getDeclaredMethod("onlyAnnotated", (Class<?>[])argsArr);
+        t = m.getAnnotatedParameterTypes();
+        check(t.length == 3);
+
+        check(t[0].getAnnotations().length == 1);
+        check(t[0].getAnnotation(TypeAnno.class) != null);
+        check(t[0].getAnnotationsByType(TypeAnno.class)[0].value().equals("1"));
+
+        check(t[1].getAnnotations().length == 1);
+        check(t[1].getAnnotation(TypeAnno.class) != null);
+        check(t[1].getAnnotationsByType(TypeAnno.class)[0].value().equals("2"));
+
+        check(t[2].getAnnotations().length == 2);
+        check(t[2].getAnnotations()[0].annotationType().equals(TypeAnno.class));
+        check(t[2].getAnnotation(TypeAnno.class) != null);
+        check(t[2].getAnnotation(TypeAnno2.class) != null);
+        check(t[2].getAnnotationsByType(TypeAnno.class)[0].value().equals("3a"));
+        check(t[2].getAnnotationsByType(TypeAnno2.class)[0].value().equals("3b"));
+
+        // MIXED ANNOTATED PARAM TYPES
+        m = Params.class.getDeclaredMethod("mixed", (Class<?>[])argsArr);
+        t = m.getAnnotatedParameterTypes();
+        check(t.length == 3);
+
+        check(t[0].getAnnotations().length == 1);
+        check(t[0].getAnnotation(TypeAnno.class) != null);
+        check(t[0].getAnnotationsByType(TypeAnno.class)[0].value().equals("1"));
+
+        check(t[1].getAnnotations().length == 0);
+        check(t[1].getAnnotation(TypeAnno.class) == null);
+        check(t[1].getAnnotation(TypeAnno2.class) == null);
+
+        check(t[2].getAnnotations().length == 2);
+        check(t[2].getAnnotations()[0].annotationType().equals(TypeAnno.class));
+        check(t[2].getAnnotation(TypeAnno.class) != null);
+        check(t[2].getAnnotation(TypeAnno2.class) != null);
+        check(t[2].getAnnotationsByType(TypeAnno.class)[0].value().equals("3a"));
+        check(t[2].getAnnotationsByType(TypeAnno2.class)[0].value().equals("3b"));
+
+        // NO ANNOTATED PARAM TYPES
+        m = Params.class.getDeclaredMethod("unAnnotated", (Class<?>[])argsArr);
+        t = m.getAnnotatedParameterTypes();
+        check(t.length == 3);
+
+        check(t[0].getAnnotations().length == 0);
+        check(t[0].getAnnotation(TypeAnno.class) == null);
+        check(t[0].getAnnotation(TypeAnno2.class) == null);
+
+        check(t[1].getAnnotations().length == 0);
+        check(t[1].getAnnotation(TypeAnno.class) == null);
+        check(t[1].getAnnotation(TypeAnno2.class) == null);
+
+        check(t[2].getAnnotations().length == 0);
+        check(t[2].getAnnotation(TypeAnno.class) == null);
+        check(t[2].getAnnotation(TypeAnno2.class) == null);
+    }
+
+    private static void testParameterType() throws Exception {
+        // NO PARAMS
+        Method m = Params.class.getDeclaredMethod("noParams", (Class<?>[])null);
+        Parameter[] p = m.getParameters();
+        check(p.length == 0);
+
+        // ONLY ANNOTATED PARAM TYPES
+        Class[] argsArr = {String.class, String.class, String.class};
+        m = Params.class.getDeclaredMethod("onlyAnnotated", (Class<?>[])argsArr);
+        p = m.getParameters();
+        check(p.length == 3);
+        AnnotatedType t0 = p[0].getAnnotatedType();
+        AnnotatedType t1 = p[1].getAnnotatedType();
+        AnnotatedType t2 = p[2].getAnnotatedType();
+
+        check(t0.getAnnotations().length == 1);
+        check(t0.getAnnotation(TypeAnno.class) != null);
+        check(t0.getAnnotationsByType(TypeAnno.class)[0].value().equals("1"));
+
+        check(t1.getAnnotations().length == 1);
+        check(t1.getAnnotation(TypeAnno.class) != null);
+        check(t1.getAnnotationsByType(TypeAnno.class)[0].value().equals("2"));
+
+        check(t2.getAnnotations().length == 2);
+        check(t2.getAnnotations()[0].annotationType().equals(TypeAnno.class));
+        check(t2.getAnnotation(TypeAnno.class) != null);
+        check(t2.getAnnotation(TypeAnno2.class) != null);
+        check(t2.getAnnotationsByType(TypeAnno.class)[0].value().equals("3a"));
+        check(t2.getAnnotationsByType(TypeAnno2.class)[0].value().equals("3b"));
+
+        // MIXED ANNOTATED PARAM TYPES
+        m = Params.class.getDeclaredMethod("mixed", (Class<?>[])argsArr);
+        p = m.getParameters();
+        check(p.length == 3);
+
+        t0 = p[0].getAnnotatedType();
+        t1 = p[1].getAnnotatedType();
+        t2 = p[2].getAnnotatedType();
+
+        check(t0.getAnnotations().length == 1);
+        check(t0.getAnnotation(TypeAnno.class) != null);
+        check(t0.getAnnotationsByType(TypeAnno.class)[0].value().equals("1"));
+
+        check(t1.getAnnotations().length == 0);
+        check(t1.getAnnotation(TypeAnno.class) == null);
+        check(t1.getAnnotation(TypeAnno2.class) == null);
+
+        check(t2.getAnnotations().length == 2);
+        check(t2.getAnnotations()[0].annotationType().equals(TypeAnno.class));
+        check(t2.getAnnotation(TypeAnno.class) != null);
+        check(t2.getAnnotation(TypeAnno2.class) != null);
+        check(t2.getAnnotationsByType(TypeAnno.class)[0].value().equals("3a"));
+        check(t2.getAnnotationsByType(TypeAnno2.class)[0].value().equals("3b"));
+
+        // NO ANNOTATED PARAM TYPES
+        m = Params.class.getDeclaredMethod("unAnnotated", (Class<?>[])argsArr);
+        p = m.getParameters();
+        check(p.length == 3);
+
+        t0 = p[0].getAnnotatedType();
+        t1 = p[1].getAnnotatedType();
+        t2 = p[2].getAnnotatedType();
+
+        check(t0.getAnnotations().length == 0);
+        check(t0.getAnnotation(TypeAnno.class) == null);
+        check(t0.getAnnotation(TypeAnno2.class) == null);
+
+        check(t1.getAnnotations().length == 0);
+        check(t1.getAnnotation(TypeAnno.class) == null);
+        check(t1.getAnnotation(TypeAnno2.class) == null);
+
+        check(t2.getAnnotations().length == 0);
+        check(t2.getAnnotation(TypeAnno.class) == null);
+        check(t2.getAnnotation(TypeAnno2.class) == null);
+    }
+}
+
+class Params {
+    public void noParams() {}
+    public void onlyAnnotated(@TypeAnno("1") String s1, @TypeAnno("2") String s2, @TypeAnno("3a") @TypeAnno2("3b") String s3) {}
+    public void mixed(@TypeAnno("1") String s1, String s2, @TypeAnno("3a") @TypeAnno2("3b") String s3) {}
+    public void unAnnotated(String s1, String s2, String s3) {}
 }
 
 abstract class TestWildcardType {
diff --git a/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java b/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java
index 9acfa7b..6b02397 100644
--- a/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java
+++ b/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java
@@ -28,7 +28,10 @@
  * @author  Mandy Chung
  *
  * @build ResetPeakMemoryUsage MemoryUtil
- * @run main/othervm ResetPeakMemoryUsage
+ * @run main/othervm -XX:+UseSerialGC -Xmn8m ResetPeakMemoryUsage
+ * @run main/othervm -XX:+UseConcMarkSweepGC -Xmn8m ResetPeakMemoryUsage
+ * @run main/othervm -XX:+UseParallelGC -Xmn8m ResetPeakMemoryUsage
+ * @run main/othervm -XX:+UseG1GC -Xmn8m -XX:G1HeapRegionSize=1m ResetPeakMemoryUsage
  */
 
 import java.lang.management.*;
@@ -36,52 +39,62 @@
 
 public class ResetPeakMemoryUsage {
     private static MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
-    private static List pools = ManagementFactory.getMemoryPoolMXBeans();
-    private static MemoryPoolMXBean mpool = null;
+    // make public so that it can't be optimized away easily
+    public static Object[] obj;
 
     public static void main(String[] argv) {
+        List pools = ManagementFactory.getMemoryPoolMXBeans();
         ListIterator iter = pools.listIterator();
+        boolean found = false;
         while (iter.hasNext()) {
             MemoryPoolMXBean p = (MemoryPoolMXBean) iter.next();
+            // only check heap pools that support usage threshold
+            // this is typically only the old generation space
+            // since the other spaces are expected to get filled up
             if (p.getType() == MemoryType.HEAP &&
-                    p.isUsageThresholdSupported()) {
-                mpool = p;
-                System.out.println("Selected memory pool: ");
-                MemoryUtil.printMemoryPool(mpool);
-                break;
+                p.isUsageThresholdSupported())
+            {
+                found = true;
+                testPool(p);
             }
         }
-        if (mpool == null) {
-            throw new RuntimeException("No heap pool found with threshold != -1");
+        if (!found) {
+            throw new RuntimeException("No heap pool found");
         }
+    }
+
+    private static void testPool(MemoryPoolMXBean mpool) {
+        System.out.println("Selected memory pool: ");
+        MemoryUtil.printMemoryPool(mpool);
 
         MemoryUsage usage0 = mpool.getUsage();
         MemoryUsage peak0 = mpool.getPeakUsage();
-        final long largeArraySize = (usage0.getMax() - usage0.getUsed()) / 10;
 
-        System.out.println("Before big object is allocated: ");
-        printMemoryUsage();
+        // use a size that is larger than the young generation and G1 regions
+        // to force the array into the old gen
+        int largeArraySize = 9 * 1000 * 1000;
 
-        // Allocate a big array - need to allocate from the old gen
-        Object[][][] obj = new Object[1][1][(int) largeArraySize];
+        System.out.println("Before big object array (of size "+largeArraySize+") is allocated: ");
+        printMemoryUsage(usage0, peak0);
 
-        System.out.println("After the object is allocated: ");
-        printMemoryUsage();
+        obj = new Object[largeArraySize];
 
         MemoryUsage usage1 = mpool.getUsage();
         MemoryUsage peak1 = mpool.getPeakUsage();
+        System.out.println("After the object is allocated: ");
+        printMemoryUsage(usage1, peak1);
 
         if (usage1.getUsed() <= usage0.getUsed()) {
             throw new RuntimeException(
                 formatSize("Before allocation: used", usage0.getUsed()) +
-                " expected to be > " +
+                " expected to be < " +
                 formatSize("After allocation: used", usage1.getUsed()));
         }
 
         if (peak1.getUsed() <= peak0.getUsed()) {
             throw new RuntimeException(
                 formatSize("Before allocation: peak", peak0.getUsed()) +
-                " expected to be > " +
+                " expected to be < " +
                 formatSize("After allocation: peak", peak1.getUsed()));
         }
 
@@ -91,11 +104,10 @@
         obj = null;
         mbean.gc();
 
-        System.out.println("After GC: ");
-        printMemoryUsage();
-
         MemoryUsage usage2 = mpool.getUsage();
         MemoryUsage peak2 = mpool.getPeakUsage();
+        System.out.println("After GC: ");
+        printMemoryUsage(usage2, peak2);
 
         if (usage2.getUsed() >= usage1.getUsed()) {
             throw new RuntimeException(
@@ -104,20 +116,12 @@
                 formatSize("After GC: used", usage2.getUsed()));
         }
 
-        if (peak2.getUsed() != peak1.getUsed()) {
-            throw new RuntimeException(
-                formatSize("Before GC: peak", peak1.getUsed()) + " " +
-                " expected to be equal to " +
-                formatSize("After GC: peak", peak2.getUsed()));
-        }
-
         mpool.resetPeakUsage();
 
-        System.out.println("After resetPeakUsage: ");
-        printMemoryUsage();
-
         MemoryUsage usage3 = mpool.getUsage();
         MemoryUsage peak3 = mpool.getPeakUsage();
+        System.out.println("After resetPeakUsage: ");
+        printMemoryUsage(usage3, peak3);
 
         if (peak3.getUsed() != usage3.getUsed()) {
             throw new RuntimeException(
@@ -137,9 +141,7 @@
     }
 
     private static String INDENT = "    ";
-    private static void printMemoryUsage() {
-        MemoryUsage current = mpool.getUsage();
-        MemoryUsage peak = mpool.getPeakUsage();
+    private static void printMemoryUsage(MemoryUsage current, MemoryUsage peak) {
         System.out.println("Current Usage: ");
         MemoryUtil.printMemoryUsage(current);
         System.out.println("Peak Usage: ");
diff --git a/jdk/test/java/lang/reflect/Proxy/Basic1.java b/jdk/test/java/lang/reflect/Proxy/Basic1.java
index b160f5d..726cc96 100644
--- a/jdk/test/java/lang/reflect/Proxy/Basic1.java
+++ b/jdk/test/java/lang/reflect/Proxy/Basic1.java
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 4227192
+ * @bug 4227192 4487672
  * @summary This is a basic functional test of the dynamic proxy API (part 1).
  * @author Peter Jones
  *
@@ -42,15 +42,15 @@
             "\nBasic functional test of dynamic proxy API, part 1\n");
 
         try {
-            Class[] interfaces =
-                new Class[] { Runnable.class, Observer.class };
+            Class<?>[] interfaces =
+                new Class<?>[] { Runnable.class, Observer.class };
 
             ClassLoader loader = ClassLoader.getSystemClassLoader();
 
             /*
              * Generate a proxy class.
              */
-            Class proxyClass = Proxy.getProxyClass(loader, interfaces);
+            Class<?> proxyClass = Proxy.getProxyClass(loader, interfaces);
             System.err.println("+ generated proxy class: " + proxyClass);
 
             /*
@@ -72,19 +72,19 @@
             /*
              * Verify that it is assignable to the proxy interfaces.
              */
-            for (int i = 0; i < interfaces.length; i++) {
-                if (!interfaces[i].isAssignableFrom(proxyClass)) {
+            for (Class<?> intf : interfaces) {
+                if (!intf.isAssignableFrom(proxyClass)) {
                     throw new RuntimeException(
                         "proxy class not assignable to proxy interface " +
-                        interfaces[i].getName());
+                        intf.getName());
                 }
             }
 
             /*
              * Verify that it has the given permutation of interfaces.
              */
-            List l1 = Arrays.asList(interfaces);
-            List l2 = Arrays.asList(proxyClass.getInterfaces());
+            List<Class<?>> l1 = Arrays.asList(interfaces);
+            List<Class<?>> l2 = Arrays.asList(proxyClass.getInterfaces());
             System.err.println("+ proxy class's interfaces: " + l2);
             if (!l1.equals(l2)) {
                 throw new RuntimeException(
@@ -118,14 +118,26 @@
              * Verify that it has a constructor that takes an
              * InvocationHandler instance.
              */
-            Constructor cons = proxyClass.getConstructor(
-                new Class[] { InvocationHandler.class });
+            Constructor<?> cons = proxyClass.getConstructor(InvocationHandler.class);
+
+            /*
+             * Test constructor with null InvocationHandler
+             */
+            try {
+                cons.newInstance(new Object[] { null });
+                throw new RuntimeException("Expected NullPointerException thrown");
+            } catch (InvocationTargetException e) {
+                Throwable t = e.getTargetException();
+                if (!(t instanceof NullPointerException)) {
+                    throw t;
+                }
+            }
 
             /*
              * Construct a proxy instance.
              */
             Handler handler = new Handler();
-            Object proxy = cons.newInstance(new Object[] { handler });
+            Object proxy = cons.newInstance(handler);
             handler.currentProxy = proxy;
 
             /*
@@ -141,7 +153,7 @@
 
             System.err.println("\nTEST PASSED");
 
-        } catch (Exception e) {
+        } catch (Throwable e) {
             System.err.println("\nTEST FAILED:");
             e.printStackTrace();
             throw new RuntimeException("TEST FAILED: " + e.toString());
diff --git a/jdk/test/java/net/CookieHandler/CookieManagerTest.java b/jdk/test/java/net/CookieHandler/CookieManagerTest.java
index f3d5b7a..a59a0a3 100644
--- a/jdk/test/java/net/CookieHandler/CookieManagerTest.java
+++ b/jdk/test/java/net/CookieHandler/CookieManagerTest.java
@@ -24,21 +24,25 @@
 /*
  * @test
  * @summary Unit test for java.net.CookieManager
- * @bug 6244040
- * @library ../../../sun/net/www/httptest/
- * @build HttpCallback TestHttpServer ClosedChannelList HttpTransaction
+ * @bug 6244040 7150552
  * @run main/othervm -ea CookieManagerTest
  * @author Edward Wang
  */
 
-import java.net.*;
-import java.util.*;
-import java.io.*;
-import sun.net.www.MessageHeader;
+import com.sun.net.httpserver.*;
+import java.io.IOException;
+import java.net.CookieHandler;
+import java.net.CookieManager;
+import java.net.CookiePolicy;
+import java.net.HttpURLConnection;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.URL;
 
 public class CookieManagerTest {
-    static CookieHttpTransaction httpTrans;
-    static TestHttpServer server;
+
+    static CookieTransactionHandler httpTrans;
+    static HttpServer server;
 
     public static void main(String[] args) throws Exception {
         startHttpServer();
@@ -49,41 +53,48 @@
         }
     }
 
-    public static void startHttpServer() {
-        try {
-            httpTrans = new CookieHttpTransaction();
-            server = new TestHttpServer(httpTrans, 1, 1, 0);
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
+    public static void startHttpServer() throws IOException {
+        httpTrans = new CookieTransactionHandler();
+        server = HttpServer.create(new InetSocketAddress(0), 0);
+        server.createContext("/", httpTrans);
+        server.start();
     }
 
-    public static void makeHttpCall() {
+    public static void makeHttpCall() throws IOException {
         try {
-            System.out.println("http server listen on: " + server.getLocalPort());
+            System.out.println("http server listenining on: "
+                    + server.getAddress().getPort());
 
             // install CookieManager to use
             CookieHandler.setDefault(new CookieManager());
 
-            for (int i = 0; i < CookieHttpTransaction.testCount; i++) {
-                System.out.println("====== CookieManager test " + (i+1) + " ======");
-                ((CookieManager)CookieHandler.getDefault()).setCookiePolicy(CookieHttpTransaction.testPolicies[i]);
-                ((CookieManager)CookieHandler.getDefault()).getCookieStore().removeAll();
-                URL url = new URL("http" , InetAddress.getLocalHost().getHostAddress(),
-                                    server.getLocalPort(), CookieHttpTransaction.testCases[i][0].serverPath);
+            for (int i = 0; i < CookieTransactionHandler.testCount; i++) {
+                System.out.println("====== CookieManager test " + (i+1)
+                                    + " ======");
+                ((CookieManager)CookieHandler.getDefault())
+                    .setCookiePolicy(CookieTransactionHandler.testPolicies[i]);
+                ((CookieManager)CookieHandler.getDefault())
+                    .getCookieStore().removeAll();
+                URL url = new URL("http" ,
+                                  InetAddress.getLocalHost().getHostAddress(),
+                                  server.getAddress().getPort(),
+                                  CookieTransactionHandler.testCases[i][0]
+                                                          .serverPath);
                 HttpURLConnection uc = (HttpURLConnection)url.openConnection();
                 uc.getResponseCode();
                 uc.disconnect();
             }
-        } catch (IOException e) {
-            e.printStackTrace();
         } finally {
-            server.terminate();
+            server.stop(0);
         }
     }
 }
 
-class CookieHttpTransaction implements HttpCallback {
+class CookieTransactionHandler implements HttpHandler {
+
+    private int testcaseDone = 0;
+    private int testDone = 0;
+
     public static boolean badRequest = false;
     // the main test control logic will also loop exactly this number
     // to send http request
@@ -91,6 +102,47 @@
 
     private String localHostAddr = "127.0.0.1";
 
+    @Override
+    public void handle(HttpExchange exchange) throws IOException {
+        if (testDone < testCases[testcaseDone].length) {
+            // still have other tests to run,
+            // check the Cookie header and then redirect it
+            if (testDone > 0) checkRequest(exchange.getRequestHeaders());
+            exchange.getResponseHeaders().add("Location",
+                    testCases[testcaseDone][testDone].serverPath);
+            exchange.getResponseHeaders()
+                    .add(testCases[testcaseDone][testDone].headerToken,
+                         testCases[testcaseDone][testDone].cookieToSend);
+            exchange.sendResponseHeaders(302, -1);
+            testDone++;
+        } else {
+            // the last test of this test case
+            if (testDone > 0) checkRequest(exchange.getRequestHeaders());
+            testcaseDone++;
+            testDone = 0;
+            exchange.sendResponseHeaders(200, -1);
+        }
+        exchange.close();
+    }
+
+    private void checkRequest(Headers hdrs) {
+
+        assert testDone > 0;
+        String cookieHeader = hdrs.getFirst("Cookie");
+        if (cookieHeader != null &&
+            cookieHeader
+                .equalsIgnoreCase(testCases[testcaseDone][testDone-1]
+                                  .cookieToRecv))
+        {
+            System.out.printf("%15s %s\n", "PASSED:", cookieHeader);
+        } else {
+            System.out.printf("%15s %s\n", "FAILED:", cookieHeader);
+            System.out.printf("%15s %s\n\n", "should be:",
+                    testCases[testcaseDone][testDone-1].cookieToRecv);
+            badRequest = true;
+        }
+    }
+
     // test cases
     public static class CookieTestCase {
         public String headerToken;
@@ -106,13 +158,17 @@
         }
     };
 
-    //
-    // these two must match each other, i.e. testCases.length == testPolicies.length
-    //
-    public static CookieTestCase[][] testCases = null;  // the test cases to run; each test case may contain multiple roundtrips
-    public static CookiePolicy[] testPolicies = null;   // indicates what CookiePolicy to use with each test cases
+    /*
+     * these two must match each other,
+     * i.e. testCases.length == testPolicies.length
+     */
 
-    CookieHttpTransaction() {
+    // the test cases to run; each test case may contain multiple roundtrips
+    public static CookieTestCase[][] testCases = null;
+    // indicates what CookiePolicy to use with each test cases
+    public static CookiePolicy[] testPolicies = null;
+
+    CookieTransactionHandler() {
         testCases = new CookieTestCase[testCount][];
         testPolicies = new CookiePolicy[testCount];
 
@@ -126,7 +182,9 @@
         testPolicies[count] = CookiePolicy.ACCEPT_ORIGINAL_SERVER;
         testCases[count++] = new CookieTestCase[]{
                 new CookieTestCase("Set-Cookie",
-                "CUSTOMER=WILE:BOB; path=/; expires=Sat, 09-Nov-2030 23:12:40 GMT;" + "domain=." + localHostAddr,
+                "CUSTOMER=WILE:BOB; " +
+                "path=/; expires=Sat, 09-Nov-2030 23:12:40 GMT;" + "domain=." +
+                localHostAddr,
                 "CUSTOMER=WILE:BOB",
                 "/"
                 ),
@@ -172,12 +230,17 @@
                 ),
                 new CookieTestCase("Set-Cookie2",
                 "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\";Path=\"/acme\";" + "domain=." + localHostAddr,
-                "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr  + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr +  "\"",
+                "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." +
+                    localHostAddr  + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";"
+                    + "$Domain=\"." + localHostAddr +  "\"",
                 "/acme/pickitem"
                 ),
                 new CookieTestCase("Set-Cookie2",
                 "Shipping=\"FedEx\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr,
-                "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr  + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr  + "\"" + "; Shipping=\"FedEx\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"",
+                "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr  +
+                    "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"."
+                    + localHostAddr  + "\"" + "; Shipping=\"FedEx\";$Path=\"/acme\";" +
+                    "$Domain=\"." + localHostAddr + "\"",
                 "/acme/shipping"
                 )
                 };
@@ -191,8 +254,11 @@
                 "/acme/ammo"
                 ),
                 new CookieTestCase("Set-Cookie2",
-                "Part_Number=\"Riding_Rocket_0023\"; Version=\"1\"; Path=\"/acme/ammo\";" + "domain=." + localHostAddr,
-                "$Version=\"1\"; Part_Number=\"Riding_Rocket_0023\";$Path=\"/acme/ammo\";$Domain=\"." + localHostAddr  + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"",
+                "Part_Number=\"Riding_Rocket_0023\"; Version=\"1\"; Path=\"/acme/ammo\";" + "domain=."
+                    + localHostAddr,
+                "$Version=\"1\"; Part_Number=\"Riding_Rocket_0023\";$Path=\"/acme/ammo\";$Domain=\"."
+                    + localHostAddr  + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";"
+                    + "$Domain=\"." + localHostAddr + "\"",
                 "/acme/ammo"
                 ),
                 new CookieTestCase("",
@@ -228,60 +294,19 @@
                 ),
                 new CookieTestCase("Set-Cookie2",
                 "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\";Path=\"/acme\"",
-                "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"",
+                "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"" +
+                    "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"",
                 "/acme/pickitem"
                 ),
                 new CookieTestCase("Set-Cookie2",
                 "Shipping=\"FedEx\"; Version=\"1\"; Path=\"/acme\"",
-                "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"" + "; Shipping=\"FedEx\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"",
+                "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"" +
+                    "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"" +
+                    "; Shipping=\"FedEx\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"",
                 "/acme/shipping"
                 )
                 };
 
         assert count == testCount;
     }
-
-    private int testcaseDone = 0;
-    private int testDone = 0;
-    /*
-     * Our http server which is conducted by testCases array
-     */
-    public void request(HttpTransaction trans) {
-        try {
-            if (testDone < testCases[testcaseDone].length) {
-                // still have other tests to run,
-                // check the Cookie header and then redirect it
-                if (testDone > 0) checkResquest(trans);
-                trans.addResponseHeader("Location", testCases[testcaseDone][testDone].serverPath);
-                trans.addResponseHeader(testCases[testcaseDone][testDone].headerToken,
-                                        testCases[testcaseDone][testDone].cookieToSend);
-                testDone++;
-                trans.sendResponse(302, "Moved Temporarily");
-            } else {
-                // the last test of this test case
-                if (testDone > 0) checkResquest(trans);
-                testcaseDone++;
-                testDone = 0;
-                trans.sendResponse(200, "OK");
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    private void checkResquest(HttpTransaction trans) {
-        String cookieHeader = null;
-
-        assert testDone > 0;
-        cookieHeader = trans.getRequestHeader("Cookie");
-        if (cookieHeader != null &&
-            cookieHeader.equalsIgnoreCase(testCases[testcaseDone][testDone-1].cookieToRecv))
-        {
-            System.out.printf("%15s %s\n", "PASSED:", cookieHeader);
-        } else {
-            System.out.printf("%15s %s\n", "FAILED:", cookieHeader);
-            System.out.printf("%15s %s\n\n", "should be:", testCases[testcaseDone][testDone-1].cookieToRecv);
-            badRequest = true;
-        }
-    }
 }
diff --git a/jdk/test/java/net/HttpURLPermission/HttpURLPermissionTest.java b/jdk/test/java/net/HttpURLPermission/HttpURLPermissionTest.java
new file mode 100644
index 0000000..4f4ea85
--- /dev/null
+++ b/jdk/test/java/net/HttpURLPermission/HttpURLPermissionTest.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.net.HttpURLPermission;
+import java.io.*;
+
+/**
+ * @test
+ * @bug 8010464
+ */
+
+public class HttpURLPermissionTest {
+
+    // super class for all test types
+    abstract static class Test {
+        boolean expected;
+        abstract boolean execute();
+    };
+
+    // Tests URL part of implies() method. This is the main test.
+    static class URLImpliesTest extends Test {
+        String arg1, arg2;
+
+        URLImpliesTest(String arg1, String arg2, boolean expected) {
+            this.arg1 = arg1;
+            this.arg2 = arg2;
+            this.expected = expected;
+        }
+
+          boolean execute() {
+            HttpURLPermission p1 = new HttpURLPermission (arg1, "GET:*");
+            HttpURLPermission p2 = new HttpURLPermission (arg2, "GET:*");
+            boolean result = p1.implies(p2);
+            return result == expected;
+        }
+    };
+
+    static URLImpliesTest imtest(String arg1, String arg2, boolean expected) {
+        return new URLImpliesTest(arg1, arg2, expected);
+    }
+
+    static class ActionImpliesTest extends Test {
+        String arg1, arg2;
+
+        ActionImpliesTest(String arg1, String arg2, boolean expected) {
+            this.arg1 = arg1;
+            this.arg2 = arg2;
+            this.expected = expected;
+        }
+
+          boolean execute() {
+            String url1 = "http://www.foo.com/-";
+            String url2 = "http://www.foo.com/a/b";
+            HttpURLPermission p1 = new HttpURLPermission(url1, arg1);
+            HttpURLPermission p2 = new HttpURLPermission(url2, arg2);
+            boolean result = p1.implies(p2);
+            return result == expected;
+        }
+    }
+
+    static ActionImpliesTest actest(String arg1, String arg2, boolean expected) {
+        return new ActionImpliesTest(arg1, arg2, expected);
+    }
+
+    static Test[] pathImplies = {
+        // single
+        imtest("http://www.foo.com/", "http://www.foo.com/", true),
+        imtest("http://www.bar.com/", "http://www.foo.com/", false),
+        imtest("http://www.foo.com/a/b", "http://www.foo.com/", false),
+        imtest("http://www.foo.com/a/b", "http://www.foo.com/a/b/c", false),
+        // wildcard
+        imtest("http://www.foo.com/a/b/*", "http://www.foo.com/a/b/c", true),
+        imtest("http://www.foo.com/a/b/*", "http://www.foo.com/a/b/*", true),
+        imtest("http://www.foo.com/a/b/*", "http://www.foo.com/a/b/c#frag", true),
+        imtest("http://www.foo.com/a/b/*", "http://www.foo.com/a/b/c#frag?foo=foo", true),
+        imtest("http://www.foo.com/a/b/*", "http://www.foo.com/b/b/c", false),
+        imtest("http://www.foo.com/a/b/*", "http://www.foo.com/a/b/c.html", true),
+        imtest("http://www.foo.com/a/b/*", "http://www.foo.com/a/b/c.html", true),
+        imtest("http://www.foo.com/a/b/*", "https://www.foo.com/a/b/c", false),
+        // recursive
+        imtest("http://www.foo.com/a/b/-", "http://www.foo.com/a/b/-", true),
+        imtest("http://www.foo.com/a/b/-", "http://www.foo.com/a/b/c", true),
+        imtest("http://www.foo.com/a/b/-", "http://www.foo.com/a/b/c#frag", true),
+        imtest("http://www.foo.com/a/b/-", "http://www.foo.com/a/b/c#frag?foo=foo", true),
+        imtest("http://www.foo.com/a/b/-", "http://www.foo.com/b/b/c", false),
+        imtest("http://www.foo.com/a/b/-", "http://www.foo.com/a/b/c.html", true),
+        imtest("http://www.foo.com/a/b/-", "http://www.foo.com/a/b/c.html", true),
+        imtest("http://www.foo.com/a/b/-", "http://www.foo.com/a/b/c/d/e.html", true),
+        imtest("https://www.foo.com/a/b/-", "http://www.foo.com/a/b/c/d/e.html", false),
+        imtest("http://www.foo.com/a/b/-", "http://www.foo.com/a/b/c/d/e#frag", true),
+        imtest("http://www.foo.com/a/b/-", "https://www.foo.com/a/b/c", false),
+        // special cases
+        imtest("http:*", "https://www.foo.com/a/b/c", false),
+        imtest("http:*", "http://www.foo.com/a/b/c", true),
+        imtest("http:*", "http://foo/bar", true),
+        imtest("http://foo/bar", "https://foo/bar", false)
+    };
+
+    static Test[] actionImplies = {
+        actest("GET", "GET", true),
+        actest("GET", "POST", false),
+        actest("GET:", "PUT", false),
+        actest("GET:", "GET", true),
+        actest("GET,POST", "GET", true),
+        actest("GET,POST:", "GET", true),
+        actest("GET:X-Foo", "GET:x-foo", true),
+        actest("GET:X-Foo,X-bar", "GET:x-foo", true),
+        actest("GET:X-Foo", "GET:x-boo", false),
+        actest("GET:X-Foo,X-Bar", "GET:x-bar,x-foo", true),
+        actest("GET:X-Bar,X-Foo,X-Bar,Y-Foo", "GET:x-bar,x-foo", true),
+        actest("GET:*", "GET:x-bar,x-foo", true),
+        actest("*:*", "GET:x-bar,x-foo", true)
+    };
+
+    static boolean failed = false;
+
+    public static void main(String args[]) throws Exception {
+        for (int i=0; i<pathImplies.length ; i++) {
+            URLImpliesTest test = (URLImpliesTest)pathImplies[i];
+            Exception caught = null;
+            boolean result = false;
+            try {
+                result = test.execute();
+            } catch (Exception e) {
+                caught = e;
+                e.printStackTrace();
+            }
+            if (!result) {
+                failed = true;
+                System.out.println ("test failed: " + test.arg1 + ": " +
+                        test.arg2 + " Exception: " + caught);
+            }
+            System.out.println ("path test " + i + " OK");
+
+        }
+        for (int i=0; i<actionImplies.length ; i++) {
+            ActionImpliesTest test = (ActionImpliesTest)actionImplies[i];
+            Exception caught = null;
+            boolean result = false;
+            try {
+                result = test.execute();
+            } catch (Exception e) {
+                caught = e;
+                e.printStackTrace();
+            }
+            if (!result) {
+                failed = true;
+                System.out.println ("test failed: " + test.arg1 + ": " +
+                        test.arg2 + " Exception: " + caught);
+            }
+            System.out.println ("action test " + i + " OK");
+        }
+
+        serializationTest("http://www.foo.com/-", "GET,DELETE:*");
+        serializationTest("https://www.foo.com/-", "POST:X-Foo");
+        serializationTest("https:*", "*:*");
+        serializationTest("http://www.foo.com/a/b/s/", "POST:X-Foo");
+        serializationTest("http://www.foo.com/a/b/s/*", "POST:X-Foo");
+
+        if (failed) {
+            throw new RuntimeException("some tests failed");
+        }
+
+    }
+
+    static void serializationTest(String name, String actions)
+        throws Exception {
+
+        HttpURLPermission out = new HttpURLPermission(name, actions);
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream o = new ObjectOutputStream(baos);
+        o.writeObject(out);
+        ByteArrayInputStream bain = new ByteArrayInputStream(baos.toByteArray());
+        ObjectInputStream i = new ObjectInputStream(bain);
+        HttpURLPermission in = (HttpURLPermission)i.readObject();
+        if (!in.equals(out)) {
+            System.out.println ("FAIL");
+            System.out.println ("in = " + in);
+            System.out.println ("out = " + out);
+            failed = true;
+        }
+    }
+}
diff --git a/jdk/test/java/net/HttpURLPermission/URLTest.java b/jdk/test/java/net/HttpURLPermission/URLTest.java
new file mode 100644
index 0000000..8aef8a1
--- /dev/null
+++ b/jdk/test/java/net/HttpURLPermission/URLTest.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.net.HttpURLPermission;
+/*
+ * Run the tests once without security manager and once with
+ *
+ * @test
+ * @bug 8010464
+ * @compile ../../../com/sun/net/httpserver/SimpleSSLContext.java
+ * @run main/othervm/policy=policy.1 URLTest one
+ * @run main/othervm URLTest one
+ * @run main/othervm/policy=policy.2 URLTest two
+ * @run main/othervm URLTest two
+ * @run main/othervm/policy=policy.3 URLTest three
+ * @run main/othervm URLTest three
+ */
+
+import java.net.*;
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.logging.*;
+import com.sun.net.httpserver.*;
+import javax.net.ssl.*;
+
+public class URLTest {
+    static boolean failed = false;
+
+    public static void main (String[] args) throws Exception {
+        boolean no = false, yes = true;
+
+        if (System.getSecurityManager() == null) {
+            yes = false;
+        }
+        createServers();
+        InetSocketAddress addr1 = httpServer.getAddress();
+        int port1 = addr1.getPort();
+        InetSocketAddress addr2 = httpsServer.getAddress();
+        int port2 = addr2.getPort();
+
+          // each of the following cases is run with a different policy file
+
+        switch (args[0]) {
+          case "one":
+            String url1 = "http://127.0.0.1:"+ port1 + "/foo.html";
+            String url2 = "https://127.0.0.1:"+ port2 + "/foo.html";
+            String url3 = "http://127.0.0.1:"+ port1 + "/bar.html";
+            String url4 = "https://127.0.0.1:"+ port2 + "/bar.html";
+
+            // simple positive test. Should succceed
+            test(url1, "GET", "X-Foo", no);
+            test(url1, "GET", "Z-Bar", "X-Foo", no);
+            test(url1, "GET", "X-Foo", "Z-Bar", no);
+            test(url1, "GET", "Z-Bar", no);
+            test(url2, "POST", "X-Fob", no);
+
+            // reverse the methods, should fail
+            test(url1, "POST", "X-Foo", yes);
+            test(url2, "GET", "X-Fob", yes);
+
+            // different URLs, should fail
+            test(url3, "GET", "X-Foo", yes);
+            test(url4, "POST", "X-Fob", yes);
+            break;
+
+          case "two":
+            url1 = "http://127.0.0.1:"+ port1 + "/foo.html";
+            url2 = "https://127.0.0.1:"+ port2 + "/foo.html";
+            url3 = "http://127.0.0.1:"+ port1 + "/bar.html";
+            url4 = "https://127.0.0.1:"+ port2 + "/bar.html";
+
+            // simple positive test. Should succceed
+            test(url1, "GET", "X-Foo", no);
+            test(url2, "POST", "X-Fob", no);
+            test(url3, "GET", "X-Foo", no);
+            test(url4, "POST", "X-Fob", no);
+            break;
+
+          case "three":
+            url1 = "http://127.0.0.1:"+ port1 + "/foo.html";
+            url2 = "https://127.0.0.1:"+ port2 + "/a/c/d/e/foo.html";
+            url3 = "http://127.0.0.1:"+ port1 + "/a/b/c";
+            url4 = "https://127.0.0.1:"+ port2 + "/a/b/c";
+
+            test(url1, "GET", "X-Foo", yes);
+            test(url2, "POST", "X-Zxc", no);
+            test(url3, "DELETE", "Y-Foo", no);
+            test(url4, "POST", "Y-Foo", yes);
+            break;
+        }
+        shutdown();
+        if (failed) {
+            throw new RuntimeException("Test failed");
+        }
+    }
+
+    public static void test (
+        String u, String method,
+        String header, boolean exceptionExpected
+    )
+        throws Exception
+    {
+        test(u, method, header, null, exceptionExpected);
+    }
+
+    public static void test (
+        String u, String method,
+        String header1, String header2, boolean exceptionExpected
+    )
+        throws Exception
+    {
+        URL url = new URL(u);
+        System.out.println ("url=" + u + " method="+method + " header1="+header1
+                +" header2 = " + header2
+                +" exceptionExpected="+exceptionExpected);
+        HttpURLConnection urlc = (HttpURLConnection)url.openConnection();
+        if (urlc instanceof HttpsURLConnection) {
+            HttpsURLConnection ssl = (HttpsURLConnection)urlc;
+            ssl.setHostnameVerifier(new HostnameVerifier() {
+                public boolean verify(String host, SSLSession sess) {
+                    return true;
+                }
+            });
+            ssl.setSSLSocketFactory (ctx.getSocketFactory());
+        }
+        urlc.setRequestMethod(method);
+        if (header1 != null) {
+            urlc.addRequestProperty(header1, "foo");
+        }
+        if (header2 != null) {
+            urlc.addRequestProperty(header2, "bar");
+        }
+        try {
+            int g = urlc.getResponseCode();
+            if (exceptionExpected) {
+                failed = true;
+                System.out.println ("FAIL");
+                return;
+            }
+            if (g != 200) {
+                String s = Integer.toString(g);
+                throw new RuntimeException("unexpected response "+ s);
+            }
+            InputStream is = urlc.getInputStream();
+            int c,count=0;
+            byte[] buf = new byte[1024];
+            while ((c=is.read(buf)) != -1) {
+                count += c;
+            }
+            is.close();
+        } catch (RuntimeException e) {
+            if (! (e instanceof SecurityException) &&
+                        !(e.getCause() instanceof SecurityException)  ||
+                        !exceptionExpected)
+            {
+                System.out.println ("FAIL");
+                //e.printStackTrace();
+                failed = true;
+            }
+        }
+        System.out.println ("OK");
+    }
+
+    static HttpServer httpServer;
+    static HttpsServer httpsServer;
+    static HttpContext c, cs;
+    static ExecutorService e, es;
+    static SSLContext ctx;
+
+    // These ports need to be hard-coded until we support port number
+    // ranges in the permission class
+
+    static final int PORT1 = 12567;
+    static final int PORT2 = 12568;
+
+    static void createServers() throws Exception {
+        InetSocketAddress addr1 = new InetSocketAddress (PORT1);
+        InetSocketAddress addr2 = new InetSocketAddress (PORT2);
+        httpServer = HttpServer.create (addr1, 0);
+        httpsServer = HttpsServer.create (addr2, 0);
+
+        MyHandler h = new MyHandler();
+
+        c = httpServer.createContext ("/", h);
+        cs = httpsServer.createContext ("/", h);
+        e = Executors.newCachedThreadPool();
+        es = Executors.newCachedThreadPool();
+        httpServer.setExecutor (e);
+        httpsServer.setExecutor (es);
+
+        // take the keystore from elsewhere in test hierarchy
+        String keysdir = System.getProperty("test.src")
+                + "/../../../com/sun/net/httpserver/";
+        ctx = new SimpleSSLContext(keysdir).get();
+        httpsServer.setHttpsConfigurator(new HttpsConfigurator (ctx));
+
+        httpServer.start();
+        httpsServer.start();
+    }
+
+    static void shutdown() {
+        httpServer.stop(1);
+        httpsServer.stop(1);
+        e.shutdown();
+        es.shutdown();
+    }
+
+    static class MyHandler implements HttpHandler {
+
+        MyHandler() {
+        }
+
+        public void handle(HttpExchange x) throws IOException {
+            x.sendResponseHeaders(200, -1);
+            x.close();
+        }
+    }
+
+}
diff --git a/jdk/test/java/net/HttpURLPermission/policy.1 b/jdk/test/java/net/HttpURLPermission/policy.1
new file mode 100644
index 0000000..73fdb00
--- /dev/null
+++ b/jdk/test/java/net/HttpURLPermission/policy.1
@@ -0,0 +1,48 @@
+//
+// Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+//
+// This code is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License version 2 only, as
+// published by the Free Software Foundation.
+//
+// This code is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// version 2 for more details (a copy is included in the LICENSE file that
+// accompanied this code).
+//
+// You should have received a copy of the GNU General Public License version
+// 2 along with this work; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+// or visit www.oracle.com if you need additional information or have any
+// questions.
+//
+
+grant {
+    permission java.net.HttpURLPermission "http://127.0.0.1:12567/foo.html", "GET:X-Foo,Z-Bar";
+    permission java.net.HttpURLPermission "https://127.0.0.1:12568/foo.html", "POST:X-Fob,T-Bar";
+
+    // needed for HttpServer
+    permission "java.net.SocketPermission" "localhost:1024-", "listen,resolve,accept";
+    permission "java.util.PropertyPermission" "test.src", "read";
+    permission java.io.FilePermission "${test.src}/../../../com/sun/net/httpserver/testkeys", "read";
+
+    //permission "java.util.logging.LoggingPermission" "control";
+    //permission "java.io.FilePermission" "/tmp/-", "read,write";
+    permission "java.lang.RuntimePermission" "modifyThread";
+    permission "java.lang.RuntimePermission" "setFactory";
+};
+
+// Normal permissions that aren't granted when run under jtreg
+
+grant codeBase "file:${{java.ext.dirs}}/*" {
+        permission java.security.AllPermission;
+};
+
+grant codeBase "file:${{java.home}}/jre/lib/rt.jar" {
+        permission java.security.AllPermission;
+};
+
diff --git a/jdk/test/java/net/HttpURLPermission/policy.2 b/jdk/test/java/net/HttpURLPermission/policy.2
new file mode 100644
index 0000000..ad86840
--- /dev/null
+++ b/jdk/test/java/net/HttpURLPermission/policy.2
@@ -0,0 +1,46 @@
+//
+// Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+//
+// This code is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License version 2 only, as
+// published by the Free Software Foundation.
+//
+// This code is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// version 2 for more details (a copy is included in the LICENSE file that
+// accompanied this code).
+//
+// You should have received a copy of the GNU General Public License version
+// 2 along with this work; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+// or visit www.oracle.com if you need additional information or have any
+// questions.
+//
+
+grant {
+    permission java.net.HttpURLPermission "http://127.0.0.1:12567/*", "GET:X-Foo";
+    permission java.net.HttpURLPermission "https://127.0.0.1:12568/*", "POST:X-Fob";
+
+    // needed for HttpServer
+    permission "java.net.SocketPermission" "localhost:1024-", "listen,resolve,accept";
+    permission "java.util.PropertyPermission" "test.src", "read";
+    permission java.io.FilePermission "${test.src}/../../../com/sun/net/httpserver/testkeys", "read";
+
+    //permission "java.util.logging.LoggingPermission" "control";
+    //permission "java.io.FilePermission" "/tmp/-", "read,write";
+    permission "java.lang.RuntimePermission" "modifyThread";
+    permission "java.lang.RuntimePermission" "setFactory";
+};
+
+grant codeBase "file:${{java.ext.dirs}}/*" {
+        permission java.security.AllPermission;
+};
+
+grant codeBase "file:///export/repos/jdk8/build/linux-x86_64-normal-server-fastdebug/images/j2sdk-image/jre/lib/rt.jar" {
+        permission java.security.AllPermission;
+};
+
diff --git a/jdk/test/java/net/HttpURLPermission/policy.3 b/jdk/test/java/net/HttpURLPermission/policy.3
new file mode 100644
index 0000000..5f036c0
--- /dev/null
+++ b/jdk/test/java/net/HttpURLPermission/policy.3
@@ -0,0 +1,48 @@
+//
+// Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+//
+// This code is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License version 2 only, as
+// published by the Free Software Foundation.
+//
+// This code is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// version 2 for more details (a copy is included in the LICENSE file that
+// accompanied this code).
+//
+// You should have received a copy of the GNU General Public License version
+// 2 along with this work; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+// or visit www.oracle.com if you need additional information or have any
+// questions.
+//
+
+grant {
+    permission java.net.HttpURLPermission "http://127.0.0.1:12567/a/b/-", "DELETE,GET:X-Foo,Y-Foo";
+    permission java.net.HttpURLPermission "https://127.0.0.1:12568/a/c/-", "POST:*";
+
+    // needed for HttpServer
+    permission "java.net.SocketPermission" "localhost:1024-", "listen,resolve,accept";
+    permission "java.util.PropertyPermission" "test.src", "read";
+    permission java.io.FilePermission "${test.src}/../../../com/sun/net/httpserver/testkeys", "read";
+
+    //permission "java.util.logging.LoggingPermission" "control";
+    //permission "java.io.FilePermission" "/tmp/-", "read,write";
+    permission "java.lang.RuntimePermission" "modifyThread";
+    permission "java.lang.RuntimePermission" "setFactory";
+};
+
+// Normal permissions that aren't granted when run under jtreg
+
+grant codeBase "file:${{java.ext.dirs}}/*" {
+        permission java.security.AllPermission;
+};
+
+grant codeBase "file:${{java.home}}/jre/lib/rt.jar" {
+        permission java.security.AllPermission;
+};
+
diff --git a/jdk/test/java/nio/file/Files/NameLimits.java b/jdk/test/java/nio/file/Files/NameLimits.java
new file mode 100644
index 0000000..21f22e0
--- /dev/null
+++ b/jdk/test/java/nio/file/Files/NameLimits.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8011128
+ * @summary Test file and directory name limits. This test is primarily
+ *   intended to test Files.createDirectory on resolved paths at or around
+ *   the short path limit of 248 on Windows.
+ */
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class NameLimits {
+
+    static final int MAX_PATH = 255;
+    static final int MIN_PATH = 8;     // arbitrarily chosen
+
+    static Path generatePath(int len) {
+        if (len < MIN_PATH)
+            throw new RuntimeException("Attempting to generate path less than MIN_PATH");
+        StringBuilder sb = new StringBuilder(len);
+        sb.append("name");
+        while (sb.length() < len) {
+            sb.append('X');
+        }
+        return Paths.get(sb.toString());
+    }
+
+    static boolean tryCreateFile(int len) throws IOException {
+        Path name = generatePath(len);
+        try {
+            Files.createFile(name);
+        } catch (IOException ioe) {
+            System.err.format("Unable to create file of length %d (full path %d), %s%n",
+                name.toString().length(), name.toAbsolutePath().toString().length(), ioe);
+            return false;
+        }
+        Files.delete(name);
+        return true;
+    }
+
+    static boolean tryCreateDirectory(int len) throws IOException {
+        Path name = generatePath(len);
+        try {
+            Files.createDirectory(name);
+        } catch (IOException ioe) {
+            System.err.format("Unable to create directory of length %d (full path %d), %s%n",
+                name.toString().length(), name.toAbsolutePath().toString().length(), ioe);
+            return false;
+        }
+        Files.delete(name);
+        return true;
+    }
+
+    public static void main(String[] args) throws Exception {
+        int len;
+
+        // find the maximum file name if MAX_PATH or less
+        len = MAX_PATH;
+        while (!tryCreateFile(len)) {
+            len--;
+        }
+        System.out.format("Testing createFile on paths %d .. %d%n", MIN_PATH, len);
+        while (len >= MIN_PATH) {
+            if (!tryCreateFile(len--))
+                throw new RuntimeException("Test failed");
+        }
+
+        // find the maximum directory name if MAX_PATH or less
+        len = MAX_PATH;
+        while (!tryCreateDirectory(len)) {
+            len--;
+        }
+        System.out.format("Testing createDirectory on paths %d .. %d%n", MIN_PATH, len);
+        while (len >= MIN_PATH) {
+            if (!tryCreateDirectory(len--))
+                throw new RuntimeException("Test failed");
+        }
+    }
+}
diff --git a/jdk/test/java/time/tck/java/time/TCKInstant.java b/jdk/test/java/time/tck/java/time/TCKInstant.java
index 0bab247..bdf5fcc 100644
--- a/jdk/test/java/time/tck/java/time/TCKInstant.java
+++ b/jdk/test/java/time/tck/java/time/TCKInstant.java
@@ -370,6 +370,8 @@
                 {"Z"},
                 {"1970-01-01T00:00:00"},
                 {"1970-01-01T00:00:0Z"},
+                {"1970-01-01T00:0:00Z"},
+                {"1970-01-01T0:00:00Z"},
                 {"1970-01-01T00:00:00.0000000000Z"},
         };
     }
@@ -2045,60 +2047,64 @@
     Object[][] data_toString() {
         return new Object[][] {
                 {Instant.ofEpochSecond(65L, 567), "1970-01-01T00:01:05.000000567Z"},
+                {Instant.ofEpochSecond(65L, 560), "1970-01-01T00:01:05.000000560Z"},
+                {Instant.ofEpochSecond(65L, 560000), "1970-01-01T00:01:05.000560Z"},
+                {Instant.ofEpochSecond(65L, 560000000), "1970-01-01T00:01:05.560Z"},
+
                 {Instant.ofEpochSecond(1, 0), "1970-01-01T00:00:01Z"},
-                {Instant.ofEpochSecond(60, 0), "1970-01-01T00:01Z"},
-                {Instant.ofEpochSecond(3600, 0), "1970-01-01T01:00Z"},
+                {Instant.ofEpochSecond(60, 0), "1970-01-01T00:01:00Z"},
+                {Instant.ofEpochSecond(3600, 0), "1970-01-01T01:00:00Z"},
                 {Instant.ofEpochSecond(-1, 0), "1969-12-31T23:59:59Z"},
 
-                {LocalDateTime.of(0, 1, 2, 0, 0).toInstant(ZoneOffset.UTC), "0000-01-02T00:00Z"},
-                {LocalDateTime.of(0, 1, 1, 12, 30).toInstant(ZoneOffset.UTC), "0000-01-01T12:30Z"},
+                {LocalDateTime.of(0, 1, 2, 0, 0).toInstant(ZoneOffset.UTC), "0000-01-02T00:00:00Z"},
+                {LocalDateTime.of(0, 1, 1, 12, 30).toInstant(ZoneOffset.UTC), "0000-01-01T12:30:00Z"},
                 {LocalDateTime.of(0, 1, 1, 0, 0, 0, 1).toInstant(ZoneOffset.UTC), "0000-01-01T00:00:00.000000001Z"},
-                {LocalDateTime.of(0, 1, 1, 0, 0).toInstant(ZoneOffset.UTC), "0000-01-01T00:00Z"},
+                {LocalDateTime.of(0, 1, 1, 0, 0).toInstant(ZoneOffset.UTC), "0000-01-01T00:00:00Z"},
 
                 {LocalDateTime.of(-1, 12, 31, 23, 59, 59, 999_999_999).toInstant(ZoneOffset.UTC), "-0001-12-31T23:59:59.999999999Z"},
-                {LocalDateTime.of(-1, 12, 31, 12, 30).toInstant(ZoneOffset.UTC), "-0001-12-31T12:30Z"},
-                {LocalDateTime.of(-1, 12, 30, 12, 30).toInstant(ZoneOffset.UTC), "-0001-12-30T12:30Z"},
+                {LocalDateTime.of(-1, 12, 31, 12, 30).toInstant(ZoneOffset.UTC), "-0001-12-31T12:30:00Z"},
+                {LocalDateTime.of(-1, 12, 30, 12, 30).toInstant(ZoneOffset.UTC), "-0001-12-30T12:30:00Z"},
 
-                {LocalDateTime.of(-9999, 1, 2, 12, 30).toInstant(ZoneOffset.UTC), "-9999-01-02T12:30Z"},
-                {LocalDateTime.of(-9999, 1, 1, 12, 30).toInstant(ZoneOffset.UTC), "-9999-01-01T12:30Z"},
-                {LocalDateTime.of(-9999, 1, 1, 0, 0).toInstant(ZoneOffset.UTC), "-9999-01-01T00:00Z"},
+                {LocalDateTime.of(-9999, 1, 2, 12, 30).toInstant(ZoneOffset.UTC), "-9999-01-02T12:30:00Z"},
+                {LocalDateTime.of(-9999, 1, 1, 12, 30).toInstant(ZoneOffset.UTC), "-9999-01-01T12:30:00Z"},
+                {LocalDateTime.of(-9999, 1, 1, 0, 0).toInstant(ZoneOffset.UTC), "-9999-01-01T00:00:00Z"},
 
                 {LocalDateTime.of(-10000, 12, 31, 23, 59, 59, 999_999_999).toInstant(ZoneOffset.UTC), "-10000-12-31T23:59:59.999999999Z"},
-                {LocalDateTime.of(-10000, 12, 31, 12, 30).toInstant(ZoneOffset.UTC), "-10000-12-31T12:30Z"},
-                {LocalDateTime.of(-10000, 12, 30, 12, 30).toInstant(ZoneOffset.UTC), "-10000-12-30T12:30Z"},
-                {LocalDateTime.of(-15000, 12, 31, 12, 30).toInstant(ZoneOffset.UTC), "-15000-12-31T12:30Z"},
+                {LocalDateTime.of(-10000, 12, 31, 12, 30).toInstant(ZoneOffset.UTC), "-10000-12-31T12:30:00Z"},
+                {LocalDateTime.of(-10000, 12, 30, 12, 30).toInstant(ZoneOffset.UTC), "-10000-12-30T12:30:00Z"},
+                {LocalDateTime.of(-15000, 12, 31, 12, 30).toInstant(ZoneOffset.UTC), "-15000-12-31T12:30:00Z"},
 
-                {LocalDateTime.of(-19999, 1, 2, 12, 30).toInstant(ZoneOffset.UTC), "-19999-01-02T12:30Z"},
-                {LocalDateTime.of(-19999, 1, 1, 12, 30).toInstant(ZoneOffset.UTC), "-19999-01-01T12:30Z"},
-                {LocalDateTime.of(-19999, 1, 1, 0, 0).toInstant(ZoneOffset.UTC), "-19999-01-01T00:00Z"},
+                {LocalDateTime.of(-19999, 1, 2, 12, 30).toInstant(ZoneOffset.UTC), "-19999-01-02T12:30:00Z"},
+                {LocalDateTime.of(-19999, 1, 1, 12, 30).toInstant(ZoneOffset.UTC), "-19999-01-01T12:30:00Z"},
+                {LocalDateTime.of(-19999, 1, 1, 0, 0).toInstant(ZoneOffset.UTC), "-19999-01-01T00:00:00Z"},
 
                 {LocalDateTime.of(-20000, 12, 31, 23, 59, 59, 999_999_999).toInstant(ZoneOffset.UTC), "-20000-12-31T23:59:59.999999999Z"},
-                {LocalDateTime.of(-20000, 12, 31, 12, 30).toInstant(ZoneOffset.UTC), "-20000-12-31T12:30Z"},
-                {LocalDateTime.of(-20000, 12, 30, 12, 30).toInstant(ZoneOffset.UTC), "-20000-12-30T12:30Z"},
-                {LocalDateTime.of(-25000, 12, 31, 12, 30).toInstant(ZoneOffset.UTC), "-25000-12-31T12:30Z"},
+                {LocalDateTime.of(-20000, 12, 31, 12, 30).toInstant(ZoneOffset.UTC), "-20000-12-31T12:30:00Z"},
+                {LocalDateTime.of(-20000, 12, 30, 12, 30).toInstant(ZoneOffset.UTC), "-20000-12-30T12:30:00Z"},
+                {LocalDateTime.of(-25000, 12, 31, 12, 30).toInstant(ZoneOffset.UTC), "-25000-12-31T12:30:00Z"},
 
-                {LocalDateTime.of(9999, 12, 30, 12, 30).toInstant(ZoneOffset.UTC), "9999-12-30T12:30Z"},
-                {LocalDateTime.of(9999, 12, 31, 12, 30).toInstant(ZoneOffset.UTC), "9999-12-31T12:30Z"},
+                {LocalDateTime.of(9999, 12, 30, 12, 30).toInstant(ZoneOffset.UTC), "9999-12-30T12:30:00Z"},
+                {LocalDateTime.of(9999, 12, 31, 12, 30).toInstant(ZoneOffset.UTC), "9999-12-31T12:30:00Z"},
                 {LocalDateTime.of(9999, 12, 31, 23, 59, 59, 999_999_999).toInstant(ZoneOffset.UTC), "9999-12-31T23:59:59.999999999Z"},
 
-                {LocalDateTime.of(10000, 1, 1, 0, 0).toInstant(ZoneOffset.UTC), "+10000-01-01T00:00Z"},
-                {LocalDateTime.of(10000, 1, 1, 12, 30).toInstant(ZoneOffset.UTC), "+10000-01-01T12:30Z"},
-                {LocalDateTime.of(10000, 1, 2, 12, 30).toInstant(ZoneOffset.UTC), "+10000-01-02T12:30Z"},
-                {LocalDateTime.of(15000, 12, 31, 12, 30).toInstant(ZoneOffset.UTC), "+15000-12-31T12:30Z"},
+                {LocalDateTime.of(10000, 1, 1, 0, 0).toInstant(ZoneOffset.UTC), "+10000-01-01T00:00:00Z"},
+                {LocalDateTime.of(10000, 1, 1, 12, 30).toInstant(ZoneOffset.UTC), "+10000-01-01T12:30:00Z"},
+                {LocalDateTime.of(10000, 1, 2, 12, 30).toInstant(ZoneOffset.UTC), "+10000-01-02T12:30:00Z"},
+                {LocalDateTime.of(15000, 12, 31, 12, 30).toInstant(ZoneOffset.UTC), "+15000-12-31T12:30:00Z"},
 
-                {LocalDateTime.of(19999, 12, 30, 12, 30).toInstant(ZoneOffset.UTC), "+19999-12-30T12:30Z"},
-                {LocalDateTime.of(19999, 12, 31, 12, 30).toInstant(ZoneOffset.UTC), "+19999-12-31T12:30Z"},
+                {LocalDateTime.of(19999, 12, 30, 12, 30).toInstant(ZoneOffset.UTC), "+19999-12-30T12:30:00Z"},
+                {LocalDateTime.of(19999, 12, 31, 12, 30).toInstant(ZoneOffset.UTC), "+19999-12-31T12:30:00Z"},
                 {LocalDateTime.of(19999, 12, 31, 23, 59, 59, 999_999_999).toInstant(ZoneOffset.UTC), "+19999-12-31T23:59:59.999999999Z"},
 
-                {LocalDateTime.of(20000, 1, 1, 0, 0).toInstant(ZoneOffset.UTC), "+20000-01-01T00:00Z"},
-                {LocalDateTime.of(20000, 1, 1, 12, 30).toInstant(ZoneOffset.UTC), "+20000-01-01T12:30Z"},
-                {LocalDateTime.of(20000, 1, 2, 12, 30).toInstant(ZoneOffset.UTC), "+20000-01-02T12:30Z"},
-                {LocalDateTime.of(25000, 12, 31, 12, 30).toInstant(ZoneOffset.UTC), "+25000-12-31T12:30Z"},
+                {LocalDateTime.of(20000, 1, 1, 0, 0).toInstant(ZoneOffset.UTC), "+20000-01-01T00:00:00Z"},
+                {LocalDateTime.of(20000, 1, 1, 12, 30).toInstant(ZoneOffset.UTC), "+20000-01-01T12:30:00Z"},
+                {LocalDateTime.of(20000, 1, 2, 12, 30).toInstant(ZoneOffset.UTC), "+20000-01-02T12:30:00Z"},
+                {LocalDateTime.of(25000, 12, 31, 12, 30).toInstant(ZoneOffset.UTC), "+25000-12-31T12:30:00Z"},
 
-                {LocalDateTime.of(-999_999_999, 1, 1, 12, 30).toInstant(ZoneOffset.UTC).minus(1, DAYS), "-1000000000-12-31T12:30Z"},
-                {LocalDateTime.of(999_999_999, 12, 31, 12, 30).toInstant(ZoneOffset.UTC).plus(1, DAYS), "+1000000000-01-01T12:30Z"},
+                {LocalDateTime.of(-999_999_999, 1, 1, 12, 30).toInstant(ZoneOffset.UTC).minus(1, DAYS), "-1000000000-12-31T12:30:00Z"},
+                {LocalDateTime.of(999_999_999, 12, 31, 12, 30).toInstant(ZoneOffset.UTC).plus(1, DAYS), "+1000000000-01-01T12:30:00Z"},
 
-                {Instant.MIN, "-1000000000-01-01T00:00Z"},
+                {Instant.MIN, "-1000000000-01-01T00:00:00Z"},
                 {Instant.MAX, "+1000000000-12-31T23:59:59.999999999Z"},
         };
     }
diff --git a/jdk/test/java/time/tck/java/time/TCKLocalTime.java b/jdk/test/java/time/tck/java/time/TCKLocalTime.java
index 72d52a2..28c5949 100644
--- a/jdk/test/java/time/tck/java/time/TCKLocalTime.java
+++ b/jdk/test/java/time/tck/java/time/TCKLocalTime.java
@@ -142,7 +142,7 @@
 
     private static final TemporalUnit[] INVALID_UNITS;
     static {
-        EnumSet<ChronoUnit> set = EnumSet.range(WEEKS, FOREVER);
+        EnumSet<ChronoUnit> set = EnumSet.range(DAYS, FOREVER);
         INVALID_UNITS = (TemporalUnit[]) set.toArray(new TemporalUnit[set.size()]);
     }
 
@@ -1122,14 +1122,6 @@
         }
     }
 
-    @Test
-    public void test_plus_longTemporalUnit_multiples() {
-        assertEquals(TEST_12_30_40_987654321.plus(0, DAYS), TEST_12_30_40_987654321);
-        assertEquals(TEST_12_30_40_987654321.plus(1, DAYS), TEST_12_30_40_987654321);
-        assertEquals(TEST_12_30_40_987654321.plus(2, DAYS), TEST_12_30_40_987654321);
-        assertEquals(TEST_12_30_40_987654321.plus(-3, DAYS), TEST_12_30_40_987654321);
-    }
-
     @Test(expectedExceptions=NullPointerException.class)
     public void test_plus_longTemporalUnit_null() {
         TEST_12_30_40_987654321.plus(1, (TemporalUnit) null);
@@ -1556,14 +1548,6 @@
         }
     }
 
-    @Test
-    public void test_minus_longTemporalUnit_long_multiples() {
-        assertEquals(TEST_12_30_40_987654321.minus(0, DAYS), TEST_12_30_40_987654321);
-        assertEquals(TEST_12_30_40_987654321.minus(1, DAYS), TEST_12_30_40_987654321);
-        assertEquals(TEST_12_30_40_987654321.minus(2, DAYS), TEST_12_30_40_987654321);
-        assertEquals(TEST_12_30_40_987654321.minus(-3, DAYS), TEST_12_30_40_987654321);
-    }
-
     @Test(expectedExceptions=NullPointerException.class)
     public void test_minus_longTemporalUnit_null() {
         TEST_12_30_40_987654321.minus(1, (TemporalUnit) null);
diff --git a/jdk/test/java/time/tck/java/time/TCKOffsetTime.java b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java
index ff8ec88..7b97380 100644
--- a/jdk/test/java/time/tck/java/time/TCKOffsetTime.java
+++ b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java
@@ -75,7 +75,13 @@
 import static java.time.temporal.ChronoField.OFFSET_SECONDS;
 import static java.time.temporal.ChronoField.SECOND_OF_DAY;
 import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
+import static java.time.temporal.ChronoUnit.MONTHS;
 import static java.time.temporal.ChronoUnit.DAYS;
+import static java.time.temporal.ChronoUnit.HOURS;
+import static java.time.temporal.ChronoUnit.MINUTES;
+import static java.time.temporal.ChronoUnit.MICROS;
+import static java.time.temporal.ChronoUnit.MILLIS;
+import static java.time.temporal.ChronoUnit.HALF_DAYS;
 import static java.time.temporal.ChronoUnit.NANOS;
 import static java.time.temporal.ChronoUnit.SECONDS;
 import static org.testng.Assert.assertEquals;
@@ -110,6 +116,7 @@
 import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQuery;
+import java.time.temporal.TemporalUnit;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -1031,6 +1038,56 @@
     }
 
     //-----------------------------------------------------------------------
+    // periodUntil(Temporal, TemporalUnit)
+    //-----------------------------------------------------------------------
+    @DataProvider(name="periodUntilUnit")
+    Object[][] data_periodUntilUnit() {
+        return new Object[][] {
+            {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(13, 1, 1), ZoneOffset.ofHours(1)), HALF_DAYS, 1},
+            {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), HOURS, 1},
+            {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), MINUTES, 60},
+            {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), SECONDS, 3600},
+            {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), MILLIS, 3600*1000},
+            {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), MICROS, 3600*1000*1000L},
+            {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), NANOS, 3600*1000*1000L*1000},
+
+            {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(14, 1, 1), ZoneOffset.ofHours(2)), HALF_DAYS, 1},
+            {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), HOURS, 1},
+            {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), MINUTES, 60},
+            {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), SECONDS, 3600},
+            {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), MILLIS, 3600*1000},
+            {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), MICROS, 3600*1000*1000L},
+            {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), NANOS, 3600*1000*1000L*1000},
+        };
+    }
+
+    @Test(dataProvider="periodUntilUnit")
+    public void test_periodUntil_TemporalUnit(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) {
+        long amount = offsetTime1.periodUntil(offsetTime2, unit);
+        assertEquals(amount, expected);
+    }
+
+    @Test(dataProvider="periodUntilUnit")
+    public void test_periodUntil_TemporalUnit_negated(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) {
+        long amount = offsetTime2.periodUntil(offsetTime1, unit);
+        assertEquals(amount, -expected);
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_periodUntil_InvalidType() {
+        OffsetTime offsetTime = OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1));
+        OffsetDateTime offsetDateTime = offsetTime.atDate(LocalDate.of(1980, 2, 10));
+        offsetTime.periodUntil(offsetDateTime, SECONDS);
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_periodUntil_InvalidTemporalUnit() {
+        OffsetTime offsetTime1 = OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1));
+        OffsetTime offsetTime2 = OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1));
+        offsetTime1.periodUntil(offsetTime2, MONTHS);
+    }
+
+    //-----------------------------------------------------------------------
     // format(DateTimeFormatter)
     //-----------------------------------------------------------------------
     @Test
diff --git a/jdk/test/java/time/tck/java/time/TCKYear.java b/jdk/test/java/time/tck/java/time/TCKYear.java
index 570946f..ac25f0b 100644
--- a/jdk/test/java/time/tck/java/time/TCKYear.java
+++ b/jdk/test/java/time/tck/java/time/TCKYear.java
@@ -71,6 +71,7 @@
 import static java.time.temporal.ChronoUnit.WEEKS;
 import static java.time.temporal.ChronoUnit.YEARS;
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
 import java.io.ByteArrayOutputStream;
@@ -89,6 +90,7 @@
 import java.time.YearMonth;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
+import java.time.chrono.IsoEra;
 import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeParseException;
@@ -526,6 +528,47 @@
     }
 
     //-----------------------------------------------------------------------
+    // plus(long, TemporalUnit)
+    //-----------------------------------------------------------------------
+    @DataProvider(name="plus_long_TemporalUnit")
+    Object[][] data_plus_long_TemporalUnit() {
+        return new Object[][] {
+            {Year.of(1), 1, ChronoUnit.YEARS, Year.of(2), null},
+            {Year.of(1), -12, ChronoUnit.YEARS, Year.of(-11), null},
+            {Year.of(1), 0, ChronoUnit.YEARS, Year.of(1), null},
+            {Year.of(999999999), 0, ChronoUnit.YEARS, Year.of(999999999), null},
+            {Year.of(-999999999), 0, ChronoUnit.YEARS, Year.of(-999999999), null},
+            {Year.of(0), -999999999, ChronoUnit.YEARS, Year.of(-999999999), null},
+            {Year.of(0), 999999999, ChronoUnit.YEARS, Year.of(999999999), null},
+
+            {Year.of(-1), 1, ChronoUnit.ERAS, Year.of(2), null},
+            {Year.of(5), 1, ChronoUnit.CENTURIES, Year.of(105), null},
+            {Year.of(5), 1, ChronoUnit.DECADES, Year.of(15), null},
+
+            {Year.of(999999999), 1, ChronoUnit.YEARS, null, DateTimeException.class},
+            {Year.of(-999999999), -1, ChronoUnit.YEARS, null, DateTimeException.class},
+
+            {Year.of(1), 0, ChronoUnit.DAYS, null, DateTimeException.class},
+            {Year.of(1), 0, ChronoUnit.WEEKS, null, DateTimeException.class},
+            {Year.of(1), 0, ChronoUnit.MONTHS, null, DateTimeException.class},
+        };
+    }
+
+    @Test(groups={"tck"}, dataProvider="plus_long_TemporalUnit")
+    public void test_plus_long_TemporalUnit(Year base, long amount, TemporalUnit unit, Year expectedYear, Class expectedEx) {
+        if (expectedEx == null) {
+            assertEquals(base.plus(amount, unit), expectedYear);
+        } else {
+            try {
+                Year result = base.plus(amount, unit);
+                fail();
+            } catch (Exception ex) {
+                assertTrue(expectedEx.isInstance(ex));
+            }
+        }
+    }
+
+    //-----------------------------------------------------------------------
     // minus(Period)
     //-----------------------------------------------------------------------
     @DataProvider(name="minusValid")
@@ -617,6 +660,47 @@
     }
 
     //-----------------------------------------------------------------------
+    // minus(long, TemporalUnit)
+    //-----------------------------------------------------------------------
+    @DataProvider(name="minus_long_TemporalUnit")
+    Object[][] data_minus_long_TemporalUnit() {
+        return new Object[][] {
+            {Year.of(1), 1, ChronoUnit.YEARS, Year.of(0), null},
+            {Year.of(1), -12, ChronoUnit.YEARS, Year.of(13), null},
+            {Year.of(1), 0, ChronoUnit.YEARS, Year.of(1), null},
+            {Year.of(999999999), 0, ChronoUnit.YEARS, Year.of(999999999), null},
+            {Year.of(-999999999), 0, ChronoUnit.YEARS, Year.of(-999999999), null},
+            {Year.of(0), -999999999, ChronoUnit.YEARS, Year.of(999999999), null},
+            {Year.of(0), 999999999, ChronoUnit.YEARS, Year.of(-999999999), null},
+
+            {Year.of(999999999), 1, ChronoUnit.ERAS, Year.of(-999999999 + 1), null},
+            {Year.of(105), 1, ChronoUnit.CENTURIES, Year.of(5), null},
+            {Year.of(15), 1, ChronoUnit.DECADES, Year.of(5), null},
+
+            {Year.of(-999999999), 1, ChronoUnit.YEARS, null, DateTimeException.class},
+            {Year.of(1), -999999999, ChronoUnit.YEARS, null, DateTimeException.class},
+
+            {Year.of(1), 0, ChronoUnit.DAYS, null, DateTimeException.class},
+            {Year.of(1), 0, ChronoUnit.WEEKS, null, DateTimeException.class},
+            {Year.of(1), 0, ChronoUnit.MONTHS, null, DateTimeException.class},
+        };
+    }
+
+    @Test(groups={"tck"}, dataProvider="minus_long_TemporalUnit")
+    public void test_minus_long_TemporalUnit(Year base, long amount, TemporalUnit unit, Year expectedYear, Class expectedEx) {
+        if (expectedEx == null) {
+            assertEquals(base.minus(amount, unit), expectedYear);
+        } else {
+            try {
+                Year result = base.minus(amount, unit);
+                fail();
+            } catch (Exception ex) {
+                assertTrue(expectedEx.isInstance(ex));
+            }
+        }
+    }
+
+    //-----------------------------------------------------------------------
     // adjustInto()
     //-----------------------------------------------------------------------
     @Test
@@ -641,6 +725,49 @@
     }
 
     //-----------------------------------------------------------------------
+    // with(TemporalAdjuster)
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_with_TemporalAdjuster() {
+        Year base = Year.of(-10);
+        for (int i = -4; i <= 2104; i++) {
+            Temporal result = base.with(Year.of(i));
+            assertEquals(result, Year.of(i));
+        }
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_with_BadTemporalAdjuster() {
+        Year test = Year.of(1);
+        test.with(LocalTime.of(18, 1, 2));
+    }
+
+    //-----------------------------------------------------------------------
+    // with(TemporalField, long)
+    //-----------------------------------------------------------------------
+    @Test(groups={"tck"})
+    public void test_with() {
+        Year base = Year.of(5);
+        Year result = base.with(ChronoField.ERA, 0);
+        assertEquals(result, base.with(IsoEra.of(0)));
+
+        int prolepticYear = IsoChronology.INSTANCE.prolepticYear(IsoEra.of(0), 5);
+        assertEquals(result.get(ChronoField.ERA), 0);
+        assertEquals(result.get(ChronoField.YEAR), prolepticYear);
+        assertEquals(result.get(ChronoField.YEAR_OF_ERA), 5);
+
+        result = base.with(ChronoField.YEAR, 10);
+        assertEquals(result.get(ChronoField.ERA), base.get(ChronoField.ERA));
+        assertEquals(result.get(ChronoField.YEAR), 10);
+        assertEquals(result.get(ChronoField.YEAR_OF_ERA), 10);
+
+        result = base.with(ChronoField.YEAR_OF_ERA, 20);
+        assertEquals(result.get(ChronoField.ERA), base.get(ChronoField.ERA));
+        assertEquals(result.get(ChronoField.YEAR), 20);
+        assertEquals(result.get(ChronoField.YEAR_OF_ERA), 20);
+    }
+
+    //-----------------------------------------------------------------------
     // length()
     //-----------------------------------------------------------------------
     @Test
diff --git a/jdk/test/java/time/tck/java/time/TCKYearMonth.java b/jdk/test/java/time/tck/java/time/TCKYearMonth.java
index 8cbf6c4..14ccc77 100644
--- a/jdk/test/java/time/tck/java/time/TCKYearMonth.java
+++ b/jdk/test/java/time/tck/java/time/TCKYearMonth.java
@@ -81,6 +81,7 @@
 import java.io.IOException;
 import java.time.Clock;
 import java.time.DateTimeException;
+import java.time.Duration;
 import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
@@ -98,6 +99,7 @@
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.JulianFields;
 import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQuery;
 import java.time.temporal.TemporalUnit;
@@ -689,6 +691,106 @@
     }
 
     //-----------------------------------------------------------------------
+    // plus(long, TemporalUnit)
+    //-----------------------------------------------------------------------
+    @DataProvider(name="plus_long_TemporalUnit")
+    Object[][] data_plus_long_TemporalUnit() {
+        return new Object[][] {
+            {YearMonth.of(1, 10), 1, ChronoUnit.YEARS, YearMonth.of(2, 10), null},
+            {YearMonth.of(1, 10), -12, ChronoUnit.YEARS, YearMonth.of(-11, 10), null},
+            {YearMonth.of(1, 10), 0, ChronoUnit.YEARS, YearMonth.of(1, 10), null},
+            {YearMonth.of(999999999, 12), 0, ChronoUnit.YEARS, YearMonth.of(999999999, 12), null},
+            {YearMonth.of(-999999999, 1), 0, ChronoUnit.YEARS, YearMonth.of(-999999999, 1), null},
+            {YearMonth.of(0, 1), -999999999, ChronoUnit.YEARS, YearMonth.of(-999999999, 1), null},
+            {YearMonth.of(0, 12), 999999999, ChronoUnit.YEARS, YearMonth.of(999999999, 12), null},
+
+            {YearMonth.of(1, 10), 1, ChronoUnit.MONTHS, YearMonth.of(1, 11), null},
+            {YearMonth.of(1, 10), -12, ChronoUnit.MONTHS, YearMonth.of(0, 10), null},
+            {YearMonth.of(1, 10), 0, ChronoUnit.MONTHS, YearMonth.of(1, 10), null},
+            {YearMonth.of(999999999, 12), 0, ChronoUnit.MONTHS, YearMonth.of(999999999, 12), null},
+            {YearMonth.of(-999999999, 1), 0, ChronoUnit.MONTHS, YearMonth.of(-999999999, 1), null},
+            {YearMonth.of(-999999999, 2), -1, ChronoUnit.MONTHS, YearMonth.of(-999999999, 1), null},
+            {YearMonth.of(999999999, 3), 9, ChronoUnit.MONTHS, YearMonth.of(999999999, 12), null},
+
+            {YearMonth.of(-1, 10), 1, ChronoUnit.ERAS, YearMonth.of(2, 10), null},
+            {YearMonth.of(5, 10), 1, ChronoUnit.CENTURIES, YearMonth.of(105, 10), null},
+            {YearMonth.of(5, 10), 1, ChronoUnit.DECADES, YearMonth.of(15, 10), null},
+
+            {YearMonth.of(999999999, 12), 1, ChronoUnit.MONTHS, null, DateTimeException.class},
+            {YearMonth.of(-999999999, 1), -1, ChronoUnit.MONTHS, null, DateTimeException.class},
+
+            {YearMonth.of(1, 1), 0, ChronoUnit.DAYS, null, DateTimeException.class},
+            {YearMonth.of(1, 1), 0, ChronoUnit.WEEKS, null, DateTimeException.class},
+        };
+    }
+
+    @Test(groups={"tck"}, dataProvider="plus_long_TemporalUnit")
+    public void test_plus_long_TemporalUnit(YearMonth base, long amount, TemporalUnit unit, YearMonth expectedYearMonth, Class expectedEx) {
+        if (expectedEx == null) {
+            assertEquals(base.plus(amount, unit), expectedYearMonth);
+        } else {
+            try {
+                YearMonth result = base.plus(amount, unit);
+                fail();
+            } catch (Exception ex) {
+                assertTrue(expectedEx.isInstance(ex));
+            }
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    // plus(TemporalAmount)
+    //-----------------------------------------------------------------------
+    @DataProvider(name="plus_TemporalAmount")
+    Object[][] data_plus_TemporalAmount() {
+        return new Object[][] {
+            {YearMonth.of(1, 1), Period.ofYears(1), YearMonth.of(2, 1), null},
+            {YearMonth.of(1, 1), Period.ofYears(-12), YearMonth.of(-11, 1), null},
+            {YearMonth.of(1, 1), Period.ofYears(0), YearMonth.of(1, 1), null},
+            {YearMonth.of(999999999, 12), Period.ofYears(0), YearMonth.of(999999999, 12), null},
+            {YearMonth.of(-999999999, 1), Period.ofYears(0), YearMonth.of(-999999999, 1), null},
+            {YearMonth.of(0, 1), Period.ofYears(-999999999), YearMonth.of(-999999999, 1), null},
+            {YearMonth.of(0, 12), Period.ofYears(999999999), YearMonth.of(999999999, 12), null},
+
+            {YearMonth.of(1, 1), Period.ofMonths(1), YearMonth.of(1, 2), null},
+            {YearMonth.of(1, 1), Period.ofMonths(-12), YearMonth.of(0, 1), null},
+            {YearMonth.of(1, 1), Period.ofMonths(121), YearMonth.of(11, 2), null},
+            {YearMonth.of(1, 1), Period.ofMonths(0), YearMonth.of(1, 1), null},
+            {YearMonth.of(999999999, 12), Period.ofMonths(0), YearMonth.of(999999999, 12), null},
+            {YearMonth.of(-999999999, 1), Period.ofMonths(0), YearMonth.of(-999999999, 1), null},
+            {YearMonth.of(-999999999, 2), Period.ofMonths(-1), YearMonth.of(-999999999, 1), null},
+            {YearMonth.of(999999999, 11), Period.ofMonths(1), YearMonth.of(999999999, 12), null},
+
+            {YearMonth.of(1, 1), Period.ofYears(1).withMonths(2), YearMonth.of(2, 3), null},
+            {YearMonth.of(1, 1), Period.ofYears(-12).withMonths(-1), YearMonth.of(-12, 12), null},
+
+            {YearMonth.of(1, 1), Period.ofMonths(2).withYears(1), YearMonth.of(2, 3), null},
+            {YearMonth.of(1, 1), Period.ofMonths(-1).withYears(-12), YearMonth.of(-12, 12), null},
+
+            {YearMonth.of(1, 1), Period.ofDays(365), null, DateTimeException.class},
+            {YearMonth.of(1, 1), Duration.ofDays(365), null, DateTimeException.class},
+            {YearMonth.of(1, 1), Duration.ofHours(365*24), null, DateTimeException.class},
+            {YearMonth.of(1, 1), Duration.ofMinutes(365*24*60), null, DateTimeException.class},
+            {YearMonth.of(1, 1), Duration.ofSeconds(365*24*3600), null, DateTimeException.class},
+            {YearMonth.of(1, 1), Duration.ofNanos(365*24*3600*1000000000), null, DateTimeException.class},
+        };
+    }
+
+    @Test(groups={"tck"}, dataProvider="plus_TemporalAmount")
+    public void test_plus_TemporalAmount(YearMonth base, TemporalAmount temporalAmount, YearMonth expectedYearMonth, Class expectedEx) {
+        if (expectedEx == null) {
+            assertEquals(base.plus(temporalAmount), expectedYearMonth);
+        } else {
+            try {
+                YearMonth result = base.plus(temporalAmount);
+                fail();
+            } catch (Exception ex) {
+                assertTrue(expectedEx.isInstance(ex));
+            }
+        }
+    }
+
+    //-----------------------------------------------------------------------
     // minusYears()
     //-----------------------------------------------------------------------
     @Test
@@ -804,6 +906,106 @@
     }
 
     //-----------------------------------------------------------------------
+    // minus(long, TemporalUnit)
+    //-----------------------------------------------------------------------
+    @DataProvider(name="minus_long_TemporalUnit")
+    Object[][] data_minus_long_TemporalUnit() {
+        return new Object[][] {
+            {YearMonth.of(1, 10), 1, ChronoUnit.YEARS, YearMonth.of(0, 10), null},
+            {YearMonth.of(1, 10), 12, ChronoUnit.YEARS, YearMonth.of(-11, 10), null},
+            {YearMonth.of(1, 10), 0, ChronoUnit.YEARS, YearMonth.of(1, 10), null},
+            {YearMonth.of(999999999, 12), 0, ChronoUnit.YEARS, YearMonth.of(999999999, 12), null},
+            {YearMonth.of(-999999999, 1), 0, ChronoUnit.YEARS, YearMonth.of(-999999999, 1), null},
+            {YearMonth.of(0, 1), 999999999, ChronoUnit.YEARS, YearMonth.of(-999999999, 1), null},
+            {YearMonth.of(0, 12), -999999999, ChronoUnit.YEARS, YearMonth.of(999999999, 12), null},
+
+            {YearMonth.of(1, 10), 1, ChronoUnit.MONTHS, YearMonth.of(1, 9), null},
+            {YearMonth.of(1, 10), 12, ChronoUnit.MONTHS, YearMonth.of(0, 10), null},
+            {YearMonth.of(1, 10), 0, ChronoUnit.MONTHS, YearMonth.of(1, 10), null},
+            {YearMonth.of(999999999, 12), 0, ChronoUnit.MONTHS, YearMonth.of(999999999, 12), null},
+            {YearMonth.of(-999999999, 1), 0, ChronoUnit.MONTHS, YearMonth.of(-999999999, 1), null},
+            {YearMonth.of(-999999999, 2), 1, ChronoUnit.MONTHS, YearMonth.of(-999999999, 1), null},
+            {YearMonth.of(999999999, 11), -1, ChronoUnit.MONTHS, YearMonth.of(999999999, 12), null},
+
+            {YearMonth.of(1, 10), 1, ChronoUnit.ERAS, YearMonth.of(0, 10), null},
+            {YearMonth.of(5, 10), 1, ChronoUnit.CENTURIES, YearMonth.of(-95, 10), null},
+            {YearMonth.of(5, 10), 1, ChronoUnit.DECADES, YearMonth.of(-5, 10), null},
+
+            {YearMonth.of(999999999, 12), -1, ChronoUnit.MONTHS, null, DateTimeException.class},
+            {YearMonth.of(-999999999, 1), 1, ChronoUnit.MONTHS, null, DateTimeException.class},
+
+            {YearMonth.of(1, 1), 0, ChronoUnit.DAYS, null, DateTimeException.class},
+            {YearMonth.of(1, 1), 0, ChronoUnit.WEEKS, null, DateTimeException.class},
+        };
+    }
+
+    @Test(groups={"tck"}, dataProvider="minus_long_TemporalUnit")
+    public void test_minus_long_TemporalUnit(YearMonth base, long amount, TemporalUnit unit, YearMonth expectedYearMonth, Class expectedEx) {
+        if (expectedEx == null) {
+            assertEquals(base.minus(amount, unit), expectedYearMonth);
+        } else {
+            try {
+                YearMonth result = base.minus(amount, unit);
+                fail();
+            } catch (Exception ex) {
+                assertTrue(expectedEx.isInstance(ex));
+            }
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    // minus(TemporalAmount)
+    //-----------------------------------------------------------------------
+    @DataProvider(name="minus_TemporalAmount")
+    Object[][] data_minus_TemporalAmount() {
+        return new Object[][] {
+            {YearMonth.of(1, 1), Period.ofYears(1), YearMonth.of(0, 1), null},
+            {YearMonth.of(1, 1), Period.ofYears(-12), YearMonth.of(13, 1), null},
+            {YearMonth.of(1, 1), Period.ofYears(0), YearMonth.of(1, 1), null},
+            {YearMonth.of(999999999, 12), Period.ofYears(0), YearMonth.of(999999999, 12), null},
+            {YearMonth.of(-999999999, 1), Period.ofYears(0), YearMonth.of(-999999999, 1), null},
+            {YearMonth.of(0, 1), Period.ofYears(999999999), YearMonth.of(-999999999, 1), null},
+            {YearMonth.of(0, 12), Period.ofYears(-999999999), YearMonth.of(999999999, 12), null},
+
+            {YearMonth.of(1, 1), Period.ofMonths(1), YearMonth.of(0, 12), null},
+            {YearMonth.of(1, 1), Period.ofMonths(-12), YearMonth.of(2, 1), null},
+            {YearMonth.of(1, 1), Period.ofMonths(121), YearMonth.of(-10, 12), null},
+            {YearMonth.of(1, 1), Period.ofMonths(0), YearMonth.of(1, 1), null},
+            {YearMonth.of(999999999, 12), Period.ofMonths(0), YearMonth.of(999999999, 12), null},
+            {YearMonth.of(-999999999, 1), Period.ofMonths(0), YearMonth.of(-999999999, 1), null},
+            {YearMonth.of(-999999999, 2), Period.ofMonths(1), YearMonth.of(-999999999, 1), null},
+            {YearMonth.of(999999999, 11), Period.ofMonths(-1), YearMonth.of(999999999, 12), null},
+
+            {YearMonth.of(1, 1), Period.ofYears(1).withMonths(2), YearMonth.of(-1, 11), null},
+            {YearMonth.of(1, 1), Period.ofYears(-12).withMonths(-1), YearMonth.of(13, 2), null},
+
+            {YearMonth.of(1, 1), Period.ofMonths(2).withYears(1), YearMonth.of(-1, 11), null},
+            {YearMonth.of(1, 1), Period.ofMonths(-1).withYears(-12), YearMonth.of(13, 2), null},
+
+            {YearMonth.of(1, 1), Period.ofDays(365), null, DateTimeException.class},
+            {YearMonth.of(1, 1), Duration.ofDays(365), null, DateTimeException.class},
+            {YearMonth.of(1, 1), Duration.ofHours(365*24), null, DateTimeException.class},
+            {YearMonth.of(1, 1), Duration.ofMinutes(365*24*60), null, DateTimeException.class},
+            {YearMonth.of(1, 1), Duration.ofSeconds(365*24*3600), null, DateTimeException.class},
+            {YearMonth.of(1, 1), Duration.ofNanos(365*24*3600*1000000000), null, DateTimeException.class},
+        };
+    }
+
+    @Test(groups={"tck"}, dataProvider="minus_TemporalAmount")
+    public void test_minus_TemporalAmount(YearMonth base, TemporalAmount temporalAmount, YearMonth expectedYearMonth, Class expectedEx) {
+        if (expectedEx == null) {
+            assertEquals(base.minus(temporalAmount), expectedYearMonth);
+        } else {
+            try {
+                YearMonth result = base.minus(temporalAmount);
+                fail();
+            } catch (Exception ex) {
+                assertTrue(expectedEx.isInstance(ex));
+            }
+        }
+    }
+
+    //-----------------------------------------------------------------------
     // adjustInto()
     //-----------------------------------------------------------------------
     @Test
diff --git a/jdk/test/java/time/tck/java/time/TCKZoneOffset.java b/jdk/test/java/time/tck/java/time/TCKZoneOffset.java
index 18882df..94f2eb5 100644
--- a/jdk/test/java/time/tck/java/time/TCKZoneOffset.java
+++ b/jdk/test/java/time/tck/java/time/TCKZoneOffset.java
@@ -73,8 +73,10 @@
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
+import java.time.OffsetDateTime;
 import java.time.temporal.ChronoField;
 import java.time.temporal.JulianFields;
 import java.time.temporal.TemporalAccessor;
@@ -620,6 +622,45 @@
     }
 
     //-----------------------------------------------------------------------
+    // adjustInto()
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_adjustInto_ZonedDateTime() {
+        ZoneOffset base = ZoneOffset.ofHoursMinutesSeconds(1, 1, 1);
+        for (String zoneId : ZoneId.getAvailableZoneIds()) {
+            //Do not change offset of ZonedDateTime after adjustInto()
+            ZonedDateTime zonedDateTime_target = ZonedDateTime.of(LocalDate.of(1909, 2, 2), LocalTime.of(10, 10, 10), ZoneId.of(zoneId));
+            ZonedDateTime zonedDateTime_result = (ZonedDateTime)(base.adjustInto(zonedDateTime_target));
+            assertEquals(zonedDateTime_target.getOffset(), zonedDateTime_result.getOffset());
+
+            OffsetDateTime offsetDateTime_target = zonedDateTime_target.toOffsetDateTime();
+            OffsetDateTime offsetDateTime_result = (OffsetDateTime)(base.adjustInto(offsetDateTime_target));
+            assertEquals(base, offsetDateTime_result.getOffset());
+        }
+    }
+
+    @Test
+    public void test_adjustInto_OffsetDateTime() {
+        ZoneOffset base = ZoneOffset.ofHoursMinutesSeconds(1, 1, 1);
+        for (int i=-18; i<=18; i++) {
+            OffsetDateTime offsetDateTime_target = OffsetDateTime.of(LocalDate.of(1909, 2, 2), LocalTime.of(10, 10, 10), ZoneOffset.ofHours(i));
+            OffsetDateTime offsetDateTime_result = (OffsetDateTime)base.adjustInto(offsetDateTime_target);
+            assertEquals(base, offsetDateTime_result.getOffset());
+
+            //Do not change offset of ZonedDateTime after adjustInto()
+            ZonedDateTime zonedDateTime_target = offsetDateTime_target.toZonedDateTime();
+            ZonedDateTime zonedDateTime_result = (ZonedDateTime)(base.adjustInto(zonedDateTime_target));
+            assertEquals(zonedDateTime_target.getOffset(), zonedDateTime_result.getOffset());
+        }
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_adjustInto_dateOnly() {
+        ZoneOffset base = ZoneOffset.ofHoursMinutesSeconds(1, 1, 1);
+        base.adjustInto((LocalDate.of(1909, 2, 2)));
+    }
+
+    //-----------------------------------------------------------------------
     // toString()
     //-----------------------------------------------------------------------
     @Test
diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java
index 17aadcc..0077be5 100644
--- a/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java
+++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java
@@ -162,39 +162,30 @@
     @DataProvider(name = "calendarsystemtype")
     Object[][] data_CalendarType() {
         return new Object[][] {
-            {HijrahChronology.INSTANCE, "islamic", "umalqura"},
-            {IsoChronology.INSTANCE, "iso8601", null},
-            {JapaneseChronology.INSTANCE, "japanese", null},
-            {MinguoChronology.INSTANCE, "roc", null},
-            {ThaiBuddhistChronology.INSTANCE, "buddhist", null},
+            {HijrahChronology.INSTANCE, "islamic-umalqura"},
+            {IsoChronology.INSTANCE, "iso8601"},
+            {JapaneseChronology.INSTANCE, "japanese"},
+            {MinguoChronology.INSTANCE, "roc"},
+            {ThaiBuddhistChronology.INSTANCE, "buddhist"},
         };
     }
 
     @Test(dataProvider = "calendarsystemtype")
-    public void test_getCalendarType(Chronology chrono, String calendarType, String variant) {
+    public void test_getCalendarType(Chronology chrono, String calendarType) {
         String type = calendarType;
-        if (variant != null) {
-            type += '-';
-            type += variant;
-        }
         assertEquals(chrono.getCalendarType(), type);
     }
 
     @Test(dataProvider = "calendarsystemtype")
-    public void test_lookupLocale(Chronology chrono, String calendarType, String variant) {
+    public void test_lookupLocale(Chronology chrono, String calendarType) {
         Locale.Builder builder = new Locale.Builder().setLanguage("en").setRegion("CA");
         builder.setUnicodeLocaleKeyword("ca", calendarType);
-        if (variant != null) {
-            builder.setUnicodeLocaleKeyword("cv", variant);
-        }
         Locale locale = builder.build();
         assertEquals(Chronology.ofLocale(locale), chrono);
     }
 
-
     /**
      * Test lookup by calendarType of each chronology.
-     * The calendarType is split on "-" to separate the calendar and variant.
      * Verify that the calendar can be found by {@link java.time.chrono.Chronology#ofLocale}.
      */
     @Test
@@ -202,15 +193,10 @@
         // Test that all available chronologies can be successfully found using ofLocale
         Set<Chronology> chronos = Chronology.getAvailableChronologies();
         for (Chronology chrono : chronos) {
-            String[] split = chrono.getCalendarType().split("-");
-
             Locale.Builder builder = new Locale.Builder().setLanguage("en").setRegion("CA");
-            builder.setUnicodeLocaleKeyword("ca", split[0]);
-            if (split.length > 1) {
-                builder.setUnicodeLocaleKeyword("cv", split[1]);
-            }
+            builder.setUnicodeLocaleKeyword("ca", chrono.getCalendarType());
             Locale locale = builder.build();
-            assertEquals(Chronology.ofLocale(locale), chrono, "Lookup by type and variant");
+            assertEquals(Chronology.ofLocale(locale), chrono, "Lookup by type");
         }
     }
 
@@ -218,7 +204,6 @@
     public void test_lookupLocale() {
         Locale.Builder builder = new Locale.Builder().setLanguage("en").setRegion("CA");
         builder.setUnicodeLocaleKeyword("ca", "xxx");
-        builder.setUnicodeLocaleKeyword("cv", "yyy");
 
         Locale locale = builder.build();
         Chronology.ofLocale(locale);
diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronologySerialization.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronologySerialization.java
index c4e4499..e9d5fb4 100644
--- a/jdk/test/java/time/tck/java/time/chrono/TCKChronologySerialization.java
+++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronologySerialization.java
@@ -93,7 +93,6 @@
     //-----------------------------------------------------------------------
     @Test(dataProvider="calendars")
     public void test_ChronoSerialization(Chronology chrono) throws Exception {
-        System.out.printf(" ChronoSerialization: %s%n", chrono);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ObjectOutputStream out = new ObjectOutputStream(baos);
         out.writeObject(chrono);
diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKHijrahChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKHijrahChronology.java
index 0efd1ab..81b3ab7 100644
--- a/jdk/test/java/time/tck/java/time/chrono/TCKHijrahChronology.java
+++ b/jdk/test/java/time/tck/java/time/chrono/TCKHijrahChronology.java
@@ -62,16 +62,20 @@
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
+import java.time.Clock;
 import java.time.DateTimeException;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.Month;
 import java.time.Period;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
 import java.time.chrono.ChronoLocalDate;
 import java.time.chrono.Chronology;
 import java.time.chrono.Era;
 import java.time.chrono.HijrahChronology;
 import java.time.chrono.HijrahDate;
+import java.time.chrono.HijrahEra;
 import java.time.chrono.IsoChronology;
 import java.time.chrono.MinguoChronology;
 import java.time.chrono.MinguoDate;
@@ -119,8 +123,11 @@
             //{HijrahChronology.INSTANCE.date(1324, 7, 3), LocalDate.of(1906, 8, 23)},
             //{HijrahChronology.INSTANCE.date(1324, 7, 4), LocalDate.of(1906, 8, 24)},
             //{HijrahChronology.INSTANCE.date(1325, 1, 1), LocalDate.of(1907, 2, 13)},
-            {HijrahChronology.INSTANCE.date(1434, 7, 1), LocalDate.of(2013, 5, 11)},
 
+            {HijrahChronology.INSTANCE.date(1434, 7, 1), LocalDate.of(2013, 5, 11)},
+            {HijrahChronology.INSTANCE.date(HijrahEra.AH, 1434, 7, 1), LocalDate.of(2013, 5, 11)},
+            {HijrahChronology.INSTANCE.dateYearDay(HijrahEra.AH, 1434, 178), LocalDate.of(2013, 5, 11)},
+            {HijrahChronology.INSTANCE.dateYearDay(1434, 178), LocalDate.of(2013, 5, 11)},
             //{HijrahChronology.INSTANCE.date(1500, 3, 3), LocalDate.of(2079, 1, 5)},
             //{HijrahChronology.INSTANCE.date(1500, 10, 28), LocalDate.of(2079, 8, 25)},
             //{HijrahChronology.INSTANCE.date(1500, 10, 29), LocalDate.of(2079, 8, 26)},
@@ -142,6 +149,26 @@
         assertEquals(hijrahDate.get(DAY_OF_WEEK), iso.get(DAY_OF_WEEK), "Hijrah day of week should be same as ISO day of week");
     }
 
+    @Test
+    public void test_dateNow(){
+        assertEquals(HijrahChronology.INSTANCE.dateNow(), HijrahDate.now()) ;
+        assertEquals(HijrahChronology.INSTANCE.dateNow(), HijrahDate.now(ZoneId.systemDefault())) ;
+        assertEquals(HijrahChronology.INSTANCE.dateNow(), HijrahDate.now(Clock.systemDefaultZone())) ;
+        assertEquals(HijrahChronology.INSTANCE.dateNow(), HijrahDate.now(Clock.systemDefaultZone().getZone())) ;
+
+        assertEquals(HijrahChronology.INSTANCE.dateNow(), HijrahChronology.INSTANCE.dateNow(ZoneId.systemDefault())) ;
+        assertEquals(HijrahChronology.INSTANCE.dateNow(), HijrahChronology.INSTANCE.dateNow(Clock.systemDefaultZone())) ;
+        assertEquals(HijrahChronology.INSTANCE.dateNow(), HijrahChronology.INSTANCE.dateNow(Clock.systemDefaultZone().getZone())) ;
+
+        ZoneId zoneId = ZoneId.of("Europe/Paris");
+        assertEquals(HijrahChronology.INSTANCE.dateNow(zoneId), HijrahChronology.INSTANCE.dateNow(Clock.system(zoneId))) ;
+        assertEquals(HijrahChronology.INSTANCE.dateNow(zoneId), HijrahChronology.INSTANCE.dateNow(Clock.system(zoneId).getZone())) ;
+        assertEquals(HijrahChronology.INSTANCE.dateNow(zoneId), HijrahDate.now(Clock.system(zoneId))) ;
+        assertEquals(HijrahChronology.INSTANCE.dateNow(zoneId), HijrahDate.now(Clock.system(zoneId).getZone())) ;
+
+        assertEquals(HijrahChronology.INSTANCE.dateNow(ZoneId.of(ZoneOffset.UTC.getId())), HijrahChronology.INSTANCE.dateNow(Clock.systemUTC())) ;
+    }
+
     @DataProvider(name="badDates")
     Object[][] data_badDates() {
         return new Object[][] {
diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java
index cd5e859..7802e5b 100644
--- a/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java
+++ b/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java
@@ -66,12 +66,15 @@
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
+import java.time.Clock;
 import java.time.DateTimeException;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.Month;
 import java.time.Period;
 import java.time.Year;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
 import java.time.chrono.ChronoLocalDate;
 import java.time.chrono.Chronology;
 import java.time.chrono.Era;
@@ -182,6 +185,16 @@
             {JapaneseChronology.INSTANCE.dateYearDay(1868, 60), LocalDate.of(1868, 2, 29)},
             {JapaneseChronology.INSTANCE.dateYearDay(1928, 60), LocalDate.of(1928, 2, 29)},
             {JapaneseChronology.INSTANCE.dateYearDay(1912, 60), LocalDate.of(1912, 2, 29)},
+
+            {JapaneseDate.ofYearDay(1996, 60), LocalDate.of(1996, 2, 29)},
+            {JapaneseDate.ofYearDay(1868, 60), LocalDate.of(1868, 2, 29)},
+            {JapaneseDate.ofYearDay(1928, 60), LocalDate.of(1928, 2, 29)},
+            {JapaneseDate.ofYearDay(1912, 60), LocalDate.of(1912, 2, 29)},
+
+            {JapaneseChronology.INSTANCE.dateYearDay(JapaneseEra.HEISEI, 1996 - YDIFF_HEISEI, 60), LocalDate.of(1996, 2, 29)},
+            {JapaneseChronology.INSTANCE.dateYearDay(JapaneseEra.MEIJI, 1868 - YDIFF_MEIJI, 60), LocalDate.of(1868, 2, 29)},
+            {JapaneseChronology.INSTANCE.dateYearDay(JapaneseEra.SHOWA, 1928 - YDIFF_SHOWA, 60), LocalDate.of(1928, 2, 29)},
+//          {JapaneseChronology.INSTANCE.dateYearDay(JapaneseEra.TAISHO, 1916 - YDIFF_TAISHO, 60), LocalDate.of(1912, 2, 29)},
         };
     }
 
@@ -195,6 +208,26 @@
         assertEquals(JapaneseChronology.INSTANCE.date(iso), jdate);
     }
 
+    @Test
+    public void test_dateNow(){
+        assertEquals(JapaneseChronology.INSTANCE.dateNow(), JapaneseDate.now()) ;
+        assertEquals(JapaneseChronology.INSTANCE.dateNow(), JapaneseDate.now(ZoneId.systemDefault())) ;
+        assertEquals(JapaneseChronology.INSTANCE.dateNow(), JapaneseDate.now(Clock.systemDefaultZone())) ;
+        assertEquals(JapaneseChronology.INSTANCE.dateNow(), JapaneseDate.now(Clock.systemDefaultZone().getZone())) ;
+
+        assertEquals(JapaneseChronology.INSTANCE.dateNow(), JapaneseChronology.INSTANCE.dateNow(ZoneId.systemDefault())) ;
+        assertEquals(JapaneseChronology.INSTANCE.dateNow(), JapaneseChronology.INSTANCE.dateNow(Clock.systemDefaultZone())) ;
+        assertEquals(JapaneseChronology.INSTANCE.dateNow(), JapaneseChronology.INSTANCE.dateNow(Clock.systemDefaultZone().getZone())) ;
+
+        ZoneId zoneId = ZoneId.of("Europe/Paris");
+        assertEquals(JapaneseChronology.INSTANCE.dateNow(zoneId), JapaneseChronology.INSTANCE.dateNow(Clock.system(zoneId))) ;
+        assertEquals(JapaneseChronology.INSTANCE.dateNow(zoneId), JapaneseChronology.INSTANCE.dateNow(Clock.system(zoneId).getZone())) ;
+        assertEquals(JapaneseChronology.INSTANCE.dateNow(zoneId), JapaneseDate.now(Clock.system(zoneId))) ;
+        assertEquals(JapaneseChronology.INSTANCE.dateNow(zoneId), JapaneseDate.now(Clock.system(zoneId).getZone())) ;
+
+        assertEquals(JapaneseChronology.INSTANCE.dateNow(ZoneId.of(ZoneOffset.UTC.getId())), JapaneseChronology.INSTANCE.dateNow(Clock.systemUTC())) ;
+    }
+
     @DataProvider(name="badDates")
     Object[][] data_badDates() {
         return new Object[][] {
@@ -232,8 +265,6 @@
         return new Object[][] {
                 {2, JapaneseEra.HEISEI, 1, 1 + YDIFF_HEISEI, false},
                 {2, JapaneseEra.HEISEI, 100, 100 + YDIFF_HEISEI, true},
-                {2, JapaneseEra.HEISEI, 0, YDIFF_HEISEI, true},
-                {2, JapaneseEra.HEISEI, -10, -10 + YDIFF_HEISEI, false},
 
                 {-1, JapaneseEra.MEIJI, 1, 1 + YDIFF_MEIJI, true},
                 {-1, JapaneseEra.MEIJI, 4, 4 + YDIFF_MEIJI, false},
diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java
index 04d9dd9..f6c7944 100644
--- a/jdk/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java
+++ b/jdk/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java
@@ -66,12 +66,15 @@
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
+import java.time.Clock;
 import java.time.DateTimeException;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.Month;
 import java.time.Period;
 import java.time.Year;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
 import java.time.chrono.ChronoLocalDate;
 import java.time.chrono.Chronology;
 import java.time.chrono.Era;
@@ -177,6 +180,15 @@
             {ThaiBuddhistChronology.INSTANCE.dateYearDay(400 + YDIFF, 60), LocalDate.of(400, 2, 29)},
             {ThaiBuddhistChronology.INSTANCE.dateYearDay(2000 + YDIFF, 60), LocalDate.of(2000, 2, 29)},
 
+            {ThaiBuddhistChronology.INSTANCE.dateYearDay(ThaiBuddhistEra.BE, 1916 + YDIFF, 60), LocalDate.of(1916, 2, 29)},
+            {ThaiBuddhistChronology.INSTANCE.dateYearDay(ThaiBuddhistEra.BEFORE_BE, -1907 - YDIFF, 60), LocalDate.of(1908, 2, 29)},
+            {ThaiBuddhistChronology.INSTANCE.dateYearDay(ThaiBuddhistEra.BE, 2000 + YDIFF, 60), LocalDate.of(2000, 2, 29)},
+            {ThaiBuddhistChronology.INSTANCE.dateYearDay(ThaiBuddhistEra.BE, 2400 + YDIFF, 60), LocalDate.of(2400, 2, 29)},
+
+            {ThaiBuddhistChronology.INSTANCE.date(ThaiBuddhistEra.BE, 1916 + YDIFF, 2, 29 ), LocalDate.of(1916, 2, 29)},
+            {ThaiBuddhistChronology.INSTANCE.date(ThaiBuddhistEra.BEFORE_BE, -1907 - YDIFF, 2, 29), LocalDate.of(1908, 2, 29)},
+            {ThaiBuddhistChronology.INSTANCE.date(ThaiBuddhistEra.BE, 2000 + YDIFF, 2, 29), LocalDate.of(2000, 2, 29)},
+            {ThaiBuddhistChronology.INSTANCE.date(ThaiBuddhistEra.BE, 2400 + YDIFF, 2, 29), LocalDate.of(2400, 2, 29)},
         };
     }
 
@@ -190,6 +202,26 @@
         assertEquals(ThaiBuddhistChronology.INSTANCE.date(iso), jdate);
     }
 
+    @Test
+    public void test_dateNow(){
+        assertEquals(ThaiBuddhistChronology.INSTANCE.dateNow(), ThaiBuddhistDate.now()) ;
+        assertEquals(ThaiBuddhistChronology.INSTANCE.dateNow(), ThaiBuddhistDate.now(ZoneId.systemDefault())) ;
+        assertEquals(ThaiBuddhistChronology.INSTANCE.dateNow(), ThaiBuddhistDate.now(Clock.systemDefaultZone())) ;
+        assertEquals(ThaiBuddhistChronology.INSTANCE.dateNow(), ThaiBuddhistDate.now(Clock.systemDefaultZone().getZone())) ;
+
+        assertEquals(ThaiBuddhistChronology.INSTANCE.dateNow(), ThaiBuddhistChronology.INSTANCE.dateNow(ZoneId.systemDefault())) ;
+        assertEquals(ThaiBuddhistChronology.INSTANCE.dateNow(), ThaiBuddhistChronology.INSTANCE.dateNow(Clock.systemDefaultZone())) ;
+        assertEquals(ThaiBuddhistChronology.INSTANCE.dateNow(), ThaiBuddhistChronology.INSTANCE.dateNow(Clock.systemDefaultZone().getZone())) ;
+
+        ZoneId zoneId = ZoneId.of("Europe/Paris");
+        assertEquals(ThaiBuddhistChronology.INSTANCE.dateNow(zoneId), ThaiBuddhistChronology.INSTANCE.dateNow(Clock.system(zoneId))) ;
+        assertEquals(ThaiBuddhistChronology.INSTANCE.dateNow(zoneId), ThaiBuddhistChronology.INSTANCE.dateNow(Clock.system(zoneId).getZone())) ;
+        assertEquals(ThaiBuddhistChronology.INSTANCE.dateNow(zoneId), ThaiBuddhistDate.now(Clock.system(zoneId))) ;
+        assertEquals(ThaiBuddhistChronology.INSTANCE.dateNow(zoneId), ThaiBuddhistDate.now(Clock.system(zoneId).getZone())) ;
+
+        assertEquals(ThaiBuddhistChronology.INSTANCE.dateNow(ZoneId.of(ZoneOffset.UTC.getId())), ThaiBuddhistChronology.INSTANCE.dateNow(Clock.systemUTC())) ;
+    }
+
     @DataProvider(name="badDates")
     Object[][] data_badDates() {
         return new Object[][] {
diff --git a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatter.java b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatter.java
index e8f137f..8e2091e 100644
--- a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatter.java
+++ b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatter.java
@@ -90,7 +90,7 @@
 import java.time.chrono.IsoChronology;
 import java.time.chrono.ThaiBuddhistChronology;
 import java.time.chrono.ThaiBuddhistDate;
-import java.time.format.DateTimeFormatSymbols;
+import java.time.format.DecimalStyle;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.DateTimeParseException;
@@ -134,14 +134,14 @@
     //-----------------------------------------------------------------------
     @Test
     public void test_withLocale() {
-        DateTimeFormatter base = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter base = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         DateTimeFormatter test = base.withLocale(Locale.GERMAN);
         assertEquals(test.getLocale(), Locale.GERMAN);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
     public void test_withLocale_null() {
-        DateTimeFormatter base = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter base = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         base.withLocale((Locale) null);
     }
 
@@ -192,7 +192,9 @@
                 .appendValue(YEAR).appendLiteral('-').appendValue(MONTH_OF_YEAR).appendLiteral('-')
                 .appendValue(DAY_OF_MONTH).appendLiteral('-').appendValue(DAY_OF_YEAR).toFormatter();
         DateTimeFormatter f = base.withResolverFields(YEAR, DAY_OF_YEAR);
-        assertEquals(f.getResolverFields(), new HashSet<>(Arrays.asList(YEAR, DAY_OF_YEAR)));
+        Set<TemporalField> expected = new HashSet<>(Arrays.asList(YEAR, DAY_OF_YEAR));
+        // Use set.equals();  testNG comparison of Collections is ordered
+        assertTrue(f.getResolverFields().equals(expected), "ResolveFields: " + f.getResolverFields());
         try {
             base.parse("2012-6-30-321", LocalDate::from);  // wrong month/day-of-month
             fail();
@@ -392,27 +394,27 @@
     //-----------------------------------------------------------------------
     @Test
     public void test_format_TemporalAccessor_simple() {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         String result = test.format(LocalDate.of(2008, 6, 30));
         assertEquals(result, "ONE30");
     }
 
     @Test(expectedExceptions = DateTimeException.class)
     public void test_format_TemporalAccessor_noSuchField() {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         test.format(LocalTime.of(11, 30));
     }
 
     @Test(expectedExceptions = NullPointerException.class)
     public void test_format_TemporalAccessor_null() {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         test.format((TemporalAccessor) null);
     }
 
     //-----------------------------------------------------------------------
     @Test
     public void test_print_TemporalAppendable() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         StringBuilder buf = new StringBuilder();
         test.formatTo(LocalDate.of(2008, 6, 30), buf);
         assertEquals(buf.toString(), "ONE30");
@@ -420,21 +422,21 @@
 
     @Test(expectedExceptions=DateTimeException.class)
     public void test_print_TemporalAppendable_noSuchField() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         StringBuilder buf = new StringBuilder();
         test.formatTo(LocalTime.of(11, 30), buf);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
     public void test_print_TemporalAppendable_nullTemporal() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         StringBuilder buf = new StringBuilder();
         test.formatTo((TemporalAccessor) null, buf);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
     public void test_print_TemporalAppendable_nullAppendable() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         test.formatTo(LocalDate.of(2008, 6, 30), (Appendable) null);
     }
 
@@ -443,7 +445,7 @@
     //-----------------------------------------------------------------------
     @Test
     public void test_parse_CharSequence() {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         TemporalAccessor result = test.parse("ONE30");
         assertEquals(result.isSupported(DAY_OF_MONTH), true);
         assertEquals(result.getLong(DAY_OF_MONTH), 30L);
@@ -466,7 +468,7 @@
 
     @Test(expectedExceptions=NullPointerException.class)
     public void test_parse_CharSequence_null() {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         test.parse((String) null);
     }
 
@@ -475,7 +477,7 @@
     //-----------------------------------------------------------------------
     @Test
     public void test_parse_CharSequence_ParsePosition() {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         ParsePosition pos = new ParsePosition(3);
         TemporalAccessor result = test.parse("XXXONE30XXX", pos);
         assertEquals(pos.getIndex(), 8);
@@ -523,13 +525,13 @@
 
     @Test(expectedExceptions=NullPointerException.class)
     public void test_parse_CharSequence_ParsePosition_nullText() {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         test.parse((CharSequence) null, new ParsePosition(0));
     }
 
     @Test(expectedExceptions=NullPointerException.class)
     public void test_parse_CharSequence_ParsePosition_nullParsePosition() {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         test.parse("Text", (ParsePosition) null);
     }
 
@@ -594,7 +596,7 @@
 
     @Test(expectedExceptions=NullPointerException.class)
     public void test_parse_Query_String_nullRule() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         test.parse("30", (TemporalQuery<?>) null);
     }
 
@@ -630,7 +632,7 @@
 
     @Test(expectedExceptions=DateTimeParseException.class)
     public void test_parseBest_String_parseErrorLongText() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         try {
             test.parseBest("ONEXXX67890123456789012345678901234567890123456789012345678901234567890123456789", ZonedDateTime::from, LocalDate::from);
         } catch (DateTimeParseException ex) {
@@ -644,7 +646,7 @@
 
     @Test(expectedExceptions=DateTimeParseException.class)
     public void test_parseBest_String_parseIncomplete() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         try {
             test.parseBest("ONE30SomethingElse", ZonedDateTime::from, LocalDate::from);
         } catch (DateTimeParseException ex) {
@@ -658,32 +660,32 @@
 
     @Test(expectedExceptions=NullPointerException.class)
     public void test_parseBest_String_nullText() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         test.parseBest((String) null, ZonedDateTime::from, LocalDate::from);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
     public void test_parseBest_String_nullRules() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         test.parseBest("30", (TemporalQuery<?>[]) null);
     }
 
     @Test(expectedExceptions=IllegalArgumentException.class)
     public void test_parseBest_String_zeroRules() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         test.parseBest("30", new TemporalQuery<?>[0]);
     }
 
     @Test(expectedExceptions=IllegalArgumentException.class)
     public void test_parseBest_String_oneRule() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         test.parseBest("30", LocalDate::from);
     }
 
     //-----------------------------------------------------------------------
     @Test
     public void test_parseUnresolved_StringParsePosition() {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         ParsePosition pos = new ParsePosition(0);
         TemporalAccessor result = test.parseUnresolved("ONE30XXX", pos);
         assertEquals(pos.getIndex(), 5);
@@ -693,7 +695,7 @@
 
     @Test
     public void test_parseUnresolved_StringParsePosition_parseError() {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         ParsePosition pos = new ParsePosition(0);
         TemporalAccessor result = test.parseUnresolved("ONEXXX", pos);
         assertEquals(pos.getIndex(), 0);
@@ -725,20 +727,20 @@
 
     @Test(expectedExceptions=NullPointerException.class)
     public void test_parseUnresolved_StringParsePosition_nullString() {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         ParsePosition pos = new ParsePosition(0);
         test.parseUnresolved((String) null, pos);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
     public void test_parseUnresolved_StringParsePosition_nullParsePosition() {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         test.parseUnresolved("ONE30", (ParsePosition) null);
     }
 
     @Test(expectedExceptions=IndexOutOfBoundsException.class)
     public void test_parseUnresolved_StringParsePosition_invalidPosition() {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         ParsePosition pos = new ParsePosition(6);
         test.parseUnresolved("ONE30", pos);
     }
@@ -747,7 +749,7 @@
     //-----------------------------------------------------------------------
     @Test
     public void test_toFormat_format() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         Format format = test.toFormat();
         String result = format.format(LocalDate.of(2008, 6, 30));
         assertEquals(result, "ONE30");
@@ -755,14 +757,14 @@
 
     @Test(expectedExceptions=NullPointerException.class)
     public void test_toFormat_format_null() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         Format format = test.toFormat();
         format.format(null);
     }
 
     @Test(expectedExceptions=IllegalArgumentException.class)
     public void test_toFormat_format_notTemporal() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         Format format = test.toFormat();
         format.format("Not a Temporal");
     }
@@ -770,7 +772,7 @@
     //-----------------------------------------------------------------------
     @Test
     public void test_toFormat_parseObject_String() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         Format format = test.toFormat();
         TemporalAccessor result = (TemporalAccessor) format.parseObject("ONE30");
         assertEquals(result.isSupported(DAY_OF_MONTH), true);
@@ -779,7 +781,7 @@
 
     @Test(expectedExceptions=ParseException.class)
     public void test_toFormat_parseObject_String_parseError() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         Format format = test.toFormat();
         try {
             format.parseObject("ONEXXX");
@@ -792,7 +794,7 @@
 
     @Test(expectedExceptions=ParseException.class)
     public void test_toFormat_parseObject_String_parseErrorLongText() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         Format format = test.toFormat();
         try {
             format.parseObject("ONEXXX67890123456789012345678901234567890123456789012345678901234567890123456789");
@@ -806,7 +808,7 @@
 
     @Test(expectedExceptions=NullPointerException.class)
     public void test_toFormat_parseObject_String_null() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         Format format = test.toFormat();
         format.parseObject((String) null);
     }
@@ -814,7 +816,7 @@
     //-----------------------------------------------------------------------
     @Test
     public void test_toFormat_parseObject_StringParsePosition() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         Format format = test.toFormat();
         ParsePosition pos = new ParsePosition(0);
         TemporalAccessor result = (TemporalAccessor) format.parseObject("ONE30XXX", pos);
@@ -826,7 +828,7 @@
 
     @Test
     public void test_toFormat_parseObject_StringParsePosition_parseError() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         Format format = test.toFormat();
         ParsePosition pos = new ParsePosition(0);
         TemporalAccessor result = (TemporalAccessor) format.parseObject("ONEXXX", pos);
@@ -838,7 +840,7 @@
     @Test(expectedExceptions=NullPointerException.class)
     public void test_toFormat_parseObject_StringParsePosition_nullString() throws Exception {
         // SimpleDateFormat has this behavior
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         Format format = test.toFormat();
         ParsePosition pos = new ParsePosition(0);
         format.parseObject((String) null, pos);
@@ -847,7 +849,7 @@
     @Test(expectedExceptions=NullPointerException.class)
     public void test_toFormat_parseObject_StringParsePosition_nullParsePosition() throws Exception {
         // SimpleDateFormat has this behavior
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         Format format = test.toFormat();
         format.parseObject("ONE30", (ParsePosition) null);
     }
@@ -855,7 +857,7 @@
     @Test
     public void test_toFormat_parseObject_StringParsePosition_invalidPosition_tooBig() throws Exception {
         // SimpleDateFormat has this behavior
-        DateTimeFormatter dtf = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter dtf = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         ParsePosition pos = new ParsePosition(6);
         Format test = dtf.toFormat();
         assertNull(test.parseObject("ONE30", pos));
@@ -865,7 +867,7 @@
     @Test
     public void test_toFormat_parseObject_StringParsePosition_invalidPosition_tooSmall() throws Exception {
         // SimpleDateFormat throws StringIndexOutOfBoundException
-        DateTimeFormatter dtf = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        DateTimeFormatter dtf = fmt.withLocale(Locale.ENGLISH).withDecimalStyle(DecimalStyle.STANDARD);
         ParsePosition pos = new ParsePosition(-1);
         Format test = dtf.toFormat();
         assertNull(test.parseObject("ONE30", pos));
diff --git a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatters.java b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatters.java
index 3ba962a..f30eb99 100644
--- a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatters.java
+++ b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatters.java
@@ -63,6 +63,7 @@
 import static java.time.temporal.ChronoField.DAY_OF_WEEK;
 import static java.time.temporal.ChronoField.DAY_OF_YEAR;
 import static java.time.temporal.ChronoField.HOUR_OF_DAY;
+import static java.time.temporal.ChronoField.INSTANT_SECONDS;
 import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
 import static java.time.temporal.ChronoField.NANO_OF_SECOND;
@@ -1180,6 +1181,52 @@
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
+    @DataProvider(name="sample_isoInstant")
+    Object[][] provider_sample_isoInstant() {
+        return new Object[][]{
+                {0, 0, "1970-01-01T00:00:00Z", null},
+                {0, null, "1970-01-01T00:00:00Z", null},
+                {0, -1, null, DateTimeException.class},
+
+                {-1, 0, "1969-12-31T23:59:59Z", null},
+                {1, 0, "1970-01-01T00:00:01Z", null},
+                {60, 0, "1970-01-01T00:01:00Z", null},
+                {3600, 0, "1970-01-01T01:00:00Z", null},
+                {86400, 0, "1970-01-02T00:00:00Z", null},
+
+                {0, 1, "1970-01-01T00:00:00.000000001Z", null},
+                {0, 2, "1970-01-01T00:00:00.000000002Z", null},
+                {0, 10, "1970-01-01T00:00:00.000000010Z", null},
+                {0, 100, "1970-01-01T00:00:00.000000100Z", null},
+        };
+    }
+
+    @Test(dataProvider="sample_isoInstant")
+    public void test_print_isoInstant(
+            long instantSecs, Integer nano, String expected, Class<?> expectedEx) {
+        TemporalAccessor test = buildAccessorInstant(instantSecs, nano);
+        if (expectedEx == null) {
+            assertEquals(DateTimeFormatter.ISO_INSTANT.format(test), expected);
+        } else {
+            try {
+                DateTimeFormatter.ISO_INSTANT.format(test);
+                fail();
+            } catch (Exception ex) {
+                assertTrue(expectedEx.isInstance(ex));
+            }
+        }
+    }
+
+    @Test(dataProvider="sample_isoInstant")
+    public void test_parse_isoInstant(
+            long instantSecs, Integer nano, String input, Class<?> invalid) {
+        if (input != null) {
+            TemporalAccessor parsed = DateTimeFormatter.ISO_INSTANT.parseUnresolved(input, new ParsePosition(0));
+            assertEquals(parsed.getLong(INSTANT_SECONDS), instantSecs);
+            assertEquals(parsed.getLong(NANO_OF_SECOND), (nano == null ? 0 : nano));
+        }
+    }
+
     @Test
     public void test_isoInstant_basics() {
         assertEquals(DateTimeFormatter.ISO_INSTANT.getChronology(), null);
@@ -1334,6 +1381,15 @@
         return mock;
     }
 
+    private TemporalAccessor buildAccessorInstant(long instantSecs, Integer nano) {
+        MockAccessor mock = new MockAccessor();
+        mock.fields.put(INSTANT_SECONDS, instantSecs);
+        if (nano != null) {
+            mock.fields.put(NANO_OF_SECOND, (long) nano);
+        }
+        return mock;
+    }
+
     private void buildCalendrical(Expected expected, String offsetId, String zoneId) {
         if (offsetId != null) {
             expected.add(ZoneOffset.of(offsetId));
diff --git a/jdk/test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java b/jdk/test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java
index 8b6c134..9b249f1 100644
--- a/jdk/test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java
+++ b/jdk/test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java
@@ -59,6 +59,9 @@
  */
 package tck.java.time.format;
 
+import static java.time.format.ResolverStyle.LENIENT;
+import static java.time.format.ResolverStyle.SMART;
+import static java.time.format.ResolverStyle.STRICT;
 import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH;
 import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR;
 import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH;
@@ -88,11 +91,15 @@
 import static java.time.temporal.ChronoField.YEAR;
 import static java.time.temporal.ChronoField.YEAR_OF_ERA;
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
 
 import java.time.LocalDate;
 import java.time.LocalTime;
+import java.time.Period;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.DateTimeParseException;
+import java.time.format.ResolverStyle;
 import java.time.temporal.IsoFields;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
@@ -519,4 +526,350 @@
         assertEquals(accessor.query(TemporalQuery.localTime()), null);
     }
 
+    //-----------------------------------------------------------------------
+    @DataProvider(name="resolveFourToTime")
+    Object[][] data_resolveFourToTime() {
+        return new Object[][]{
+                // merge
+                {null, 0, 0, 0, 0, LocalTime.of(0, 0, 0, 0), Period.ZERO},
+                {null, 1, 0, 0, 0, LocalTime.of(1, 0, 0, 0), Period.ZERO},
+                {null, 0, 2, 0, 0, LocalTime.of(0, 2, 0, 0), Period.ZERO},
+                {null, 0, 0, 3, 0, LocalTime.of(0, 0, 3, 0), Period.ZERO},
+                {null, 0, 0, 0, 4, LocalTime.of(0, 0, 0, 4), Period.ZERO},
+                {null, 1, 2, 3, 4, LocalTime.of(1, 2, 3, 4), Period.ZERO},
+                {null, 23, 59, 59, 123456789, LocalTime.of(23, 59, 59, 123456789), Period.ZERO},
+
+                {ResolverStyle.STRICT, 14, 59, 60, 123456789, null, null},
+                {ResolverStyle.SMART, 14, 59, 60, 123456789, null, null},
+                {ResolverStyle.LENIENT, 14, 59, 60, 123456789, LocalTime.of(15, 0, 0, 123456789), Period.ZERO},
+
+                {ResolverStyle.STRICT, 23, 59, 60, 123456789, null, null},
+                {ResolverStyle.SMART, 23, 59, 60, 123456789, null, null},
+                {ResolverStyle.LENIENT, 23, 59, 60, 123456789, LocalTime.of(0, 0, 0, 123456789), Period.ofDays(1)},
+
+                {ResolverStyle.STRICT, 24, 0, 0, 0, null, null},
+                {ResolverStyle.SMART, 24, 0, 0, 0, LocalTime.of(0, 0, 0, 0), Period.ofDays(1)},
+                {ResolverStyle.LENIENT, 24, 0, 0, 0, LocalTime.of(0, 0, 0, 0), Period.ofDays(1)},
+
+                {ResolverStyle.STRICT, 24, 1, 0, 0, null, null},
+                {ResolverStyle.SMART, 24, 1, 0, 0, null, null},
+                {ResolverStyle.LENIENT, 24, 1, 0, 0, LocalTime.of(0, 1, 0, 0), Period.ofDays(1)},
+
+                {ResolverStyle.STRICT, 25, 0, 0, 0, null, null},
+                {ResolverStyle.SMART, 25, 0, 0, 0, null, null},
+                {ResolverStyle.LENIENT, 25, 0, 0, 0, LocalTime.of(1, 0, 0, 0), Period.ofDays(1)},
+
+                {ResolverStyle.STRICT, 49, 2, 3, 4, null, null},
+                {ResolverStyle.SMART, 49, 2, 3, 4, null, null},
+                {ResolverStyle.LENIENT, 49, 2, 3, 4, LocalTime.of(1, 2, 3, 4), Period.ofDays(2)},
+
+                {ResolverStyle.STRICT, -1, 2, 3, 4, null, null},
+                {ResolverStyle.SMART, -1, 2, 3, 4, null, null},
+                {ResolverStyle.LENIENT, -1, 2, 3, 4, LocalTime.of(23, 2, 3, 4), Period.ofDays(-1)},
+
+                {ResolverStyle.STRICT, -6, 2, 3, 4, null, null},
+                {ResolverStyle.SMART, -6, 2, 3, 4, null, null},
+                {ResolverStyle.LENIENT, -6, 2, 3, 4, LocalTime.of(18, 2, 3, 4), Period.ofDays(-1)},
+
+                {ResolverStyle.STRICT, 25, 61, 61, 1_123456789, null, null},
+                {ResolverStyle.SMART, 25, 61, 61, 1_123456789, null, null},
+                {ResolverStyle.LENIENT, 25, 61, 61, 1_123456789, LocalTime.of(2, 2, 2, 123456789), Period.ofDays(1)},
+        };
+    }
+
+    @Test(dataProvider="resolveFourToTime")
+    public void test_resolveFourToTime(ResolverStyle style,
+                       long hour, long min, long sec, long nano, LocalTime expectedTime, Period excessPeriod) {
+        DateTimeFormatter f = new DateTimeFormatterBuilder()
+                .parseDefaulting(HOUR_OF_DAY, hour)
+                .parseDefaulting(MINUTE_OF_HOUR, min)
+                .parseDefaulting(SECOND_OF_MINUTE, sec)
+                .parseDefaulting(NANO_OF_SECOND, nano).toFormatter();
+
+        ResolverStyle[] styles = (style != null ? new ResolverStyle[] {style} : ResolverStyle.values());
+        for (ResolverStyle s : styles) {
+            if (expectedTime != null) {
+                TemporalAccessor accessor = f.withResolverStyle(s).parse("");
+                assertEquals(accessor.query(TemporalQuery.localDate()), null, "ResolverStyle: " + s);
+                assertEquals(accessor.query(TemporalQuery.localTime()), expectedTime, "ResolverStyle: " + s);
+                assertEquals(accessor.query(DateTimeFormatter.parsedExcessDays()), excessPeriod, "ResolverStyle: " + s);
+            } else {
+                try {
+                    f.withResolverStyle(style).parse("");
+                    fail();
+                } catch (DateTimeParseException ex) {
+                    // expected
+                }
+            }
+        }
+    }
+
+    @Test(dataProvider="resolveFourToTime")
+    public void test_resolveThreeToTime(ResolverStyle style,
+                                       long hour, long min, long sec, long nano, LocalTime expectedTime, Period excessPeriod) {
+        DateTimeFormatter f = new DateTimeFormatterBuilder()
+                .parseDefaulting(HOUR_OF_DAY, hour)
+                .parseDefaulting(MINUTE_OF_HOUR, min)
+                .parseDefaulting(SECOND_OF_MINUTE, sec).toFormatter();
+
+        ResolverStyle[] styles = (style != null ? new ResolverStyle[] {style} : ResolverStyle.values());
+        for (ResolverStyle s : styles) {
+            if (expectedTime != null) {
+                TemporalAccessor accessor = f.withResolverStyle(s).parse("");
+                assertEquals(accessor.query(TemporalQuery.localDate()), null, "ResolverStyle: " + s);
+                assertEquals(accessor.query(TemporalQuery.localTime()), expectedTime.minusNanos(nano), "ResolverStyle: " + s);
+                assertEquals(accessor.query(DateTimeFormatter.parsedExcessDays()), excessPeriod, "ResolverStyle: " + s);
+            } else {
+                try {
+                    f.withResolverStyle(style).parse("");
+                    fail();
+                } catch (DateTimeParseException ex) {
+                    // expected
+                }
+            }
+        }
+    }
+
+    @Test(dataProvider="resolveFourToTime")
+    public void test_resolveFourToDateTime(ResolverStyle style,
+                       long hour, long min, long sec, long nano, LocalTime expectedTime, Period excessPeriod) {
+        DateTimeFormatter f = new DateTimeFormatterBuilder()
+                .parseDefaulting(YEAR, 2012).parseDefaulting(MONTH_OF_YEAR, 6).parseDefaulting(DAY_OF_MONTH, 30)
+                .parseDefaulting(HOUR_OF_DAY, hour)
+                .parseDefaulting(MINUTE_OF_HOUR, min)
+                .parseDefaulting(SECOND_OF_MINUTE, sec)
+                .parseDefaulting(NANO_OF_SECOND, nano).toFormatter();
+
+        ResolverStyle[] styles = (style != null ? new ResolverStyle[] {style} : ResolverStyle.values());
+        if (expectedTime != null && excessPeriod != null) {
+            LocalDate expectedDate = LocalDate.of(2012, 6, 30).plus(excessPeriod);
+            for (ResolverStyle s : styles) {
+                TemporalAccessor accessor = f.withResolverStyle(s).parse("");
+                assertEquals(accessor.query(TemporalQuery.localDate()), expectedDate, "ResolverStyle: " + s);
+                assertEquals(accessor.query(TemporalQuery.localTime()), expectedTime, "ResolverStyle: " + s);
+                assertEquals(accessor.query(DateTimeFormatter.parsedExcessDays()), Period.ZERO, "ResolverStyle: " + s);
+            }
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="resolveSecondOfDay")
+    Object[][] data_resolveSecondOfDay() {
+        return new Object[][]{
+                {STRICT, 0, 0, 0},
+                {STRICT, 1, 1, 0},
+                {STRICT, 86399, 86399, 0},
+                {STRICT, -1, null, 0},
+                {STRICT, 86400, null, 0},
+
+                {SMART, 0, 0, 0},
+                {SMART, 1, 1, 0},
+                {SMART, 86399, 86399, 0},
+                {SMART, -1, null, 0},
+                {SMART, 86400, null, 0},
+
+                {LENIENT, 0, 0, 0},
+                {LENIENT, 1, 1, 0},
+                {LENIENT, 86399, 86399, 0},
+                {LENIENT, -1, 86399, -1},
+                {LENIENT, 86400, 0, 1},
+        };
+    }
+
+    @Test(dataProvider="resolveSecondOfDay")
+    public void test_resolveSecondOfDay(ResolverStyle style, long value, Integer expectedSecond, int expectedDays) {
+        String str = Long.toString(value);
+        DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(SECOND_OF_DAY).toFormatter();
+
+        if (expectedSecond != null) {
+            TemporalAccessor accessor = f.withResolverStyle(style).parse(str);
+            assertEquals(accessor.query(TemporalQuery.localDate()), null);
+            assertEquals(accessor.query(TemporalQuery.localTime()), LocalTime.ofSecondOfDay(expectedSecond));
+            assertEquals(accessor.query(DateTimeFormatter.parsedExcessDays()), Period.ofDays(expectedDays));
+        } else {
+            try {
+                f.withResolverStyle(style).parse(str);
+                fail();
+            } catch (DateTimeParseException ex) {
+                // expected
+            }
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="resolveMinuteOfDay")
+    Object[][] data_resolveMinuteOfDay() {
+        return new Object[][]{
+                {STRICT, 0, 0, 0},
+                {STRICT, 1, 1, 0},
+                {STRICT, 1439, 1439, 0},
+                {STRICT, -1, null, 0},
+                {STRICT, 1440, null, 0},
+
+                {SMART, 0, 0, 0},
+                {SMART, 1, 1, 0},
+                {SMART, 1439, 1439, 0},
+                {SMART, -1, null, 0},
+                {SMART, 1440, null, 0},
+
+                {LENIENT, 0, 0, 0},
+                {LENIENT, 1, 1, 0},
+                {LENIENT, 1439, 1439, 0},
+                {LENIENT, -1, 1439, -1},
+                {LENIENT, 1440, 0, 1},
+        };
+    }
+
+    @Test(dataProvider="resolveMinuteOfDay")
+    public void test_resolveMinuteOfDay(ResolverStyle style, long value, Integer expectedMinute, int expectedDays) {
+        String str = Long.toString(value);
+        DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(MINUTE_OF_DAY).toFormatter();
+
+        if (expectedMinute != null) {
+            TemporalAccessor accessor = f.withResolverStyle(style).parse(str);
+            assertEquals(accessor.query(TemporalQuery.localDate()), null);
+            assertEquals(accessor.query(TemporalQuery.localTime()), LocalTime.ofSecondOfDay(expectedMinute * 60));
+            assertEquals(accessor.query(DateTimeFormatter.parsedExcessDays()), Period.ofDays(expectedDays));
+        } else {
+            try {
+                f.withResolverStyle(style).parse(str);
+                fail();
+            } catch (DateTimeParseException ex) {
+                // expected
+            }
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="resolveClockHourOfDay")
+    Object[][] data_resolveClockHourOfDay() {
+        return new Object[][]{
+                {STRICT, 1, 1, 0},
+                {STRICT, 24, 0, 0},
+                {STRICT, 0, null, 0},
+                {STRICT, -1, null, 0},
+                {STRICT, 25, null, 0},
+
+                {SMART, 1, 1, 0},
+                {SMART, 24, 0, 0},
+                {SMART, 0, 0, 0},
+                {SMART, -1, null, 0},
+                {SMART, 25, null, 0},
+
+                {LENIENT, 1, 1, 0},
+                {LENIENT, 24, 0, 0},
+                {LENIENT, 0, 0, 0},
+                {LENIENT, -1, 23, -1},
+                {LENIENT, 25, 1, 1},
+        };
+    }
+
+    @Test(dataProvider="resolveClockHourOfDay")
+    public void test_resolveClockHourOfDay(ResolverStyle style, long value, Integer expectedHour, int expectedDays) {
+        String str = Long.toString(value);
+        DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(CLOCK_HOUR_OF_DAY).toFormatter();
+
+        if (expectedHour != null) {
+            TemporalAccessor accessor = f.withResolverStyle(style).parse(str);
+            assertEquals(accessor.query(TemporalQuery.localDate()), null);
+            assertEquals(accessor.query(TemporalQuery.localTime()), LocalTime.of(expectedHour, 0));
+            assertEquals(accessor.query(DateTimeFormatter.parsedExcessDays()), Period.ofDays(expectedDays));
+        } else {
+            try {
+                f.withResolverStyle(style).parse(str);
+                fail();
+            } catch (DateTimeParseException ex) {
+                // expected
+            }
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="resolveClockHourOfAmPm")
+    Object[][] data_resolveClockHourOfAmPm() {
+        return new Object[][]{
+                {STRICT, 1, 1},
+                {STRICT, 12, 0},
+                {STRICT, 0, null},
+                {STRICT, -1, null},
+                {STRICT, 13, null},
+
+                {SMART, 1, 1},
+                {SMART, 12, 0},
+                {SMART, 0, 0},
+                {SMART, -1, null},
+                {SMART, 13, null},
+
+                {LENIENT, 1, 1},
+                {LENIENT, 12, 0},
+                {LENIENT, 0, 0},
+                {LENIENT, -1, -1},
+                {LENIENT, 13, 13},
+        };
+    }
+
+    @Test(dataProvider="resolveClockHourOfAmPm")
+    public void test_resolveClockHourOfAmPm(ResolverStyle style, long value, Integer expectedValue) {
+        String str = Long.toString(value);
+        DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(CLOCK_HOUR_OF_AMPM).toFormatter();
+
+        if (expectedValue != null) {
+            TemporalAccessor accessor = f.withResolverStyle(style).parse(str);
+            assertEquals(accessor.query(TemporalQuery.localDate()), null);
+            assertEquals(accessor.query(TemporalQuery.localTime()), null);
+            assertEquals(accessor.isSupported(CLOCK_HOUR_OF_AMPM), false);
+            assertEquals(accessor.isSupported(HOUR_OF_AMPM), true);
+            assertEquals(accessor.getLong(HOUR_OF_AMPM), expectedValue.longValue());
+        } else {
+            try {
+                f.withResolverStyle(style).parse(str);
+                fail();
+            } catch (DateTimeParseException ex) {
+                // expected
+            }
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="resolveAmPm")
+    Object[][] data_resolveAmPm() {
+        return new Object[][]{
+                {STRICT, 0, 0},
+                {STRICT, 1, 1},
+                {STRICT, -1, null},
+                {STRICT, 2, null},
+
+                {SMART, 0, 0},
+                {SMART, 1, 1},
+                {SMART, -1, null},
+                {SMART, 2, null},
+
+                {LENIENT, 0, 0},
+                {LENIENT, 1, 1},
+                {LENIENT, -1, -1},
+                {LENIENT, 2, 2},
+        };
+    }
+
+    @Test(dataProvider="resolveAmPm")
+    public void test_resolveAmPm(ResolverStyle style, long value, Integer expectedValue) {
+        String str = Long.toString(value);
+        DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(AMPM_OF_DAY).toFormatter();
+
+        if (expectedValue != null) {
+            TemporalAccessor accessor = f.withResolverStyle(style).parse(str);
+            assertEquals(accessor.query(TemporalQuery.localDate()), null);
+            assertEquals(accessor.query(TemporalQuery.localTime()), null);
+            assertEquals(accessor.isSupported(AMPM_OF_DAY), true);
+            assertEquals(accessor.getLong(AMPM_OF_DAY), expectedValue.longValue());
+        } else {
+            try {
+                f.withResolverStyle(style).parse(str);
+                fail();
+            } catch (DateTimeParseException ex) {
+                // expected
+            }
+        }
+    }
+
 }
diff --git a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatSymbols.java b/jdk/test/java/time/tck/java/time/format/TCKDecimalStyle.java
similarity index 77%
rename from jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatSymbols.java
rename to jdk/test/java/time/tck/java/time/format/TCKDecimalStyle.java
index 9deec99..f5a4321 100644
--- a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatSymbols.java
+++ b/jdk/test/java/time/tck/java/time/format/TCKDecimalStyle.java
@@ -61,29 +61,30 @@
 
 import static org.testng.Assert.assertEquals;
 
-import java.time.format.DateTimeFormatSymbols;
+import java.time.format.DecimalStyle;
 import java.util.Arrays;
 import java.util.Locale;
+import java.util.Set;
 
 import org.testng.annotations.Test;
 
 /**
- * Test DateTimeFormatSymbols.
+ * Test DecimalStyle.
  */
 @Test
-public class TCKDateTimeFormatSymbols {
+public class TCKDecimalStyle {
 
     @Test
     public void test_getAvailableLocales() {
-        Locale[] locales = DateTimeFormatSymbols.getAvailableLocales();
-        assertEquals(locales.length > 0, true);
-        assertEquals(Arrays.asList(locales).contains(Locale.US), true);
+        Set<Locale> locales = DecimalStyle.getAvailableLocales();
+        assertEquals(locales.size() > 0, true, "locales: " + locales);
+        assertEquals(locales.contains(Locale.US), true, "Locale.US not found in available Locales");
     }
 
     //-----------------------------------------------------------------------
     @Test
     public void test_of_Locale() {
-        DateTimeFormatSymbols loc1 = DateTimeFormatSymbols.of(Locale.CANADA);
+        DecimalStyle loc1 = DecimalStyle.of(Locale.CANADA);
         assertEquals(loc1.getZeroDigit(), '0');
         assertEquals(loc1.getPositiveSign(), '+');
         assertEquals(loc1.getNegativeSign(), '-');
@@ -93,7 +94,7 @@
     //-----------------------------------------------------------------------
     @Test
     public void test_STANDARD() {
-        DateTimeFormatSymbols loc1 = DateTimeFormatSymbols.STANDARD;
+        DecimalStyle loc1 = DecimalStyle.STANDARD;
         assertEquals(loc1.getZeroDigit(), '0');
         assertEquals(loc1.getPositiveSign(), '+');
         assertEquals(loc1.getNegativeSign(), '-');
@@ -103,25 +104,25 @@
     //-----------------------------------------------------------------------
     @Test
     public void test_zeroDigit() {
-        DateTimeFormatSymbols base = DateTimeFormatSymbols.STANDARD;
+        DecimalStyle base = DecimalStyle.STANDARD;
         assertEquals(base.withZeroDigit('A').getZeroDigit(), 'A');
     }
 
     @Test
     public void test_positiveSign() {
-        DateTimeFormatSymbols base = DateTimeFormatSymbols.STANDARD;
+        DecimalStyle base = DecimalStyle.STANDARD;
         assertEquals(base.withPositiveSign('A').getPositiveSign(), 'A');
     }
 
     @Test
     public void test_negativeSign() {
-        DateTimeFormatSymbols base = DateTimeFormatSymbols.STANDARD;
+        DecimalStyle base = DecimalStyle.STANDARD;
         assertEquals(base.withNegativeSign('A').getNegativeSign(), 'A');
     }
 
     @Test
     public void test_decimalSeparator() {
-        DateTimeFormatSymbols base = DateTimeFormatSymbols.STANDARD;
+        DecimalStyle base = DecimalStyle.STANDARD;
         assertEquals(base.withDecimalSeparator('A').getDecimalSeparator(), 'A');
     }
 
@@ -129,7 +130,7 @@
     /* TBD: convertToDigit and convertNumberToI18N are package-private methods
     @Test
     public void test_convertToDigit_base() {
-        DateTimeFormatSymbols base = DateTimeFormatSymbols.STANDARD;
+        DecimalStyle base = DecimalStyle.STANDARD;
         assertEquals(base.convertToDigit('0'), 0);
         assertEquals(base.convertToDigit('1'), 1);
         assertEquals(base.convertToDigit('9'), 9);
@@ -139,7 +140,7 @@
 
     @Test
     public void test_convertToDigit_altered() {
-        DateTimeFormatSymbols base = DateTimeFormatSymbols.STANDARD.withZeroDigit('A');
+        DecimalStyle base = DecimalStyle.STANDARD.withZeroDigit('A');
         assertEquals(base.convertToDigit('A'), 0);
         assertEquals(base.convertToDigit('B'), 1);
         assertEquals(base.convertToDigit('J'), 9);
@@ -150,21 +151,21 @@
     //-----------------------------------------------------------------------
     @Test
     public void test_convertNumberToI18N_base() {
-        DateTimeFormatSymbols base = DateTimeFormatSymbols.STANDARD;
+        DecimalStyle base = DecimalStyle.STANDARD;
         assertEquals(base.convertNumberToI18N("134"), "134");
     }
 
     @Test
     public void test_convertNumberToI18N_altered() {
-        DateTimeFormatSymbols base = DateTimeFormatSymbols.STANDARD.withZeroDigit('A');
+        DecimalStyle base = DecimalStyle.STANDARD.withZeroDigit('A');
         assertEquals(base.convertNumberToI18N("134"), "BDE");
     }
     */
     //-----------------------------------------------------------------------
     @Test
     public void test_equalsHashCode1() {
-        DateTimeFormatSymbols a = DateTimeFormatSymbols.STANDARD;
-        DateTimeFormatSymbols b = DateTimeFormatSymbols.STANDARD;
+        DecimalStyle a = DecimalStyle.STANDARD;
+        DecimalStyle b = DecimalStyle.STANDARD;
         assertEquals(a.equals(b), true);
         assertEquals(b.equals(a), true);
         assertEquals(a.hashCode(), b.hashCode());
@@ -172,8 +173,8 @@
 
     @Test
     public void test_equalsHashCode2() {
-        DateTimeFormatSymbols a = DateTimeFormatSymbols.STANDARD.withZeroDigit('A');
-        DateTimeFormatSymbols b = DateTimeFormatSymbols.STANDARD.withZeroDigit('A');
+        DecimalStyle a = DecimalStyle.STANDARD.withZeroDigit('A');
+        DecimalStyle b = DecimalStyle.STANDARD.withZeroDigit('A');
         assertEquals(a.equals(b), true);
         assertEquals(b.equals(a), true);
         assertEquals(a.hashCode(), b.hashCode());
@@ -181,15 +182,15 @@
 
     @Test
     public void test_equalsHashCode3() {
-        DateTimeFormatSymbols a = DateTimeFormatSymbols.STANDARD.withZeroDigit('A');
-        DateTimeFormatSymbols b = DateTimeFormatSymbols.STANDARD.withDecimalSeparator('A');
+        DecimalStyle a = DecimalStyle.STANDARD.withZeroDigit('A');
+        DecimalStyle b = DecimalStyle.STANDARD.withDecimalSeparator('A');
         assertEquals(a.equals(b), false);
         assertEquals(b.equals(a), false);
     }
 
     @Test
     public void test_equalsHashCode_bad() {
-        DateTimeFormatSymbols a = DateTimeFormatSymbols.STANDARD;
+        DecimalStyle a = DecimalStyle.STANDARD;
         assertEquals(a.equals(""), false);
         assertEquals(a.equals(null), false);
     }
@@ -197,14 +198,14 @@
     //-----------------------------------------------------------------------
     @Test
     public void test_toString_base() {
-        DateTimeFormatSymbols base = DateTimeFormatSymbols.STANDARD;
-        assertEquals(base.toString(), "Symbols[0+-.]");
+        DecimalStyle base = DecimalStyle.STANDARD;
+        assertEquals(base.toString(), "DecimalStyle[0+-.]");
     }
 
     @Test
     public void test_toString_altered() {
-        DateTimeFormatSymbols base = DateTimeFormatSymbols.of(Locale.US).withZeroDigit('A').withDecimalSeparator('@');
-        assertEquals(base.toString(), "Symbols[A+-@]");
+        DecimalStyle base = DecimalStyle.of(Locale.US).withZeroDigit('A').withDecimalSeparator('@');
+        assertEquals(base.toString(), "DecimalStyle[A+-@]");
     }
 
 }
diff --git a/jdk/test/java/time/tck/java/time/format/TCKInstantPrinterParser.java b/jdk/test/java/time/tck/java/time/format/TCKInstantPrinterParser.java
new file mode 100644
index 0000000..ebd9050
--- /dev/null
+++ b/jdk/test/java/time/tck/java/time/format/TCKInstantPrinterParser.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2010-2013, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package tck.java.time.format;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+import java.time.DateTimeException;
+import java.time.Instant;
+import java.time.OffsetDateTime;
+import java.time.Period;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.ResolverStyle;
+import java.time.temporal.TemporalAccessor;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Test DateTimeFormatterBuilder.appendInstant().
+ */
+@Test
+public class TCKInstantPrinterParser {
+
+    @DataProvider(name="printGrouped")
+    Object[][] data_printGrouped() {
+        return new Object[][] {
+                {0, 0, "1970-01-01T00:00:00Z"},
+
+                {-1, 0, "1969-12-31T23:59:59Z"},
+                {1, 0, "1970-01-01T00:00:01Z"},
+                {60, 0, "1970-01-01T00:01:00Z"},
+                {3600, 0, "1970-01-01T01:00:00Z"},
+                {86400, 0, "1970-01-02T00:00:00Z"},
+
+                {182, 2, "1970-01-01T00:03:02.000000002Z"},
+                {182, 20, "1970-01-01T00:03:02.000000020Z"},
+                {182, 200, "1970-01-01T00:03:02.000000200Z"},
+                {182, 2000, "1970-01-01T00:03:02.000002Z"},
+                {182, 20000, "1970-01-01T00:03:02.000020Z"},
+                {182, 200000, "1970-01-01T00:03:02.000200Z"},
+                {182, 2000000, "1970-01-01T00:03:02.002Z"},
+                {182, 20000000, "1970-01-01T00:03:02.020Z"},
+                {182, 200000000, "1970-01-01T00:03:02.200Z"},
+
+                {Instant.MAX.getEpochSecond(), 999999999, "+1000000000-12-31T23:59:59.999999999Z"},
+                {Instant.MIN.getEpochSecond(), 0, "-1000000000-01-01T00:00:00Z"},
+        };
+    }
+
+    @Test(dataProvider="printGrouped")
+    public void test_print_grouped(long instantSecs, int nano, String expected) {
+        Instant instant = Instant.ofEpochSecond(instantSecs, nano);
+        DateTimeFormatter f = new DateTimeFormatterBuilder().appendInstant().toFormatter();
+        assertEquals(f.format(instant), expected);
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="printDigits")
+    Object[][] data_printDigits() {
+        return new Object[][] {
+                {-1, 0, 0, "1970-01-01T00:00:00Z"},
+                {0, 0, 0, "1970-01-01T00:00:00Z"},
+                {1, 0, 0, "1970-01-01T00:00:00.0Z"},
+                {3, 0, 0, "1970-01-01T00:00:00.000Z"},
+                {9, 0, 0, "1970-01-01T00:00:00.000000000Z"},
+
+                {-1, -1, 0, "1969-12-31T23:59:59Z"},
+                {-1, 1, 0, "1970-01-01T00:00:01Z"},
+                {-1, 60, 0, "1970-01-01T00:01:00Z"},
+                {-1, 3600, 0, "1970-01-01T01:00:00Z"},
+                {-1, 86400, 0, "1970-01-02T00:00:00Z"},
+
+                {-1, 182, 2, "1970-01-01T00:03:02.000000002Z"},
+                {-1, 182, 20, "1970-01-01T00:03:02.00000002Z"},
+                {-1, 182, 200, "1970-01-01T00:03:02.0000002Z"},
+                {-1, 182, 2000, "1970-01-01T00:03:02.000002Z"},
+                {-1, 182, 20000, "1970-01-01T00:03:02.00002Z"},
+                {-1, 182, 200000, "1970-01-01T00:03:02.0002Z"},
+                {-1, 182, 2000000, "1970-01-01T00:03:02.002Z"},
+                {-1, 182, 20000000, "1970-01-01T00:03:02.02Z"},
+                {-1, 182, 200000000, "1970-01-01T00:03:02.2Z"},
+
+                {0, 182, 2, "1970-01-01T00:03:02Z"},
+                {0, 182, 20, "1970-01-01T00:03:02Z"},
+                {0, 182, 200, "1970-01-01T00:03:02Z"},
+                {0, 182, 2000, "1970-01-01T00:03:02Z"},
+                {0, 182, 20000, "1970-01-01T00:03:02Z"},
+                {0, 182, 200000, "1970-01-01T00:03:02Z"},
+                {0, 182, 2000000, "1970-01-01T00:03:02Z"},
+                {0, 182, 20000000, "1970-01-01T00:03:02Z"},
+                {0, 182, 200000000, "1970-01-01T00:03:02Z"},
+
+                {1, 182, 2, "1970-01-01T00:03:02.0Z"},
+                {1, 182, 20, "1970-01-01T00:03:02.0Z"},
+                {1, 182, 200, "1970-01-01T00:03:02.0Z"},
+                {1, 182, 2000, "1970-01-01T00:03:02.0Z"},
+                {1, 182, 20000, "1970-01-01T00:03:02.0Z"},
+                {1, 182, 200000, "1970-01-01T00:03:02.0Z"},
+                {1, 182, 2000000, "1970-01-01T00:03:02.0Z"},
+                {1, 182, 20000000, "1970-01-01T00:03:02.0Z"},
+                {1, 182, 200000000, "1970-01-01T00:03:02.2Z"},
+
+                {3, 182, 2, "1970-01-01T00:03:02.000Z"},
+                {3, 182, 20, "1970-01-01T00:03:02.000Z"},
+                {3, 182, 200, "1970-01-01T00:03:02.000Z"},
+                {3, 182, 2000, "1970-01-01T00:03:02.000Z"},
+                {3, 182, 20000, "1970-01-01T00:03:02.000Z"},
+                {3, 182, 200000, "1970-01-01T00:03:02.000Z"},
+                {3, 182, 2000000, "1970-01-01T00:03:02.002Z"},
+                {3, 182, 20000000, "1970-01-01T00:03:02.020Z"},
+                {3, 182, 200000000, "1970-01-01T00:03:02.200Z"},
+
+                {9, 182, 2, "1970-01-01T00:03:02.000000002Z"},
+                {9, 182, 20, "1970-01-01T00:03:02.000000020Z"},
+                {9, 182, 200, "1970-01-01T00:03:02.000000200Z"},
+                {9, 182, 2000, "1970-01-01T00:03:02.000002000Z"},
+                {9, 182, 20000, "1970-01-01T00:03:02.000020000Z"},
+                {9, 182, 200000, "1970-01-01T00:03:02.000200000Z"},
+                {9, 182, 2000000, "1970-01-01T00:03:02.002000000Z"},
+                {9, 182, 20000000, "1970-01-01T00:03:02.020000000Z"},
+                {9, 182, 200000000, "1970-01-01T00:03:02.200000000Z"},
+
+                {9, Instant.MAX.getEpochSecond(), 999999999, "+1000000000-12-31T23:59:59.999999999Z"},
+                {9, Instant.MIN.getEpochSecond(), 0, "-1000000000-01-01T00:00:00.000000000Z"},
+        };
+    }
+
+    @Test(dataProvider="printDigits")
+    public void test_print_digits(int fractionalDigits, long instantSecs, int nano, String expected) {
+        Instant instant = Instant.ofEpochSecond(instantSecs, nano);
+        DateTimeFormatter f = new DateTimeFormatterBuilder().appendInstant(fractionalDigits).toFormatter();
+        assertEquals(f.format(instant), expected);
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="parseDigits")
+    Object[][] data_parse_digits() {
+        return new Object[][] {
+                {0, 0, "1970-01-01T00:00:00Z"},
+                {0, 0, "1970-01-01T00:00:00Z"},
+                {0, 0, "1970-01-01T00:00:00.0Z"},
+                {0, 0, "1970-01-01T00:00:00.000Z"},
+                {0, 0, "1970-01-01T00:00:00.000000000Z"},
+
+                {-1, 0, "1969-12-31T23:59:59Z"},
+                {1, 0, "1970-01-01T00:00:01Z"},
+                {60, 0, "1970-01-01T00:01:00Z"},
+                {3600, 0, "1970-01-01T01:00:00Z"},
+                {86400, 0, "1970-01-02T00:00:00Z"},
+
+                {182, 234000000, "1970-01-01T00:03:02.234Z"},
+                {182, 234000000, "1970-01-01T00:03:02.2340Z"},
+                {182, 234000000, "1970-01-01T00:03:02.23400Z"},
+                {182, 234000000, "1970-01-01T00:03:02.234000Z"},
+                {182, 234000000, "1970-01-01T00:03:02.234000000Z"},
+
+                {((23 * 60) + 59) * 60 + 59, 123456789, "1970-01-01T23:59:59.123456789Z"},
+
+                {Instant.MAX.getEpochSecond(), 999999999, "+1000000000-12-31T23:59:59.999999999Z"},
+                {Instant.MIN.getEpochSecond(), 0, "-1000000000-01-01T00:00:00.000000000Z"},
+        };
+    }
+
+    @Test(dataProvider="parseDigits")
+    public void test_parse_digitsMinusOne(long instantSecs, int nano, String input) {
+        Instant expected = Instant.ofEpochSecond(instantSecs, nano);
+        DateTimeFormatter f = new DateTimeFormatterBuilder().appendInstant(-1).toFormatter();
+        assertEquals(f.parse(input, Instant::from), expected);
+        assertEquals(f.parse(input).query(DateTimeFormatter.parsedExcessDays()), Period.ZERO);
+        assertEquals(f.parse(input).query(DateTimeFormatter.parsedLeapSecond()), Boolean.FALSE);
+    }
+
+    @Test(dataProvider="parseDigits")
+    public void test_parse_digitsNine(long instantSecs, int nano, String input) {
+        DateTimeFormatter f = new DateTimeFormatterBuilder().appendInstant(9).toFormatter();
+        if (input.charAt(input.length() - 11) == '.') {
+            Instant expected = Instant.ofEpochSecond(instantSecs, nano);
+            assertEquals(f.parse(input, Instant::from), expected);
+            assertEquals(f.parse(input).query(DateTimeFormatter.parsedExcessDays()), Period.ZERO);
+            assertEquals(f.parse(input).query(DateTimeFormatter.parsedLeapSecond()), Boolean.FALSE);
+        } else {
+            try {
+                f.parse(input, Instant::from);
+                fail();
+            } catch (DateTimeException ex) {
+                // expected
+            }
+        }
+    }
+
+    @Test
+    public void test_parse_endOfDay() {
+        Instant expected = OffsetDateTime.of(1970, 2, 4, 0, 0, 0, 0, ZoneOffset.UTC).toInstant();
+        DateTimeFormatter f = new DateTimeFormatterBuilder().appendInstant(-1).toFormatter();
+        for (ResolverStyle style : ResolverStyle.values()) {
+            TemporalAccessor parsed = f.withResolverStyle(style).parse("1970-02-03T24:00:00Z");
+            assertEquals(parsed.query(Instant::from), expected);
+            assertEquals(parsed.query(DateTimeFormatter.parsedExcessDays()), Period.ZERO);
+            assertEquals(parsed.query(DateTimeFormatter.parsedLeapSecond()), Boolean.FALSE);
+        }
+    }
+
+    @Test
+    public void test_parse_leapSecond() {
+        Instant expected = OffsetDateTime.of(1970, 2, 3, 23, 59, 59, 123456789, ZoneOffset.UTC).toInstant();
+        DateTimeFormatter f = new DateTimeFormatterBuilder().appendInstant(-1).toFormatter();
+        for (ResolverStyle style : ResolverStyle.values()) {
+            TemporalAccessor parsed = f.withResolverStyle(style).parse("1970-02-03T23:59:60.123456789Z");
+            assertEquals(parsed.query(Instant::from), expected);
+            assertEquals(parsed.query(DateTimeFormatter.parsedExcessDays()), Period.ZERO);
+            assertEquals(parsed.query(DateTimeFormatter.parsedLeapSecond()), Boolean.TRUE);
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_appendInstant_tooSmall() {
+        new DateTimeFormatterBuilder().appendInstant(-2);
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_appendInstant_tooBig() {
+        new DateTimeFormatterBuilder().appendInstant(10);
+    }
+
+}
diff --git a/jdk/test/java/time/tck/java/time/format/TCKTextStyle.java b/jdk/test/java/time/tck/java/time/format/TCKTextStyle.java
index 4e80960..344a870 100644
--- a/jdk/test/java/time/tck/java/time/format/TCKTextStyle.java
+++ b/jdk/test/java/time/tck/java/time/format/TCKTextStyle.java
@@ -67,7 +67,7 @@
 import org.testng.annotations.Test;
 
 /**
- * Test DateTimeFormatSymbols.
+ * Test DecimalStyle.
  */
 @Test
 public class TCKTextStyle {
diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java b/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java
index 748b528..ccb1a4c 100644
--- a/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java
+++ b/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java
@@ -71,7 +71,6 @@
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.temporal.ChronoUnit;
-import java.time.temporal.JulianFields;
 import java.time.temporal.TemporalField;
 import java.time.temporal.ValueRange;
 import java.time.temporal.WeekFields;
@@ -161,9 +160,6 @@
         TemporalField dowField = week.dayOfWeek();
         TemporalField womField = week.weekOfMonth();
 
-        DayOfWeek isoDOW = day.getDayOfWeek();
-        int dow = (7 + isoDOW.getValue() - firstDayOfWeek.getValue()) % 7 + 1;
-
         for (int i = 1; i <= 15; i++) {
             int actualDOW = day.get(dowField);
             int actualWOM = day.get(womField);
@@ -197,9 +193,6 @@
         TemporalField dowField = week.dayOfWeek();
         TemporalField woyField = week.weekOfYear();
 
-        DayOfWeek isoDOW = day.getDayOfWeek();
-        int dow = (7 + isoDOW.getValue() - firstDayOfWeek.getValue()) % 7 + 1;
-
         for (int i = 1; i <= 15; i++) {
             int actualDOW = day.get(dowField);
             int actualWOY = day.get(woyField);
@@ -470,6 +463,28 @@
     public void test_parse_resolve_localizedWoWBY(DayOfWeek firstDayOfWeek, int minDays) {
         LocalDate date = LocalDate.of(2012, 12, 31);
         WeekFields week = WeekFields.of(firstDayOfWeek, minDays);
+        TemporalField wowbyField = week.weekOfWeekBasedYear();
+        TemporalField yowbyField = week.weekBasedYear();
+
+        for (int i = 1; i <= 60; i++) {
+            // Test that with dayOfWeek, week of year and year of week-based-year it computes the date
+            DateTimeFormatter f = new DateTimeFormatterBuilder()
+                    .appendValue(yowbyField).appendLiteral('-')
+                    .appendValue(wowbyField).appendLiteral('-')
+                    .appendValue(DAY_OF_WEEK).toFormatter();
+            String str = date.get(yowbyField) + "-" + date.get(wowbyField) + "-" +
+                    date.get(DAY_OF_WEEK);
+            LocalDate parsed = LocalDate.parse(str, f);
+            assertEquals(parsed, date, " :: " + str + " " + i);
+
+            date = date.plusDays(1);
+        }
+    }
+
+    @Test(dataProvider="weekFields")
+    public void test_parse_resolve_localizedWoWBYDow(DayOfWeek firstDayOfWeek, int minDays) {
+        LocalDate date = LocalDate.of(2012, 12, 31);
+        WeekFields week = WeekFields.of(firstDayOfWeek, minDays);
         TemporalField dowField = week.dayOfWeek();
         TemporalField wowbyField = week.weekOfWeekBasedYear();
         TemporalField yowbyField = week.weekBasedYear();
diff --git a/jdk/test/java/time/test/java/time/chrono/TestChronologyPerf.java b/jdk/test/java/time/test/java/time/chrono/TestChronologyPerf.java
index 8d73568..e8b3a00 100644
--- a/jdk/test/java/time/test/java/time/chrono/TestChronologyPerf.java
+++ b/jdk/test/java/time/test/java/time/chrono/TestChronologyPerf.java
@@ -26,6 +26,8 @@
 
 import java.time.Duration;
 import java.time.chrono.Chronology;
+import java.time.chrono.HijrahChronology;
+import java.time.chrono.HijrahDate;
 import java.time.temporal.ChronoUnit;
 import java.util.Set;
 
@@ -42,7 +44,19 @@
         Set<Chronology> chronos = Chronology.getAvailableChronologies();
         long end = System.nanoTime();
         Duration d = Duration.of(end - start, ChronoUnit.NANOS);
-        System.out.printf(" Duration of Chronology.getAvailableChronologies(): %s%n", d);
+        System.out.printf(" Cold Duration of Chronology.getAvailableChronologies(): %s%n", d);
+
+        start = System.nanoTime();
+        chronos = Chronology.getAvailableChronologies();
+        end = System.nanoTime();
+        d = Duration.of(end - start, ChronoUnit.NANOS);
+        System.out.printf(" Warm Duration of Chronology.getAvailableChronologies(): %s%n", d);
+
+        start = System.nanoTime();
+        HijrahChronology.INSTANCE.date(1434, 1, 1);
+        end = System.nanoTime();
+        d = Duration.of(end - start, ChronoUnit.NANOS);
+        System.out.printf(" Warm Duration of HijrahDate.date(1434, 1, 1): %s%n", d);
     }
 
 }
diff --git a/jdk/test/java/time/test/java/time/chrono/TestExampleCode.java b/jdk/test/java/time/test/java/time/chrono/TestExampleCode.java
index d387c88..cfa478f 100644
--- a/jdk/test/java/time/test/java/time/chrono/TestExampleCode.java
+++ b/jdk/test/java/time/test/java/time/chrono/TestExampleCode.java
@@ -109,21 +109,20 @@
     }
 
     //-----------------------------------------------------------------------
-    // Data provider for Hijrah Variant names
+    // Data provider for Hijrah Type names
     //-----------------------------------------------------------------------
-    @DataProvider(name = "HijrahVariantNames")
+    @DataProvider(name = "HijrahTypeNames")
     Object[][] data_of_ummalqura() {
         return new Object[][]{
-            { "Hijrah-umalqura", "islamic", "umalqura"},
+            { "Hijrah-umalqura", "islamic-umalqura"},
         };
     }
 
-    @Test(dataProvider= "HijrahVariantNames")
-    public void test_HijrahVariantViaLocale(String calendarId, String calendarType, String variant) {
+    @Test(dataProvider= "HijrahTypeNames")
+    public void test_HijrahTypeViaLocale(String calendarId, String calendarType) {
         Locale.Builder builder = new Locale.Builder();
         builder.setLanguage("en").setRegion("US");
         builder.setUnicodeLocaleKeyword("ca", calendarType);
-        builder.setUnicodeLocaleKeyword("cv", variant);
         Locale locale = builder.build();
         Chronology chrono = Chronology.ofLocale(locale);
         System.out.printf(" Locale language tag: %s, Chronology ID: %s, type: %s%n",
diff --git a/jdk/test/java/time/test/java/time/chrono/TestJapaneseChronology.java b/jdk/test/java/time/test/java/time/chrono/TestJapaneseChronology.java
new file mode 100644
index 0000000..b87555d
--- /dev/null
+++ b/jdk/test/java/time/test/java/time/chrono/TestJapaneseChronology.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test.java.time.chrono;
+
+import java.time.*;
+import java.time.chrono.*;
+import java.time.temporal.*;
+import java.util.List;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Tests for the Japanese chronology
+ */
+@Test
+public class TestJapaneseChronology {
+    private static final JapaneseChronology JAPANESE = JapaneseChronology.INSTANCE;
+    private static final Locale jaJPJP = Locale.forLanguageTag("ja-JP-u-ca-japanese");
+
+    @DataProvider(name="transitions")
+    Object[][] transitionData() {
+        return new Object[][] {
+            // Japanese era, yearOfEra, month, dayOfMonth, gregorianYear
+            { JapaneseEra.SEIREKI, Year.MIN_VALUE, 1, 1, Year.MIN_VALUE },
+            { JapaneseEra.SEIREKI, 1867, 12, 31, 1867 },
+            { JapaneseEra.MEIJI,      1,  1, 25, 1868 }, // Note: the dates of Meiji 1 to 5 are incorrect
+            { JapaneseEra.MEIJI,      6,  1,  1, 1873 },
+            // Meiji-Taisho transition isn't accurate. 1912-07-30 is the last day of Meiji
+            // and the first day of Taisho.
+            { JapaneseEra.MEIJI,     45,  7, 29, 1912 },
+            { JapaneseEra.TAISHO,     1,  7, 30, 1912 },
+            // Same for Taisho-Showa transition. 1926-12-25 is the last day of Taisho
+            // and the first day of Showa.
+            { JapaneseEra.TAISHO,    15, 12, 24, 1926 },
+            { JapaneseEra.SHOWA,      1, 12, 25, 1926 },
+            { JapaneseEra.SHOWA,     64,  1,  7, 1989 },
+            { JapaneseEra.HEISEI,     1,  1,  8, 1989 },
+        };
+    }
+
+    @DataProvider(name="day_year_data")
+    Object[][] dayYearData() {
+        return new Object[][] {
+            // Japanese era, yearOfEra, dayOfYear, month, dayOfMonth
+            { JapaneseEra.MEIJI,  45,  211,  7, 29 },
+            { JapaneseEra.TAISHO,  1,    1,  7, 30 },
+            { JapaneseEra.TAISHO,  2,   60,  3,  1 },
+            { JapaneseEra.TAISHO, 15,  358, 12, 24 },
+            { JapaneseEra.SHOWA,   1,    1, 12, 25 },
+            { JapaneseEra.SHOWA,   2,    8,  1,  8 },
+            { JapaneseEra.SHOWA,  64,    7,  1,  7 },
+            { JapaneseEra.HEISEI,  1,    1,  1,  8 },
+            { JapaneseEra.HEISEI,  2,    8,  1,  8 },
+        };
+    }
+
+    @DataProvider(name="range_data")
+    Object[][] rangeData() {
+        return new Object[][] {
+            // field, minSmallest, minLargest, maxSmallest, maxLargest
+            { ChronoField.ERA,         -999, -999, 2, 2},
+            { ChronoField.YEAR_OF_ERA, -999999999, 1, 15, 999999999-1989 }, // depends on the current era
+            { ChronoField.DAY_OF_YEAR, 1, 1, 7, 366},
+        };
+    }
+
+    @DataProvider(name="invalid_dates")
+    Object[][] invalidDatesData() {
+        return new Object[][] {
+            // Japanese era, yearOfEra, month, dayOfMonth
+            { JapaneseEra.SEIREKI, Year.MIN_VALUE - 1, 1, 1 },
+            { JapaneseEra.SEIREKI, 1855,  2, 29 },
+            { JapaneseEra.SEIREKI, 1868,  1, 25 },
+            { JapaneseEra.MEIJI,      6,  2, 29 },
+            { JapaneseEra.MEIJI,     45,  7, 30 },
+            { JapaneseEra.MEIJI,     46,  1,  1 },
+            { JapaneseEra.TAISHO,     1,  7, 29 },
+            { JapaneseEra.TAISHO,     2,  2, 29 },
+            { JapaneseEra.TAISHO,    15, 12, 25 },
+            { JapaneseEra.TAISHO,    16,  1,  1 },
+            { JapaneseEra.SHOWA,      1, 12, 24 },
+            { JapaneseEra.SHOWA,      2,  2, 29 },
+            { JapaneseEra.SHOWA,     64,  1,  8 },
+            { JapaneseEra.SHOWA,     65,  1,  1 },
+            { JapaneseEra.HEISEI,     1,  1,  7 },
+            { JapaneseEra.HEISEI,     1,  2, 29 },
+            { JapaneseEra.HEISEI, Year.MAX_VALUE,  12, 31 },
+        };
+    }
+
+    @DataProvider(name="invalid_eraYear")
+    Object[][] invalidEraYearData() {
+        return new Object[][] {
+            // Japanese era, yearOfEra
+            { JapaneseEra.SEIREKI, Year.MIN_VALUE - 1 },
+            { JapaneseEra.SEIREKI, 2012 },
+            { JapaneseEra.MEIJI,     -1 },
+            { JapaneseEra.MEIJI,      0 },
+            { JapaneseEra.MEIJI,     46 },
+            { JapaneseEra.TAISHO,    -1 },
+            { JapaneseEra.TAISHO,     0 },
+            { JapaneseEra.TAISHO,    16 },
+            { JapaneseEra.SHOWA,     -1 },
+            { JapaneseEra.SHOWA,      0 },
+            { JapaneseEra.SHOWA,     65 },
+            { JapaneseEra.HEISEI,    -1 },
+            { JapaneseEra.HEISEI,     0 },
+            { JapaneseEra.HEISEI, Year.MAX_VALUE },
+        };
+    }
+
+    @DataProvider(name="invalid_day_year_data")
+    Object[][] invalidDayYearData() {
+        return new Object[][] {
+            // Japanese era, yearOfEra, dayOfYear
+            { JapaneseEra.MEIJI,  45, 240 },
+            { JapaneseEra.TAISHO,  1, 365 },
+            { JapaneseEra.TAISHO,  2, 366 },
+            { JapaneseEra.TAISHO, 15, 359 },
+            { JapaneseEra.SHOWA,   1,   8 },
+            { JapaneseEra.SHOWA,   2, 366 },
+            { JapaneseEra.SHOWA,  64,   8 },
+            { JapaneseEra.HEISEI,  1, 360 },
+            { JapaneseEra.HEISEI,  2, 366 },
+        };
+    }
+
+    @Test
+    public void test_ofLocale() {
+        // must be a singleton
+        assertEquals(Chronology.ofLocale(jaJPJP) == JAPANESE, true);
+    }
+
+    @Test(dataProvider="transitions")
+    public void test_transitions(JapaneseEra era, int yearOfEra, int month, int dayOfMonth, int gregorianYear) {
+        assertEquals(JAPANESE.prolepticYear(era, yearOfEra), gregorianYear);
+
+        JapaneseDate jdate1 = JapaneseDate.of(era, yearOfEra, month, dayOfMonth);
+        JapaneseDate jdate2 = JapaneseDate.of(gregorianYear, month, dayOfMonth);
+        assertEquals(jdate1, jdate2);
+    }
+
+    @Test(dataProvider="range_data")
+    public void test_range(ChronoField field, int minSmallest, int minLargest, int maxSmallest, int maxLargest) {
+        ValueRange range = JAPANESE.range(field);
+        assertEquals(range.getMinimum(), minSmallest);
+        assertEquals(range.getLargestMinimum(), minLargest);
+        assertEquals(range.getSmallestMaximum(), maxSmallest);
+        assertEquals(range.getMaximum(), maxLargest);
+    }
+
+    @Test(dataProvider="day_year_data")
+    public void test_firstDayOfEra(JapaneseEra era, int yearOfEra, int dayOfYear, int month, int dayOfMonth) {
+        JapaneseDate date1 = JAPANESE.dateYearDay(era, yearOfEra, dayOfYear);
+        JapaneseDate date2 = JAPANESE.date(era, yearOfEra, month, dayOfMonth);
+        assertEquals(date1, date2);
+    }
+
+    @Test(dataProvider="invalid_dates", expectedExceptions=DateTimeException.class)
+    public void test_invalidDate(JapaneseEra era, int yearOfEra, int month, int dayOfMonth) {
+        JapaneseDate jdate = JapaneseDate.of(era, yearOfEra, month, dayOfMonth);
+        System.out.printf("No DateTimeException with %s %d.%02d.%02d%n", era, yearOfEra, month, dayOfMonth);
+    }
+
+    @Test(dataProvider="invalid_eraYear", expectedExceptions=DateTimeException.class)
+    public void test_invalidEraYear(JapaneseEra era, int yearOfEra) {
+        int year = JAPANESE.prolepticYear(era, yearOfEra);
+        System.out.printf("No DateTimeException with era=%s, year=%d%n", era, yearOfEra);
+    }
+
+    @Test(dataProvider="invalid_day_year_data", expectedExceptions=DateTimeException.class)
+    public void test_invalidDayYear(JapaneseEra era, int yearOfEra, int dayOfYear) {
+        JapaneseDate date = JAPANESE.dateYearDay(era, yearOfEra, dayOfYear);
+        System.out.printf("No DateTimeException with era=%s, year=%d, dayOfYear=%d%n", era, yearOfEra, dayOfYear);
+    }
+}
diff --git a/jdk/test/java/time/test/java/time/format/AbstractTestPrinterParser.java b/jdk/test/java/time/test/java/time/format/AbstractTestPrinterParser.java
index e11a24d..023f5c1 100644
--- a/jdk/test/java/time/test/java/time/format/AbstractTestPrinterParser.java
+++ b/jdk/test/java/time/test/java/time/format/AbstractTestPrinterParser.java
@@ -63,7 +63,7 @@
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatSymbols;
+import java.time.format.DecimalStyle;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.SignStyle;
@@ -85,7 +85,7 @@
     protected DateTimeFormatterBuilder builder;
     protected TemporalAccessor dta;
     protected Locale locale;
-    protected DateTimeFormatSymbols symbols;
+    protected DecimalStyle decimalStyle;
 
 
     @BeforeMethod
@@ -94,7 +94,7 @@
         builder = new DateTimeFormatterBuilder();
         dta = ZonedDateTime.of(LocalDateTime.of(2011, 6, 30, 12, 30, 40, 0), ZoneId.of("Europe/Paris"));
         locale = Locale.ENGLISH;
-        symbols = DateTimeFormatSymbols.STANDARD;
+        decimalStyle = DecimalStyle.STANDARD;
     }
 
     protected void setCaseSensitive(boolean caseSensitive) {
@@ -114,35 +114,35 @@
     }
 
     protected DateTimeFormatter getFormatter() {
-        return builder.toFormatter(locale).withSymbols(symbols);
+        return builder.toFormatter(locale).withDecimalStyle(decimalStyle);
     }
 
     protected DateTimeFormatter getFormatter(char c) {
-        return builder.appendLiteral(c).toFormatter(locale).withSymbols(symbols);
+        return builder.appendLiteral(c).toFormatter(locale).withDecimalStyle(decimalStyle);
     }
 
     protected DateTimeFormatter getFormatter(String s) {
-        return builder.appendLiteral(s).toFormatter(locale).withSymbols(symbols);
+        return builder.appendLiteral(s).toFormatter(locale).withDecimalStyle(decimalStyle);
     }
 
     protected DateTimeFormatter getFormatter(TemporalField field) {
-        return builder.appendText(field).toFormatter(locale).withSymbols(symbols);
+        return builder.appendText(field).toFormatter(locale).withDecimalStyle(decimalStyle);
     }
 
     protected DateTimeFormatter getFormatter(TemporalField field, TextStyle style) {
-        return builder.appendText(field, style).toFormatter(locale).withSymbols(symbols);
+        return builder.appendText(field, style).toFormatter(locale).withDecimalStyle(decimalStyle);
     }
 
     protected DateTimeFormatter getFormatter(TemporalField field, int minWidth, int maxWidth, SignStyle signStyle) {
-        return builder.appendValue(field, minWidth, maxWidth, signStyle).toFormatter(locale).withSymbols(symbols);
+        return builder.appendValue(field, minWidth, maxWidth, signStyle).toFormatter(locale).withDecimalStyle(decimalStyle);
     }
 
     protected DateTimeFormatter getFormatter(String pattern, String noOffsetText) {
-        return builder.appendOffset(pattern, noOffsetText).toFormatter(locale).withSymbols(symbols);
+        return builder.appendOffset(pattern, noOffsetText).toFormatter(locale).withDecimalStyle(decimalStyle);
     }
 
     protected DateTimeFormatter getPatternFormatter(String pattern) {
-        return builder.appendPattern(pattern).toFormatter(locale).withSymbols(symbols);
+        return builder.appendPattern(pattern).toFormatter(locale).withDecimalStyle(decimalStyle);
     }
 
     protected static final TemporalAccessor EMPTY_DTA = new TemporalAccessor() {
diff --git a/jdk/test/java/time/test/java/time/format/TestDateTimeFormatter.java b/jdk/test/java/time/test/java/time/format/TestDateTimeFormatter.java
index a96dfb6..540a0e8 100644
--- a/jdk/test/java/time/test/java/time/format/TestDateTimeFormatter.java
+++ b/jdk/test/java/time/test/java/time/format/TestDateTimeFormatter.java
@@ -62,7 +62,7 @@
 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
 import static org.testng.Assert.assertSame;
 
-import java.time.format.DateTimeFormatSymbols;
+import java.time.format.DecimalStyle;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.SignStyle;
@@ -82,7 +82,7 @@
             new DateTimeFormatterBuilder().appendLiteral("ONE")
                                           .appendValue(DAY_OF_MONTH, 1, 2, SignStyle.NOT_NEGATIVE)
                                           .toFormatter(Locale.ENGLISH)
-                                          .withSymbols(DateTimeFormatSymbols.STANDARD);
+                                          .withDecimalStyle(DecimalStyle.STANDARD);
         DateTimeFormatter test = base.withLocale(Locale.ENGLISH);
         assertSame(test, base);
     }
diff --git a/jdk/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java b/jdk/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java
index 432c038..bdaf22b 100644
--- a/jdk/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java
+++ b/jdk/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java
@@ -65,13 +65,19 @@
 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
 import static java.time.temporal.ChronoField.YEAR;
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
 
 import java.text.ParsePosition;
 import java.time.LocalDate;
 import java.time.YearMonth;
 import java.time.ZoneOffset;
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.MinguoChronology;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.FormatStyle;
 import java.time.format.SignStyle;
 import java.time.format.TextStyle;
 import java.time.temporal.Temporal;
@@ -268,7 +274,7 @@
     public void test_appendValueReduced() throws Exception {
         builder.appendValueReduced(YEAR, 2, 2000);
         DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "ReducedValue(Year,2,2000)");
+        assertEquals(f.toString(), "ReducedValue(Year,2,2,2000)");
         TemporalAccessor parsed = f.parseUnresolved("12", new ParsePosition(0));
         assertEquals(parsed.getLong(YEAR), 2012L);
     }
@@ -277,8 +283,10 @@
     public void test_appendValueReduced_subsequent_parse() throws Exception {
         builder.appendValue(MONTH_OF_YEAR, 1, 2, SignStyle.NORMAL).appendValueReduced(YEAR, 2, 2000);
         DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(MonthOfYear,1,2,NORMAL)ReducedValue(Year,2,2000)");
-        TemporalAccessor parsed = f.parseUnresolved("123", new ParsePosition(0));
+        assertEquals(f.toString(), "Value(MonthOfYear,1,2,NORMAL)ReducedValue(Year,2,2,2000)");
+        ParsePosition ppos = new ParsePosition(0);
+        TemporalAccessor parsed = f.parseUnresolved("123", ppos);
+        assertNotNull(parsed, "Parse failed: " + ppos.toString());
         assertEquals(parsed.getLong(MONTH_OF_YEAR), 1L);
         assertEquals(parsed.getLong(YEAR), 2023L);
     }
@@ -646,13 +654,13 @@
             {"GGGGG", "Text(Era,NARROW)"},
 
             {"u", "Value(Year)"},
-            {"uu", "ReducedValue(Year,2,2000)"},
+            {"uu", "ReducedValue(Year,2,2,2000)"},
             {"uuu", "Value(Year,3,19,NORMAL)"},
             {"uuuu", "Value(Year,4,19,EXCEEDS_PAD)"},
             {"uuuuu", "Value(Year,5,19,EXCEEDS_PAD)"},
 
             {"y", "Value(YearOfEra)"},
-            {"yy", "ReducedValue(YearOfEra,2,2000)"},
+            {"yy", "ReducedValue(YearOfEra,2,2,2000)"},
             {"yyy", "Value(YearOfEra,3,19,NORMAL)"},
             {"yyyy", "Value(YearOfEra,4,19,EXCEEDS_PAD)"},
             {"yyyyy", "Value(YearOfEra,5,19,EXCEEDS_PAD)"},
@@ -892,6 +900,109 @@
         assertEquals(test, expected);
     }
 
+    //-----------------------------------------------------------------------
+    @DataProvider(name="localePatterns")
+    Object[][] localizedDateTimePatterns() {
+        return new Object[][] {
+            {FormatStyle.FULL, FormatStyle.FULL, IsoChronology.INSTANCE, Locale.US, "EEEE, MMMM d, yyyy h:mm:ss a z"},
+            {FormatStyle.LONG, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.US, "MMMM d, yyyy h:mm:ss a z"},
+            {FormatStyle.MEDIUM, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.US, "MMM d, yyyy h:mm:ss a"},
+            {FormatStyle.SHORT, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.US, "M/d/yy h:mm a"},
+            {FormatStyle.FULL, null, IsoChronology.INSTANCE, Locale.US, "EEEE, MMMM d, yyyy"},
+            {FormatStyle.LONG, null, IsoChronology.INSTANCE, Locale.US, "MMMM d, yyyy"},
+            {FormatStyle.MEDIUM, null, IsoChronology.INSTANCE, Locale.US, "MMM d, yyyy"},
+            {FormatStyle.SHORT, null, IsoChronology.INSTANCE, Locale.US, "M/d/yy"},
+            {null, FormatStyle.FULL, IsoChronology.INSTANCE, Locale.US, "h:mm:ss a z"},
+            {null, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.US, "h:mm:ss a z"},
+            {null, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.US, "h:mm:ss a"},
+            {null, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.US, "h:mm a"},
+
+            // French Locale and ISO Chronology
+            {FormatStyle.FULL, FormatStyle.FULL, IsoChronology.INSTANCE, Locale.FRENCH, "EEEE d MMMM yyyy HH' h 'mm z"},
+            {FormatStyle.LONG, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.FRENCH, "d MMMM yyyy HH:mm:ss z"},
+            {FormatStyle.MEDIUM, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM yyyy HH:mm:ss"},
+            {FormatStyle.SHORT, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.FRENCH, "dd/MM/yy HH:mm"},
+            {FormatStyle.FULL, null, IsoChronology.INSTANCE, Locale.FRENCH, "EEEE d MMMM yyyy"},
+            {FormatStyle.LONG, null, IsoChronology.INSTANCE, Locale.FRENCH, "d MMMM yyyy"},
+            {FormatStyle.MEDIUM, null, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM yyyy"},
+            {FormatStyle.SHORT, null, IsoChronology.INSTANCE, Locale.FRENCH, "dd/MM/yy"},
+            {null, FormatStyle.FULL, IsoChronology.INSTANCE, Locale.FRENCH, "HH' h 'mm z"},
+            {null, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss z"},
+            {null, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss"},
+            {null, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm"},
+
+            // Japanese Locale and JapaneseChronology
+            {FormatStyle.FULL, FormatStyle.FULL, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy'\u5e74'M'\u6708'd'\u65e5' H'\u6642'mm'\u5206'ss'\u79d2' z"},
+            {FormatStyle.LONG, FormatStyle.LONG, JapaneseChronology.INSTANCE, Locale.JAPANESE, "GGGGGy.MM.dd H:mm:ss z"},
+            {FormatStyle.MEDIUM, FormatStyle.MEDIUM, JapaneseChronology.INSTANCE, Locale.JAPANESE, "GGGGGy.MM.dd H:mm:ss"},
+            {FormatStyle.SHORT, FormatStyle.SHORT, JapaneseChronology.INSTANCE, Locale.JAPANESE, "GGGGGy.MM.dd H:mm"},
+            {FormatStyle.FULL, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy'\u5e74'M'\u6708'd'\u65e5'"},
+            {FormatStyle.LONG, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "GGGGGy.MM.dd"},
+            {FormatStyle.MEDIUM, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "GGGGGy.MM.dd"},
+            {FormatStyle.SHORT, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "GGGGGy.MM.dd"},
+            {null, FormatStyle.FULL, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H'\u6642'mm'\u5206'ss'\u79d2' z"},
+            {null, FormatStyle.LONG, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm:ss z"},
+            {null, FormatStyle.MEDIUM, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm:ss"},
+            {null, FormatStyle.SHORT, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm"},
+
+            // Chinese Local and Chronology
+            {FormatStyle.FULL, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE ahh'\u65f6'mm'\u5206'ss'\u79d2' z"},
+            {FormatStyle.LONG, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 ahh'\u65f6'mm'\u5206'ss'\u79d2'"},
+            {FormatStyle.MEDIUM, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy-M-d H:mm:ss"},
+            {FormatStyle.SHORT, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy-M-d ah:mm"},
+            {FormatStyle.FULL, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE"},
+            {FormatStyle.LONG, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5"},
+            {FormatStyle.MEDIUM, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy-M-d"},
+            {FormatStyle.SHORT, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy-M-d"},
+            {null, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "ahh'\u65f6'mm'\u5206'ss'\u79d2' z"},
+            {null, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "ahh'\u65f6'mm'\u5206'ss'\u79d2'"},
+            {null, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "H:mm:ss"},
+            {null, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "ah:mm"},
+        };
+    }
+
+    @Test(dataProvider="localePatterns")
+    public void test_getLocalizedDateTimePattern(FormatStyle dateStyle, FormatStyle timeStyle,
+            Chronology chrono, Locale locale, String expected) {
+        String actual = DateTimeFormatterBuilder.getLocalizedDateTimePattern(dateStyle, timeStyle, chrono, locale);
+        assertEquals(actual, expected, "Pattern " + convertNonAscii(actual));
+    }
+
+    @Test(expectedExceptions=java.lang.IllegalArgumentException.class)
+    public void test_getLocalizedDateTimePatternIAE() {
+        DateTimeFormatterBuilder.getLocalizedDateTimePattern(null, null, IsoChronology.INSTANCE, Locale.US);
+    }
+
+    @Test(expectedExceptions=java.lang.NullPointerException.class)
+    public void test_getLocalizedChronoNPE() {
+        DateTimeFormatterBuilder.getLocalizedDateTimePattern(FormatStyle.SHORT, FormatStyle.SHORT, null, Locale.US);
+    }
+
+    @Test(expectedExceptions=java.lang.NullPointerException.class)
+    public void test_getLocalizedLocaleNPE() {
+        DateTimeFormatterBuilder.getLocalizedDateTimePattern(FormatStyle.SHORT, FormatStyle.SHORT, IsoChronology.INSTANCE, null);
+    }
+
+    /**
+     * Returns a string that includes non-ascii characters after expanding
+     * the non-ascii characters to their Java language \\uxxxx form.
+     * @param input an input string
+     * @return the encoded string.
+     */
+    private String convertNonAscii(String input) {
+        StringBuilder sb = new StringBuilder(input.length() * 6);
+        for (int i = 0; i < input.length(); i++) {
+            char ch = input.charAt(i);
+            if (ch < 255) {
+                sb.append(ch);
+            } else {
+                sb.append("\\u");
+                sb.append(Integer.toHexString(ch));
+            }
+        }
+        return sb.toString();
+    }
+
     private static Temporal date(int y, int m, int d) {
         return LocalDate.of(y, m, d);
     }
diff --git a/jdk/test/java/time/test/java/time/format/TestDateTimeFormatSymbols.java b/jdk/test/java/time/test/java/time/format/TestDecimalStyle.java
similarity index 88%
rename from jdk/test/java/time/test/java/time/format/TestDateTimeFormatSymbols.java
rename to jdk/test/java/time/test/java/time/format/TestDecimalStyle.java
index cb3932a..b506d54 100644
--- a/jdk/test/java/time/test/java/time/format/TestDateTimeFormatSymbols.java
+++ b/jdk/test/java/time/test/java/time/format/TestDecimalStyle.java
@@ -61,29 +61,29 @@
 
 import static org.testng.Assert.assertSame;
 
-import java.time.format.DateTimeFormatSymbols;
+import java.time.format.DecimalStyle;
 import java.util.Locale;
 
 import org.testng.annotations.Test;
 
 /**
- * Test DateTimeFormatSymbols.
+ * Test DecimalStyle.
  */
 @Test
-public class TestDateTimeFormatSymbols {
+public class TestDecimalStyle {
 
     @Test
     public void test_of_Locale_cached() {
-        DateTimeFormatSymbols loc1 = DateTimeFormatSymbols.of(Locale.CANADA);
-        DateTimeFormatSymbols loc2 = DateTimeFormatSymbols.of(Locale.CANADA);
+        DecimalStyle loc1 = DecimalStyle.of(Locale.CANADA);
+        DecimalStyle loc2 = DecimalStyle.of(Locale.CANADA);
         assertSame(loc1, loc2);
     }
 
     //-----------------------------------------------------------------------
     @Test
     public void test_ofDefaultLocale_cached() {
-        DateTimeFormatSymbols loc1 = DateTimeFormatSymbols.ofDefaultLocale();
-        DateTimeFormatSymbols loc2 = DateTimeFormatSymbols.ofDefaultLocale();
+        DecimalStyle loc1 = DecimalStyle.ofDefaultLocale();
+        DecimalStyle loc2 = DecimalStyle.ofDefaultLocale();
         assertSame(loc1, loc2);
     }
 
diff --git a/jdk/test/java/time/test/java/time/format/TestFractionPrinterParser.java b/jdk/test/java/time/test/java/time/format/TestFractionPrinterParser.java
index ae94054..c476772 100644
--- a/jdk/test/java/time/test/java/time/format/TestFractionPrinterParser.java
+++ b/jdk/test/java/time/test/java/time/format/TestFractionPrinterParser.java
@@ -82,7 +82,7 @@
 public class TestFractionPrinterParser extends AbstractTestPrinterParser {
 
     private DateTimeFormatter getFormatter(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint) {
-        return builder.appendFraction(field, minWidth, maxWidth, decimalPoint).toFormatter(locale).withSymbols(symbols);
+        return builder.appendFraction(field, minWidth, maxWidth, decimalPoint).toFormatter(locale).withDecimalStyle(decimalStyle);
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java b/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java
index 24852ef..49ec4d65 100644
--- a/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java
+++ b/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java
@@ -32,7 +32,7 @@
 import java.time.chrono.JapaneseChronology;
 import java.time.chrono.MinguoChronology;
 import java.time.chrono.ThaiBuddhistChronology;
-import java.time.format.DateTimeFormatSymbols;
+import java.time.format.DecimalStyle;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.DateTimeParseException;
@@ -129,7 +129,7 @@
                                          ChronoLocalDate<?> date, String expected) {
         DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)
             .withChronology(chrono).withLocale(formatLocale)
-            .withSymbols(DateTimeFormatSymbols.of(numberingLocale));
+            .withDecimalStyle(DecimalStyle.of(numberingLocale));
         String text = dtf.format(date);
         assertEquals(text, expected);
     }
@@ -139,7 +139,7 @@
                                         ChronoLocalDate<?> expected, String text) {
         DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)
             .withChronology(chrono).withLocale(formatLocale)
-            .withSymbols(DateTimeFormatSymbols.of(numberingLocale));
+            .withDecimalStyle(DecimalStyle.of(numberingLocale));
         TemporalAccessor temporal = dtf.parse(text);
         ChronoLocalDate<?> date = chrono.date(temporal);
         assertEquals(date, expected);
diff --git a/jdk/test/java/time/test/java/time/format/TestNumberParser.java b/jdk/test/java/time/test/java/time/format/TestNumberParser.java
index a6fc4a2..3e657582 100644
--- a/jdk/test/java/time/test/java/time/format/TestNumberParser.java
+++ b/jdk/test/java/time/test/java/time/format/TestNumberParser.java
@@ -169,7 +169,7 @@
         DateTimeFormatter dtf = getFormatter(DAY_OF_MONTH, minWidth, maxWidth, signStyle);
         if (subsequentWidth > 0) {
             // hacky, to reserve space
-            dtf = builder.appendValue(DAY_OF_YEAR, subsequentWidth).toFormatter(locale).withSymbols(symbols);
+            dtf = builder.appendValue(DAY_OF_YEAR, subsequentWidth).toFormatter(locale).withDecimalStyle(decimalStyle);
         }
         TemporalAccessor parsed = dtf.parseUnresolved(text, ppos);
         if (ppos.getErrorIndex() != -1) {
@@ -189,7 +189,7 @@
         DateTimeFormatter dtf = getFormatter(DAY_OF_WEEK, minWidth, maxWidth, signStyle);
         if (subsequentWidth > 0) {
             // hacky, to reserve space
-            dtf = builder.appendValue(DAY_OF_YEAR, subsequentWidth).toFormatter(locale).withSymbols(symbols);
+            dtf = builder.appendValue(DAY_OF_YEAR, subsequentWidth).toFormatter(locale).withDecimalStyle(decimalStyle);
         }
         TemporalAccessor parsed = dtf.parseUnresolved(text, ppos);
         if (ppos.getErrorIndex() != -1) {
@@ -326,16 +326,16 @@
             {"0", 1, 2, SignStyle.NEVER, 1, 0},
             {"5", 1, 2, SignStyle.NEVER, 1, 5},
             {"50", 1, 2, SignStyle.NEVER, 2, 50},
-            {"500", 1, 2, SignStyle.NEVER, 2, 50},
+            {"500", 1, 2, SignStyle.NEVER, 3, 500},
             {"-0", 1, 2, SignStyle.NEVER, 2, 0},
             {"-5", 1, 2, SignStyle.NEVER, 2, -5},
             {"-50", 1, 2, SignStyle.NEVER, 3, -50},
-            {"-500", 1, 2, SignStyle.NEVER, 3, -50},
+            {"-500", 1, 2, SignStyle.NEVER, 4, -500},
             {"-AAA", 1, 2, SignStyle.NEVER, 1, null},
             {"+0", 1, 2, SignStyle.NEVER, 2, 0},
             {"+5", 1, 2, SignStyle.NEVER, 2, 5},
             {"+50", 1, 2, SignStyle.NEVER, 3, 50},
-            {"+500", 1, 2, SignStyle.NEVER, 3, 50},
+            {"+500", 1, 2, SignStyle.NEVER, 4, 500},
             {"+AAA", 1, 2, SignStyle.NEVER, 1, null},
             {"50", 2, 2, SignStyle.NEVER, 2, 50},
             {"-50", 2, 2, SignStyle.NEVER, 0, null},
@@ -345,16 +345,16 @@
             {"0", 1, 2, SignStyle.NOT_NEGATIVE, 1, 0},
             {"5", 1, 2, SignStyle.NOT_NEGATIVE, 1, 5},
             {"50", 1, 2, SignStyle.NOT_NEGATIVE, 2, 50},
-            {"500", 1, 2, SignStyle.NOT_NEGATIVE, 2, 50},
+            {"500", 1, 2, SignStyle.NOT_NEGATIVE, 3, 500},
             {"-0", 1, 2, SignStyle.NOT_NEGATIVE, 2, 0},
             {"-5", 1, 2, SignStyle.NOT_NEGATIVE, 2, -5},
             {"-50", 1, 2, SignStyle.NOT_NEGATIVE, 3, -50},
-            {"-500", 1, 2, SignStyle.NOT_NEGATIVE, 3, -50},
+            {"-500", 1, 2, SignStyle.NOT_NEGATIVE, 4, -500},
             {"-AAA", 1, 2, SignStyle.NOT_NEGATIVE, 1, null},
             {"+0", 1, 2, SignStyle.NOT_NEGATIVE, 2, 0},
             {"+5", 1, 2, SignStyle.NOT_NEGATIVE, 2, 5},
             {"+50", 1, 2, SignStyle.NOT_NEGATIVE, 3, 50},
-            {"+500", 1, 2, SignStyle.NOT_NEGATIVE, 3, 50},
+            {"+500", 1, 2, SignStyle.NOT_NEGATIVE, 4, 500},
             {"+AAA", 1, 2, SignStyle.NOT_NEGATIVE, 1, null},
             {"50", 2, 2, SignStyle.NOT_NEGATIVE, 2, 50},
             {"-50", 2, 2, SignStyle.NOT_NEGATIVE, 0, null},
@@ -364,16 +364,16 @@
             {"0", 1, 2, SignStyle.NORMAL, 1, 0},
             {"5", 1, 2, SignStyle.NORMAL, 1, 5},
             {"50", 1, 2, SignStyle.NORMAL, 2, 50},
-            {"500", 1, 2, SignStyle.NORMAL, 2, 50},
+            {"500", 1, 2, SignStyle.NORMAL, 3, 500},
             {"-0", 1, 2, SignStyle.NORMAL, 2, 0},
             {"-5", 1, 2, SignStyle.NORMAL, 2, -5},
             {"-50", 1, 2, SignStyle.NORMAL, 3, -50},
-            {"-500", 1, 2, SignStyle.NORMAL, 3, -50},
+            {"-500", 1, 2, SignStyle.NORMAL, 4, -500},
             {"-AAA", 1, 2, SignStyle.NORMAL, 1, null},
             {"+0", 1, 2, SignStyle.NORMAL, 2, 0},
             {"+5", 1, 2, SignStyle.NORMAL, 2, 5},
             {"+50", 1, 2, SignStyle.NORMAL, 3, 50},
-            {"+500", 1, 2, SignStyle.NORMAL, 3, 50},
+            {"+500", 1, 2, SignStyle.NORMAL, 4, 500},
             {"+AAA", 1, 2, SignStyle.NORMAL, 1, null},
             {"50", 2, 2, SignStyle.NORMAL, 2, 50},
             {"-50", 2, 2, SignStyle.NORMAL, 3, -50},
@@ -383,32 +383,32 @@
             {"0", 1, 2, SignStyle.ALWAYS, 1, 0},
             {"5", 1, 2, SignStyle.ALWAYS, 1, 5},
             {"50", 1, 2, SignStyle.ALWAYS, 2, 50},
-            {"500", 1, 2, SignStyle.ALWAYS, 2, 50},
+            {"500", 1, 2, SignStyle.ALWAYS, 3, 500},
             {"-0", 1, 2, SignStyle.ALWAYS, 2, 0},
             {"-5", 1, 2, SignStyle.ALWAYS, 2, -5},
             {"-50", 1, 2, SignStyle.ALWAYS, 3, -50},
-            {"-500", 1, 2, SignStyle.ALWAYS, 3, -50},
+            {"-500", 1, 2, SignStyle.ALWAYS, 4, -500},
             {"-AAA", 1, 2, SignStyle.ALWAYS, 1, null},
             {"+0", 1, 2, SignStyle.ALWAYS, 2, 0},
             {"+5", 1, 2, SignStyle.ALWAYS, 2, 5},
             {"+50", 1, 2, SignStyle.ALWAYS, 3, 50},
-            {"+500", 1, 2, SignStyle.ALWAYS, 3, 50},
+            {"+500", 1, 2, SignStyle.ALWAYS, 4, 500},
             {"+AAA", 1, 2, SignStyle.ALWAYS, 1, null},
 
             // exceeds pad
             {"0", 1, 2, SignStyle.EXCEEDS_PAD, 1, 0},
             {"5", 1, 2, SignStyle.EXCEEDS_PAD, 1, 5},
             {"50", 1, 2, SignStyle.EXCEEDS_PAD, 2, 50},
-            {"500", 1, 2, SignStyle.EXCEEDS_PAD, 2, 50},
+            {"500", 1, 2, SignStyle.EXCEEDS_PAD, 3, 500},
             {"-0", 1, 2, SignStyle.EXCEEDS_PAD, 2, 0},
             {"-5", 1, 2, SignStyle.EXCEEDS_PAD, 2, -5},
             {"-50", 1, 2, SignStyle.EXCEEDS_PAD, 3, -50},
-            {"-500", 1, 2, SignStyle.EXCEEDS_PAD, 3, -50},
+            {"-500", 1, 2, SignStyle.EXCEEDS_PAD, 4, -500},
             {"-AAA", 1, 2, SignStyle.EXCEEDS_PAD, 1, null},
             {"+0", 1, 2, SignStyle.EXCEEDS_PAD, 2, 0},
             {"+5", 1, 2, SignStyle.EXCEEDS_PAD, 2, 5},
             {"+50", 1, 2, SignStyle.EXCEEDS_PAD, 3, 50},
-            {"+500", 1, 2, SignStyle.EXCEEDS_PAD, 3, 50},
+            {"+500", 1, 2, SignStyle.EXCEEDS_PAD, 4, 500},
             {"+AAA", 1, 2, SignStyle.EXCEEDS_PAD, 1, null},
        };
     }
@@ -441,9 +441,9 @@
                 {"543", 1, 3, SignStyle.NEVER, 3, 543},
                 {"543", 2, 3, SignStyle.NEVER, 3, 543},
                 {"543", 3, 3, SignStyle.NEVER, 3, 543},
-                {"5432", 1, 3, SignStyle.NEVER, 3, 543},
-                {"5432", 2, 3, SignStyle.NEVER, 3, 543},
-                {"5432", 3, 3, SignStyle.NEVER, 3, 543},
+                {"5432", 1, 3, SignStyle.NEVER, 4, 5432},
+                {"5432", 2, 3, SignStyle.NEVER, 4, 5432},
+                {"5432", 3, 3, SignStyle.NEVER, 4, 5432},
                 {"5AAA", 2, 3, SignStyle.NEVER, 1, 5},
 
                 // not negative
@@ -455,9 +455,9 @@
                 {"543", 1, 3, SignStyle.NOT_NEGATIVE, 3, 543},
                 {"543", 2, 3, SignStyle.NOT_NEGATIVE, 3, 543},
                 {"543", 3, 3, SignStyle.NOT_NEGATIVE, 3, 543},
-                {"5432", 1, 3, SignStyle.NOT_NEGATIVE, 3, 543},
-                {"5432", 2, 3, SignStyle.NOT_NEGATIVE, 3, 543},
-                {"5432", 3, 3, SignStyle.NOT_NEGATIVE, 3, 543},
+                {"5432", 1, 3, SignStyle.NOT_NEGATIVE, 4, 5432},
+                {"5432", 2, 3, SignStyle.NOT_NEGATIVE, 4, 5432},
+                {"5432", 3, 3, SignStyle.NOT_NEGATIVE, 4, 5432},
                 {"5AAA", 2, 3, SignStyle.NOT_NEGATIVE, 1, 5},
 
                 // normal
@@ -469,9 +469,9 @@
                 {"543", 1, 3, SignStyle.NORMAL, 3, 543},
                 {"543", 2, 3, SignStyle.NORMAL, 3, 543},
                 {"543", 3, 3, SignStyle.NORMAL, 3, 543},
-                {"5432", 1, 3, SignStyle.NORMAL, 3, 543},
-                {"5432", 2, 3, SignStyle.NORMAL, 3, 543},
-                {"5432", 3, 3, SignStyle.NORMAL, 3, 543},
+                {"5432", 1, 3, SignStyle.NORMAL, 4, 5432},
+                {"5432", 2, 3, SignStyle.NORMAL, 4, 5432},
+                {"5432", 3, 3, SignStyle.NORMAL, 4, 5432},
                 {"5AAA", 2, 3, SignStyle.NORMAL, 1, 5},
 
                 // always
@@ -483,9 +483,9 @@
                 {"543", 1, 3, SignStyle.ALWAYS, 3, 543},
                 {"543", 2, 3, SignStyle.ALWAYS, 3, 543},
                 {"543", 3, 3, SignStyle.ALWAYS, 3, 543},
-                {"5432", 1, 3, SignStyle.ALWAYS, 3, 543},
-                {"5432", 2, 3, SignStyle.ALWAYS, 3, 543},
-                {"5432", 3, 3, SignStyle.ALWAYS, 3, 543},
+                {"5432", 1, 3, SignStyle.ALWAYS, 4, 5432},
+                {"5432", 2, 3, SignStyle.ALWAYS, 4, 5432},
+                {"5432", 3, 3, SignStyle.ALWAYS, 4, 5432},
                 {"5AAA", 2, 3, SignStyle.ALWAYS, 1, 5},
 
                 // exceeds pad
@@ -497,9 +497,9 @@
                 {"543", 1, 3, SignStyle.EXCEEDS_PAD, 3, 543},
                 {"543", 2, 3, SignStyle.EXCEEDS_PAD, 3, 543},
                 {"543", 3, 3, SignStyle.EXCEEDS_PAD, 3, 543},
-                {"5432", 1, 3, SignStyle.EXCEEDS_PAD, 3, 543},
-                {"5432", 2, 3, SignStyle.EXCEEDS_PAD, 3, 543},
-                {"5432", 3, 3, SignStyle.EXCEEDS_PAD, 3, 543},
+                {"5432", 1, 3, SignStyle.EXCEEDS_PAD, 4, 5432},
+                {"5432", 2, 3, SignStyle.EXCEEDS_PAD, 4, 5432},
+                {"5432", 3, 3, SignStyle.EXCEEDS_PAD, 4, 5432},
                 {"5AAA", 2, 3, SignStyle.EXCEEDS_PAD, 1, 5},
         };
     }
@@ -533,8 +533,8 @@
                 {"5432", 4, 54, 32},
                 {"5432A", 4, 54, 32},
 
-                {"54321", 4, 54, 32},
-                {"54321A", 4, 54, 32},
+                {"54321", 5, 543, 21},
+                {"54321A", 5, 543, 21},
         };
     }
 
@@ -544,7 +544,7 @@
         ParsePosition pos = new ParsePosition(0);
         DateTimeFormatter f = builder
                 .appendValue(MONTH_OF_YEAR, 1, 2, SignStyle.NORMAL)
-                .appendValue(DAY_OF_MONTH, 2).toFormatter(locale).withSymbols(symbols);
+                .appendValue(DAY_OF_MONTH, 2).toFormatter(locale).withDecimalStyle(decimalStyle);
         TemporalAccessor parsed = f.parseUnresolved(input, pos);
         if (pos.getErrorIndex() != -1) {
             assertEquals(pos.getErrorIndex(), parseLen);
diff --git a/jdk/test/java/time/test/java/time/format/TestReducedParser.java b/jdk/test/java/time/test/java/time/format/TestReducedParser.java
index b8ae45f..237b5b9 100644
--- a/jdk/test/java/time/test/java/time/format/TestReducedParser.java
+++ b/jdk/test/java/time/test/java/time/format/TestReducedParser.java
@@ -59,13 +59,18 @@
  */
 package test.java.time.format;
 
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
 import static java.time.temporal.ChronoField.DAY_OF_YEAR;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
 import static java.time.temporal.ChronoField.YEAR;
+import static java.time.temporal.ChronoField.YEAR_OF_ERA;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertNotNull;
 
 import java.text.ParsePosition;
 import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
 
@@ -77,9 +82,15 @@
  */
 @Test
 public class TestReducedParser extends AbstractTestPrinterParser {
+    private static final boolean STRICT = true;
+    private static final boolean LENIENT = false;
 
     private DateTimeFormatter getFormatter0(TemporalField field, int width, int baseValue) {
-        return builder.appendValueReduced(field, width, baseValue).toFormatter(locale).withSymbols(symbols);
+        return builder.appendValueReduced(field, width, baseValue).toFormatter(locale).withDecimalStyle(decimalStyle);
+    }
+
+    private DateTimeFormatter getFormatter0(TemporalField field, int minWidth, int maxWidth, int baseValue) {
+        return builder.appendValueReduced(field, minWidth, maxWidth, baseValue).toFormatter(locale).withDecimalStyle(decimalStyle);
     }
 
     //-----------------------------------------------------------------------
@@ -109,89 +120,242 @@
     }
 
     //-----------------------------------------------------------------------
-    @DataProvider(name="Parse")
-    Object[][] provider_parse() {
+    // Parse data and values that are consistent whether strict or lenient
+    // The data is the ChronoField, width, baseValue, text, startPos, endPos, value
+    //-----------------------------------------------------------------------
+    @DataProvider(name="ParseAll")
+    Object[][] provider_parseAll() {
         return new Object[][] {
              // negative zero
             {YEAR, 1, 2010, "-0", 0, 0, null},
 
             // general
             {YEAR, 2, 2010, "Xxx12Xxx", 3, 5, 2012},
-            {YEAR, 2, 2010, "12345", 0, 2, 2012},
             {YEAR, 2, 2010, "12-45", 0, 2, 2012},
 
-            // insufficient digits
-            {YEAR, 2, 2010, "0", 0, 0, null},
-            {YEAR, 2, 2010, "1", 0, 0, null},
-            {YEAR, 2, 2010, "1", 1, 1, null},
-            {YEAR, 2, 2010, "1-2", 0, 0, null},
-            {YEAR, 2, 2010, "9", 0, 0, null},
-
             // other junk
             {YEAR, 2, 2010, "A0", 0, 0, null},
-            {YEAR, 2, 2010, "0A", 0, 0, null},
             {YEAR, 2, 2010, "  1", 0, 0, null},
             {YEAR, 2, 2010, "-1", 0, 0, null},
             {YEAR, 2, 2010, "-10", 0, 0, null},
+            {YEAR, 2, 2000, " 1", 0, 0, null},
 
             // parse OK 1
-            {YEAR, 1, 2010, "0", 0, 1, 2010},
+            {YEAR, 1, 2010, "1", 0, 1, 2011},
+            {YEAR, 1, 2010, "3", 1, 1, null},
             {YEAR, 1, 2010, "9", 0, 1, 2019},
-            {YEAR, 1, 2010, "10", 0, 1, 2011},
 
             {YEAR, 1, 2005, "0", 0, 1, 2010},
             {YEAR, 1, 2005, "4", 0, 1, 2014},
             {YEAR, 1, 2005, "5", 0, 1, 2005},
             {YEAR, 1, 2005, "9", 0, 1, 2009},
-            {YEAR, 1, 2005, "10", 0, 1, 2011},
+            {YEAR, 1, 2010, "1-2", 0, 1, 2011},
 
             // parse OK 2
             {YEAR, 2, 2010, "00", 0, 2, 2100},
             {YEAR, 2, 2010, "09", 0, 2, 2109},
             {YEAR, 2, 2010, "10", 0, 2, 2010},
             {YEAR, 2, 2010, "99", 0, 2, 2099},
-            {YEAR, 2, 2010, "100", 0, 2, 2010},
 
             // parse OK 2
             {YEAR, 2, -2005, "05", 0, 2, -2005},
             {YEAR, 2, -2005, "00", 0, 2, -2000},
             {YEAR, 2, -2005, "99", 0, 2, -1999},
             {YEAR, 2, -2005, "06", 0, 2, -1906},
-            {YEAR, 2, -2005, "100", 0, 2, -1910},
-       };
+
+            {YEAR, 2, -2005, "43", 0, 2, -1943},
+        };
     }
 
-    @Test(dataProvider="Parse")
-    public void test_parse(TemporalField field, int width, int baseValue, String input, int pos, int parseLen, Integer parseVal) {
+    @Test(dataProvider="ParseAll")
+    public void test_parseAllStrict(TemporalField field, int width, int baseValue, String input, int pos, int parseLen, Integer parseVal) {
         ParsePosition ppos = new ParsePosition(pos);
+        setStrict(true);
         TemporalAccessor parsed = getFormatter0(field, width, baseValue).parseUnresolved(input, ppos);
         if (ppos.getErrorIndex() != -1) {
-            assertEquals(ppos.getErrorIndex(), parseLen);
+            assertEquals(ppos.getErrorIndex(), parseLen, "error case parse position");
+            assertEquals(parsed, parseVal, "unexpected parse result");
         } else {
-            assertEquals(ppos.getIndex(), parseLen);
+            assertEquals(ppos.getIndex(), parseLen, "parse position");
             assertParsed(parsed, YEAR, parseVal != null ? (long) parseVal : null);
         }
     }
 
-    @Test(dataProvider="Parse")
-    public void test_parseLenient(TemporalField field, int width, int baseValue, String input, int pos, int parseLen, Integer parseVal) {
-        setStrict(false);
+   @Test(dataProvider="ParseAll")
+    public void test_parseAllLenient(TemporalField field, int width, int baseValue, String input, int pos, int parseLen, Integer parseVal) {
         ParsePosition ppos = new ParsePosition(pos);
+        setStrict(false);
         TemporalAccessor parsed = getFormatter0(field, width, baseValue).parseUnresolved(input, ppos);
         if (ppos.getErrorIndex() != -1) {
-            assertEquals(ppos.getErrorIndex(), parseLen);
+            assertEquals(ppos.getErrorIndex(), parseLen, "error case parse position");
+            assertEquals(parsed, parseVal, "unexpected parse result");
         } else {
-            assertEquals(ppos.getIndex(), parseLen);
+            assertEquals(ppos.getIndex(), parseLen, "parse position");
             assertParsed(parsed, YEAR, parseVal != null ? (long) parseVal : null);
         }
     }
 
+    //-----------------------------------------------------------------------
+    // Parse data and values in strict and lenient modes.
+    // The data is the ChronoField, minWidth, maxWidth, baseValue, text, startPos,
+    // Strict Pair(endPos, value), Lenient Pair(endPos, value)
+    //-----------------------------------------------------------------------
+    @DataProvider(name="ParseLenientSensitive")
+    Object[][] provider_parseLenientSensitive() {
+        return new Object[][] {
+            // few digits supplied
+            {YEAR, 2, 2, 2010, "3", 0, strict(0, null), lenient(1, 3)},
+            {YEAR, 2, 2, 2010, "4", 0, strict(0, null), lenient(1, 4)},
+            {YEAR, 2, 2, 2010, "5", 1, strict(1, null), lenient(1, null)},
+            {YEAR, 2, 2, 2010, "6-2", 0, strict(0, null), lenient(1, 6)},
+            {YEAR, 2, 2, 2010, "9", 0, strict(0, null), lenient(1, 9)},
+
+            // other junk
+            {YEAR, 1, 4, 2000, "7A", 0, strict(1, 2007), lenient(1, 2007)},
+            {YEAR, 2, 2, 2010, "8A", 0, strict(0, null), lenient(1, 8)},
+
+            // Negative sign cases
+            {YEAR, 2, 4, 2000, "-1", 0, strict(0, null), lenient(2, -1)},
+            {YEAR, 2, 4, 2000, "-10", 0, strict(0, null), lenient(3, -10)},
+
+            // Positive sign cases
+            {YEAR, 2, 4, 2000, "+1", 0, strict(0, null), lenient(2, 1)},
+            {YEAR, 2, 4, 2000, "+10", 0, strict(0, null), lenient(3, 2010)},
+
+            // No sign cases
+            {YEAR, 1, 1, 2005, "21", 0, strict(1, 2012), lenient(2, 21)},
+            {YEAR, 1, 2, 2010, "12", 0, strict(2, 12), lenient(2, 12)},
+            {YEAR, 1, 4, 2000, "87", 0, strict(2, 87), lenient(2, 87)},
+            {YEAR, 1, 4, 2000, "9876", 0, strict(4, 9876), lenient(4, 9876)},
+            {YEAR, 2, 2, 2010, "321", 0, strict(2, 2032), lenient(3, 321)},
+            {YEAR, 2, 4, 2010, "2", 0, strict(0, null), lenient(1, 2)},
+            {YEAR, 2, 4, 2010, "21", 0, strict(2, 2021), lenient(2, 2021)},
+            {YEAR, 2, 4, 2010, "321", 0, strict(3, 321), lenient(3, 321)},
+            {YEAR, 2, 4, 2010, "4321", 0, strict(4, 4321), lenient(4, 4321)},
+            {YEAR, 2, 4, 2010, "54321", 0, strict(4, 5432), lenient(5, 54321)},
+            {YEAR, 2, 8, 2010, "87654321", 3, strict(8, 54321), lenient(8, 54321)},
+            {YEAR, 2, 9, 2010, "987654321", 0, strict(9, 987654321), lenient(9, 987654321)},
+            {YEAR, 3, 3, 2010, "765", 0, strict(3, 2765), lenient(3, 2765)},
+            {YEAR, 3, 4, 2010, "76", 0, strict(0, null), lenient(2, 76)},
+            {YEAR, 3, 4, 2010, "765", 0, strict(3, 2765), lenient(3, 2765)},
+            {YEAR, 3, 4, 2010, "7654", 0, strict(4, 7654), lenient(4, 7654)},
+            {YEAR, 3, 4, 2010, "76543", 0, strict(4, 7654), lenient(5, 76543)},
+
+            // Negative baseValue
+            {YEAR, 2, 4, -2005, "123", 0, strict(3, 123), lenient(3, 123)},
+        };
+    }
+
+    //-----------------------------------------------------------------------
+    // Parsing tests for strict mode
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="ParseLenientSensitive")
+    public void test_parseStrict(TemporalField field, int minWidth, int maxWidth, int baseValue, String input, int pos,
+        Pair strict, Pair lenient) {
+        ParsePosition ppos = new ParsePosition(pos);
+        setStrict(true);
+        TemporalAccessor parsed = getFormatter0(field, minWidth, maxWidth, baseValue).parseUnresolved(input, ppos);
+        if (ppos.getErrorIndex() != -1) {
+            assertEquals(ppos.getErrorIndex(), strict.parseLen, "error case parse position");
+            assertEquals(parsed, strict.parseVal, "unexpected parse result");
+        } else {
+            assertEquals(ppos.getIndex(), strict.parseLen, "parse position");
+            assertParsed(parsed, YEAR, strict.parseVal != null ? (long) strict.parseVal : null);
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    // Parsing tests for lenient mode
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="ParseLenientSensitive")
+    public void test_parseLenient(TemporalField field, int minWidth, int maxWidth, int baseValue, String input, int pos,
+        Pair strict, Pair lenient) {
+        ParsePosition ppos = new ParsePosition(pos);
+        setStrict(false);
+        TemporalAccessor parsed = getFormatter0(field, minWidth, maxWidth, baseValue).parseUnresolved(input, ppos);
+        if (ppos.getErrorIndex() != -1) {
+            assertEquals(ppos.getErrorIndex(), lenient.parseLen, "error case parse position");
+            assertEquals(parsed, lenient.parseVal, "unexpected parse result");
+        } else {
+            assertEquals(ppos.getIndex(), lenient.parseLen, "parse position");
+            assertParsed(parsed, YEAR, lenient.parseVal != null ? (long) lenient.parseVal : null);
+        }
+    }
+
     private void assertParsed(TemporalAccessor parsed, TemporalField field, Long value) {
         if (value == null) {
-            assertEquals(parsed, null);
+            assertEquals(parsed, null, "Parsed Value");
         } else {
-            assertEquals(parsed.isSupported(field), true);
-            assertEquals(parsed.getLong(field), (long) value);
+            assertEquals(parsed.isSupported(field), true, "isSupported: " + field);
+            assertEquals(parsed.getLong(field), (long) value, "Temporal.getLong: " + field);
+        }
+    }
+
+
+    //-----------------------------------------------------------------------
+    // Cases and values in adjacent parsing mode
+    //-----------------------------------------------------------------------
+    @DataProvider(name="ParseAdjacent")
+    Object[][] provider_parseAdjacent() {
+        return new Object[][] {
+            // general
+            {"yyMMdd", "19990703",  LENIENT, 0, 8, 1999, 7, 3},
+            {"yyMMdd", "19990703",  STRICT, 0, 6, 2019, 99, 7},
+            {"yyMMdd", "990703",    LENIENT, 0, 6, 2099, 7, 3},
+            {"yyMMdd", "990703",    STRICT, 0, 6, 2099, 7, 3},
+            {"yyMMdd", "200703",    LENIENT, 0, 6, 2020, 7, 3},
+            {"yyMMdd", "200703",    STRICT, 0, 6, 2020, 7, 3},
+            {"ddMMyy", "230714",    LENIENT, 0, 6, 2014, 7, 23},
+            {"ddMMyy", "230714",    STRICT, 0, 6, 2014, 7, 23},
+            {"ddMMyy", "25062001",  LENIENT, 0, 8, 2001, 20, 2506},
+            {"ddMMyy", "25062001",  STRICT, 0, 6, 2020, 6, 25},
+            {"ddMMy",  "27052002",  LENIENT, 0, 8, 2002, 5, 27},
+            {"ddMMy",  "27052002",  STRICT, 0, 8, 2002, 5, 27},
+        };
+    }
+
+    @Test(dataProvider="ParseAdjacent")
+    public void test_parseAdjacent(String pattern, String input, boolean strict, int pos, int parseLen, int year, int month, int day) {
+        ParsePosition ppos = new ParsePosition(0);
+        builder = new DateTimeFormatterBuilder();
+        setStrict(strict);
+        builder.appendPattern(pattern);
+        DateTimeFormatter dtf = builder.toFormatter();
+
+        TemporalAccessor parsed = dtf.parseUnresolved(input, ppos);
+        assertNotNull(parsed, String.format("parse failed: ppos: %s, formatter: %s%n", ppos.toString(), dtf));
+        if (ppos.getErrorIndex() != -1) {
+            assertEquals(ppos.getErrorIndex(), parseLen, "error case parse position");
+        } else {
+            assertEquals(ppos.getIndex(), parseLen, "parse position");
+            assertParsed(parsed, YEAR_OF_ERA, Long.valueOf(year));
+            assertParsed(parsed, MONTH_OF_YEAR, Long.valueOf(month));
+            assertParsed(parsed, DAY_OF_MONTH, Long.valueOf(day));
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    // Class to structure the test data
+    //-----------------------------------------------------------------------
+
+    private static Pair strict(int parseLen, Integer parseVal) {
+        return new Pair(parseLen, parseVal, STRICT);
+    }
+    private static Pair lenient(int parseLen, Integer parseVal) {
+        return new Pair(parseLen, parseVal, LENIENT);
+    }
+
+    private static class Pair {
+        public final int parseLen;
+        public final Integer parseVal;
+        private final boolean strict;
+        public Pair(int parseLen, Integer parseVal, boolean strict) {
+            this.parseLen = parseLen;
+            this.parseVal = parseVal;
+            this.strict = strict;
+        }
+        public String toString() {
+            return (strict ? "strict" : "lenient") + "(" + parseLen + "," + parseVal + ")";
         }
     }
 
diff --git a/jdk/test/java/time/test/java/time/format/TestReducedPrinter.java b/jdk/test/java/time/test/java/time/format/TestReducedPrinter.java
index b213b80..5ff2cd5 100644
--- a/jdk/test/java/time/test/java/time/format/TestReducedPrinter.java
+++ b/jdk/test/java/time/test/java/time/format/TestReducedPrinter.java
@@ -59,6 +59,7 @@
  */
 package test.java.time.format;
 
+import java.text.ParsePosition;
 import static java.time.temporal.ChronoField.YEAR;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.fail;
@@ -66,6 +67,11 @@
 import java.time.DateTimeException;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static java.time.temporal.ChronoField.YEAR_OF_ERA;
+import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
 
 import org.testng.annotations.DataProvider;
@@ -79,7 +85,11 @@
 public class TestReducedPrinter extends AbstractTestPrinterParser {
 
     private DateTimeFormatter getFormatter0(TemporalField field, int width, int baseValue) {
-        return builder.appendValueReduced(field, width, baseValue).toFormatter(locale).withSymbols(symbols);
+        return builder.appendValueReduced(field, width, baseValue).toFormatter(locale).withDecimalStyle(decimalStyle);
+    }
+
+    private DateTimeFormatter getFormatter0(TemporalField field, int minWidth, int maxWidth, int baseValue) {
+        return builder.appendValueReduced(field, minWidth, maxWidth, baseValue).toFormatter(locale).withDecimalStyle(decimalStyle);
     }
 
     //-----------------------------------------------------------------------
@@ -99,66 +109,76 @@
     @DataProvider(name="Pivot")
     Object[][] provider_pivot() {
         return new Object[][] {
-            {1, 2010, 2010, "0"},
-            {1, 2010, 2011, "1"},
-            {1, 2010, 2012, "2"},
-            {1, 2010, 2013, "3"},
-            {1, 2010, 2014, "4"},
-            {1, 2010, 2015, "5"},
-            {1, 2010, 2016, "6"},
-            {1, 2010, 2017, "7"},
-            {1, 2010, 2018, "8"},
-            {1, 2010, 2019, "9"},
-            {1, 2010, 2009, "9"},
-            {1, 2010, 2020, "0"},
+            {1, 1, 2010, 2010, "0"},
+            {1, 1, 2010, 2011, "1"},
+            {1, 1, 2010, 2012, "2"},
+            {1, 1, 2010, 2013, "3"},
+            {1, 1, 2010, 2014, "4"},
+            {1, 1, 2010, 2015, "5"},
+            {1, 1, 2010, 2016, "6"},
+            {1, 1, 2010, 2017, "7"},
+            {1, 1, 2010, 2018, "8"},
+            {1, 1, 2010, 2019, "9"},
+            {1, 1, 2010, 2009, "9"},
+            {1, 1, 2010, 2020, "0"},
 
-            {2, 2010, 2010, "10"},
-            {2, 2010, 2011, "11"},
-            {2, 2010, 2021, "21"},
-            {2, 2010, 2099, "99"},
-            {2, 2010, 2100, "00"},
-            {2, 2010, 2109, "09"},
-            {2, 2010, 2009, "09"},
-            {2, 2010, 2110, "10"},
+            {2, 2, 2010, 2010, "10"},
+            {2, 2, 2010, 2011, "11"},
+            {2, 2, 2010, 2021, "21"},
+            {2, 2, 2010, 2099, "99"},
+            {2, 2, 2010, 2100, "00"},
+            {2, 2, 2010, 2109, "09"},
+            {2, 2, 2010, 2009, "09"},
+            {2, 2, 2010, 2110, "10"},
 
-            {2, 2005, 2005, "05"},
-            {2, 2005, 2099, "99"},
-            {2, 2005, 2100, "00"},
-            {2, 2005, 2104, "04"},
-            {2, 2005, 2004, "04"},
-            {2, 2005, 2105, "05"},
+            {2, 2, 2005, 2005, "05"},
+            {2, 2, 2005, 2099, "99"},
+            {2, 2, 2005, 2100, "00"},
+            {2, 2, 2005, 2104, "04"},
+            {2, 2, 2005, 2004, "04"},
+            {2, 2, 2005, 2105, "05"},
 
-            {3, 2005, 2005, "005"},
-            {3, 2005, 2099, "099"},
-            {3, 2005, 2100, "100"},
-            {3, 2005, 2999, "999"},
-            {3, 2005, 3000, "000"},
-            {3, 2005, 3004, "004"},
-            {3, 2005, 2004, "004"},
-            {3, 2005, 3005, "005"},
+            {3, 3, 2005, 2005, "005"},
+            {3, 3, 2005, 2099, "099"},
+            {3, 3, 2005, 2100, "100"},
+            {3, 3, 2005, 2999, "999"},
+            {3, 3, 2005, 3000, "000"},
+            {3, 3, 2005, 3004, "004"},
+            {3, 3, 2005, 2004, "004"},
+            {3, 3, 2005, 3005, "005"},
 
-            {9, 2005, 2005, "000002005"},
-            {9, 2005, 2099, "000002099"},
-            {9, 2005, 2100, "000002100"},
-            {9, 2005, 999999999, "999999999"},
-            {9, 2005, 1000000000, "000000000"},
-            {9, 2005, 1000002004, "000002004"},
-            {9, 2005, 2004, "000002004"},
-            {9, 2005, 1000002005, "000002005"},
+            {9, 9, 2005, 2005, "000002005"},
+            {9, 9, 2005, 2099, "000002099"},
+            {9, 9, 2005, 2100, "000002100"},
+            {9, 9, 2005, 999999999, "999999999"},
+            {9, 9, 2005, 1000000000, "000000000"},
+            {9, 9, 2005, 1000002004, "000002004"},
+            {9, 9, 2005, 2004, "000002004"},
+            {9, 9, 2005, 1000002005, "000002005"},
 
-            {2, -2005, -2005, "05"},
-            {2, -2005, -2000, "00"},
-            {2, -2005, -1999, "99"},
-            {2, -2005, -1904, "04"},
-            {2, -2005, -2006, "06"},
-            {2, -2005, -1905, "05"},
-       };
+            {2, 2, -2005, -2005, "05"},
+            {2, 2, -2005, -2000, "00"},
+            {2, 2, -2005, -1999, "99"},
+            {2, 2, -2005, -1904, "04"},
+            {2, 2, -2005, -2006, "06"},
+            {2, 2, -2005, -1905, "05"},
+
+            {2, 4, 2005, 2099, "99"},
+            {2, 4, 2005, 2100, "00"},
+            {2, 4, 2005, 9999, "9999"},
+            {2, 4, 2005, 1000000000, "00"},
+            {2, 4, 2005, 1000002004, "2004"},
+            {2, 4, 2005, 2004, "2004"},
+            {2, 4, 2005, 2005, "05"},
+            {2, 4, 2005, 2104, "04"},
+            {2, 4, 2005, 2105, "2105"},
+        };
     }
 
     @Test(dataProvider="Pivot")
-    public void test_pivot(int width, int baseValue, int value, String result) throws Exception {
+    public void test_pivot(int minWidth, int maxWidth, int baseValue, int value, String result) throws Exception {
         try {
-            getFormatter0(YEAR, width, baseValue).formatTo(new MockFieldValue(YEAR, value), buf);
+            getFormatter0(YEAR, minWidth, maxWidth, baseValue).formatTo(new MockFieldValue(YEAR, value), buf);
             if (result == null) {
                 fail("Expected exception");
             }
@@ -174,7 +194,34 @@
 
     //-----------------------------------------------------------------------
     public void test_toString() throws Exception {
-        assertEquals(getFormatter0(YEAR, 2, 2005).toString(), "ReducedValue(Year,2,2005)");
+        assertEquals(getFormatter0(YEAR, 2, 2, 2005).toString(), "ReducedValue(Year,2,2,2005)");
+    }
+
+    //-----------------------------------------------------------------------
+    // Cases and values in adjacent parsing mode
+    //-----------------------------------------------------------------------
+    @DataProvider(name="PrintAdjacent")
+    Object[][] provider_printAdjacent() {
+        return new Object[][] {
+            // general
+            {"yyMMdd", "990703",   1999, 7, 3},
+            {"yyMMdd", "990703",   2099, 7, 3},
+            {"yyMMdd", "200703",   2020, 7, 3},
+            {"ddMMyy", "030714",   2014, 7, 3},
+            {"ddMMyy", "030720",   2020, 7, 3},
+            {"ddMMy",  "03072001", 2001, 7, 3},
+        };
+    }
+
+    @Test(dataProvider="PrintAdjacent")
+    public void test_printAdjacent(String pattern, String text, int year, int month, int day) {
+        builder = new DateTimeFormatterBuilder();
+        builder.appendPattern(pattern);
+        DateTimeFormatter dtf = builder.toFormatter();
+
+        LocalDate ld = LocalDate.of(year, month, day);
+        String actual = dtf.format(ld);
+        assertEquals(actual, text, "formatter output: " + dtf);
     }
 
 }
diff --git a/jdk/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java b/jdk/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java
index 0175c22..7ab8804 100644
--- a/jdk/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java
+++ b/jdk/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java
@@ -28,7 +28,7 @@
 import java.text.DateFormatSymbols;
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatSymbols;
+import java.time.format.DecimalStyle;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.TextStyle;
@@ -55,7 +55,7 @@
     protected static DateTimeFormatter getFormatter(Locale locale, TextStyle style) {
         return new DateTimeFormatterBuilder().appendZoneText(style)
                                              .toFormatter(locale)
-                                             .withSymbols(DateTimeFormatSymbols.of(locale));
+                                             .withDecimalStyle(DecimalStyle.of(locale));
     }
 
     public void test_printText() {
@@ -148,7 +148,7 @@
     public void test_ParseText(String expected, String text, Set<ZoneId> preferred, Locale locale, TextStyle style) {
         DateTimeFormatter fmt = new DateTimeFormatterBuilder().appendZoneText(style, preferred)
                                                               .toFormatter(locale)
-                                                              .withSymbols(DateTimeFormatSymbols.of(locale));
+                                                              .withDecimalStyle(DecimalStyle.of(locale));
 
         String ret = fmt.parse(text, TemporalQuery.zone()).getId();
 
@@ -209,7 +209,7 @@
         }
         return db.appendZoneText(style)
                  .toFormatter(locale)
-                 .withSymbols(DateTimeFormatSymbols.of(locale));
+                 .withDecimalStyle(DecimalStyle.of(locale));
     }
 
 }
diff --git a/jdk/test/java/util/Base64/TestBase64.java b/jdk/test/java/util/Base64/TestBase64.java
index 94413a2..a8895a0 100644
--- a/jdk/test/java/util/Base64/TestBase64.java
+++ b/jdk/test/java/util/Base64/TestBase64.java
@@ -23,6 +23,7 @@
 
 /**
  * @test 4235519 8004212 8005394 8007298 8006295 8006315 8006530 8007379 8008925
+ *       8014217
  * @summary tests java.util.Base64
  */
 
@@ -110,6 +111,14 @@
         // illegal ending unit
         checkIAE(new Runnable() { public void run() { Base64.getMimeDecoder().decode("$=#"); }});
 
+        checkIOE(new Testable() { public void test() throws IOException {
+                                     byte[] bytes = "AA=".getBytes("ASCII");
+                                     try (InputStream stream =
+                                              Base64.getDecoder().wrap(new ByteArrayInputStream(bytes))) {
+                                         while (stream.read() != -1);
+                                     }
+        }});
+
         // test return value from decode(ByteBuffer, ByteBuffer)
         testDecBufRet();
 
diff --git a/jdk/test/java/util/BitSet/BitSetStreamTest.java b/jdk/test/java/util/BitSet/BitSetStreamTest.java
new file mode 100644
index 0000000..a7fae5c
--- /dev/null
+++ b/jdk/test/java/util/BitSet/BitSetStreamTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.Integer;
+import java.lang.Object;
+import java.lang.System;
+import java.util.BitSet;
+import java.util.OptionalInt;
+import java.util.PrimitiveIterator;
+import java.util.Random;
+import java.util.function.IntSupplier;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+/**
+ * @test
+ * @summary test BitSet stream
+ * @bug 8012645
+ * @run testng BitSetStreamTest
+ */
+public class BitSetStreamTest {
+    static class Fibs implements IntSupplier {
+        private int n1 = 0;
+        private int n2 = 1;
+
+        static int fibs(int n) {
+            Fibs f = new Fibs();
+            while (n-- > 0) f.getAsInt();
+            return f.getAsInt();
+        }
+
+        public int getAsInt() { int s = n1; n1 = n2; n2 = s + n1; return s; }
+    }
+
+    private static final Object[][] testcases = new Object[][] {
+        { "none", IntStream.empty() },
+        { "index 0", IntStream.of(0) },
+        { "index 255", IntStream.of(255) },
+        { "every bit", IntStream.range(0, 255) },
+        { "step 2", IntStream.range(0, 255, 2) },
+        { "step 3", IntStream.range(0, 255, 3) },
+        { "step 5", IntStream.range(0, 255, 5) },
+        { "step 7", IntStream.range(0, 255, 7) },
+        { "1, 10, 100, 1000", IntStream.of(1, 10, 100, 1000) },
+        { "25 fibs", IntStream.generate(new Fibs()).limit(25) }
+    };
+
+    @DataProvider(name = "cases")
+    public static Object[][] produceCases() {
+        return testcases;
+    }
+
+    @Test
+    public void testFibs() {
+        Fibs f = new Fibs();
+        assertEquals(0, f.getAsInt());
+        assertEquals(1, f.getAsInt());
+        assertEquals(1, f.getAsInt());
+        assertEquals(2, f.getAsInt());
+        assertEquals(3, f.getAsInt());
+        assertEquals(5, f.getAsInt());
+        assertEquals(8, f.getAsInt());
+        assertEquals(13, f.getAsInt());
+        assertEquals(987, Fibs.fibs(16));
+    }
+
+    @Test(dataProvider = "cases")
+    public void testBitsetStream(String name, IntStream data) {
+        BitSet bs = new BitSet();
+        long setBits = data.distinct()
+                           .peek(i -> bs.set(i))
+                           .count();
+
+        assertEquals(bs.cardinality(), setBits);
+        assertEquals(bs.cardinality(), bs.stream().reduce(0, (s, i) -> s+1));
+
+        PrimitiveIterator.OfInt it = bs.stream().iterator();
+        for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
+            assertTrue(it.hasNext());
+            assertEquals(it.nextInt(), i);
+        }
+        assertFalse(it.hasNext());
+    }
+
+    @Test
+    public void testRandomStream() {
+        final int size = 1024 * 1024;
+        final int[] seeds = {
+                2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
+                43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
+        final byte[] bytes = new byte[size];
+        for (int seed : seeds) {
+            final Random random = new Random(seed);
+            random.nextBytes(bytes);
+            final BitSet bitSet = BitSet.valueOf(bytes);
+            final int cardinality = bitSet.cardinality();
+            final IntStream stream = bitSet.stream();
+            final int[] array = stream.toArray();
+            assertEquals(array.length, cardinality);
+            int nextSetBit = -1;
+            for (int i=0; i < cardinality; i++) {
+                nextSetBit = bitSet.nextSetBit(nextSetBit + 1);
+                assertEquals(array[i], nextSetBit);
+            }
+        }
+    }
+}
diff --git a/jdk/test/java/util/Collection/MOAT.java b/jdk/test/java/util/Collection/MOAT.java
index 3953240..7abc669 100644
--- a/jdk/test/java/util/Collection/MOAT.java
+++ b/jdk/test/java/util/Collection/MOAT.java
@@ -26,6 +26,7 @@
  * @bug     6207984 6272521 6192552 6269713 6197726 6260652 5073546 4137464
  *          4155650 4216399 4294891 6282555 6318622 6355327 6383475 6420753
  *          6431845 4802633 6570566 6570575 6570631 6570924 6691185 6691215
+ *          4802647 7123424
  * @summary Run many tests on many Collection and Map implementations
  * @author  Martin Buchholz
  * @run main MOAT
@@ -58,6 +59,8 @@
 public class MOAT {
     public static void realMain(String[] args) {
 
+        testCollection(new NewAbstractCollection<Integer>());
+        testCollection(new NewAbstractSet<Integer>());
         testCollection(new LinkedHashSet<Integer>());
         testCollection(new HashSet<Integer>());
         testCollection(new Vector<Integer>());
@@ -753,6 +756,14 @@
         // The "all" operations should throw NPE when passed null
         //----------------------------------------------------------------
         {
+            clear(c);
+            try {
+                c.removeAll(null);
+                fail("Expected NullPointerException");
+            }
+            catch (NullPointerException e) { pass(); }
+            catch (Throwable t) { unexpected(t); }
+
             oneElement(c);
             try {
                 c.removeAll(null);
@@ -761,6 +772,14 @@
             catch (NullPointerException e) { pass(); }
             catch (Throwable t) { unexpected(t); }
 
+            clear(c);
+            try {
+                c.retainAll(null);
+                fail("Expected NullPointerException");
+            }
+            catch (NullPointerException e) { pass(); }
+            catch (Throwable t) { unexpected(t); }
+
             oneElement(c);
             try {
                 c.retainAll(null);
@@ -1205,4 +1224,35 @@
     static <T> T serialClone(T obj) {
         try { return (T) readObject(serializedForm(obj)); }
         catch (Exception e) { throw new Error(e); }}
+    private static class NewAbstractCollection<E> extends AbstractCollection<E> {
+        ArrayList<E> list = new ArrayList<>();
+        public boolean remove(Object obj) {
+            return list.remove(obj);
+        }
+        public boolean add(E e) {
+            return list.add(e);
+        }
+        public Iterator<E> iterator() {
+            return list.iterator();
+        }
+        public int size() {
+            return list.size();
+        }
+    }
+    private static class NewAbstractSet<E> extends AbstractSet<E> {
+        HashSet<E> set = new HashSet<>();
+        public boolean remove(Object obj) {
+            return set.remove(obj);
+        }
+        public boolean add(E e) {
+            return set.add(e);
+        }
+        public Iterator<E> iterator() {
+            return set.iterator();
+        }
+        public int size() {
+            return set.size();
+        }
+    }
+
 }
diff --git a/jdk/test/java/util/Iterator/IteratorDefaults.java b/jdk/test/java/util/Iterator/IteratorDefaults.java
new file mode 100644
index 0000000..28b849a
--- /dev/null
+++ b/jdk/test/java/util/Iterator/IteratorDefaults.java
@@ -0,0 +1,425 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+/**
+ * @test
+ * @run testng IteratorDefaults
+ * @summary test extension methods on Iterator
+ */
+@Test
+public class IteratorDefaults {
+
+    private static interface Callback {
+        void call(List<Integer> list);
+    }
+
+    // call the callback for each recursive subList
+    private void trimmedSubList(final List<Integer> list, final Callback callback) {
+        int size = list.size();
+        if (size > 1) {
+            // trim 1 element from both ends
+            final List<Integer> subList = list.subList(1, size - 1);
+            callback.call(subList);
+            trimmedSubList(subList, callback);
+        }
+    }
+
+    public void testRemoveUnsupported() {
+        final Iterator iterator = new Iterator() {
+            @Override
+            public boolean hasNext() {
+                return false;
+            }
+            @Override
+            public Object next() {
+                return null;
+            }
+        };
+
+        try {
+            iterator.remove();
+            fail("expected UnsupportedOperationException from remove not thrown");
+        } catch (UnsupportedOperationException ignore) {
+        }
+    }
+
+    public void testRemoveOverride() {
+        final IteratorWithRemove iterator = new IteratorWithRemove();
+        iterator.remove();
+        assertTrue(iterator.removed);
+    }
+
+    public void testForEach() throws Exception {
+        final Integer[] data = new Integer[1000];
+        for (int i=0; i < data.length; i++) {
+            data[i] = i;
+        }
+        final List<Integer> source = Arrays.asList(data);
+
+        final String[] iterableCollectionClasses = {
+                "java.util.ArrayDeque",
+                "java.util.ArrayList",
+                "java.util.HashSet",
+                "java.util.LinkedHashSet",
+                "java.util.LinkedList",
+                "java.util.PriorityQueue",
+                "java.util.TreeSet",
+                "java.util.Vector",
+                "java.util.concurrent.ConcurrentLinkedDeque",
+                "java.util.concurrent.ConcurrentLinkedQueue",
+                "java.util.concurrent.ConcurrentSkipListSet",
+                "java.util.concurrent.CopyOnWriteArrayList",
+                "java.util.concurrent.CopyOnWriteArraySet",
+                "java.util.concurrent.LinkedBlockingDeque",
+                "java.util.concurrent.LinkedBlockingQueue",
+                "java.util.concurrent.LinkedTransferQueue",
+                "java.util.concurrent.PriorityBlockingQueue"
+        };
+
+        for (final String iterableClass : iterableCollectionClasses) {
+            final Iterable<Integer> iterable =
+                    (Iterable<Integer>) Class.forName(iterableClass).newInstance();
+            ((Collection<Integer>) iterable).addAll(source);
+            final Iterator<Integer> iterator = iterable.iterator();
+            final List<Integer> target = new ArrayList<>(source.size());
+            iterator.forEachRemaining(target::add);
+            if ("java.util.HashSet".equals(iterableClass)) {
+                target.sort((x, y) -> x - y);
+                assertEquals(target, source);
+            } else {
+                assertEquals(target, source);
+            }
+
+            // verify that for an iterator that has been advanced via next(),
+            // forEach starts from the current location, not zero
+            final int OFFSET = 5;
+            final List<Integer> reference2 = new ArrayList<>(source).subList(OFFSET, source.size());
+            final List<Integer> removed2 = new ArrayList<>(OFFSET);
+            final Iterator<Integer> iterator2 = iterable.iterator();
+            for (int i=0; i < OFFSET; i++) {
+                // advance the iterator by OFFSET, saving iterated elements
+                removed2.add(iterator2.next());
+            }
+            final List<Integer> target2 = new ArrayList<>(reference2.size());
+            iterator2.forEachRemaining(target2::add);
+            if ("java.util.HashSet".equals(iterableClass)) {
+                assertEquals(target2.size(), reference2.size());
+                target2.addAll(removed2);
+                target2.sort((x, y) -> x - y);
+                assertEquals(target2, source);
+                assertEquals(target2.subList(OFFSET, source.size()), reference2);
+            } else {
+                assertEquals(target2, reference2);
+            }
+        }
+    }
+
+    public void testForEachSubList() throws Exception {
+        final Integer[] data = new Integer[100];
+        for (int i = 0; i < data.length; i++) {
+            data[i] = i;
+        }
+        final List<Integer> source = Arrays.asList(data);
+        final String[] listClasses = {
+                "java.util.ArrayList",
+                "java.util.LinkedList",
+                "java.util.Vector",
+                "java.util.concurrent.CopyOnWriteArrayList"
+        };
+        for (final String listClass : listClasses) {
+            final List<Integer> list =
+                    (List<Integer>) Class.forName(listClass).newInstance();
+            list.addAll(source);
+            trimmedSubList(list, new Callback() {
+                @Override
+                public void call(final List<Integer> list) {
+                    if (list.size() < 1) {
+                        return;
+                    }
+                    final List<Integer> target = new ArrayList<>(list.size());
+                    final ListIterator<Integer> iterator = list.listIterator();
+                    assertTrue(iterator.hasNext());
+                    assertFalse(iterator.hasPrevious());
+                    assertEquals(iterator.nextIndex(), 0);
+                    assertEquals(iterator.previousIndex(), -1);
+
+                    iterator.forEachRemaining(target::add);
+                    assertEquals(target, list);
+
+                    assertFalse(iterator.hasNext());
+                    assertTrue(iterator.hasPrevious());
+                    assertEquals(iterator.nextIndex(), list.size());
+                    assertEquals(iterator.previousIndex(), list.size() - 1);
+
+                    try {
+                        iterator.next();
+                        fail(listClass + " iterator advanced beyond end");
+                    } catch (NoSuchElementException ignore) {
+                    }
+                }
+            });
+        }
+    }
+
+    public void testOptimizedForEach() throws Exception {
+        final Integer[] data = new Integer[1000 * 1000];
+        for (int i=0; i < data.length; i++) {
+            data[i] = i;
+        }
+        final List<Integer> source = Arrays.asList(data);
+
+        final String[] listClasses = {
+                "java.util.ArrayList",
+                "java.util.LinkedList",
+                "java.util.Vector",
+                "java.util.concurrent.CopyOnWriteArrayList"
+        };
+
+        final int OFFSET = 3;
+        final List<Integer> target = new ArrayList<>(source);
+        for (final String listClass : listClasses) {
+            final List<Integer> list =
+                    (List<Integer>) Class.forName(listClass).newInstance();
+            list.addAll(source);
+            final ListIterator<Integer> iterator = list.listIterator();
+            assertFalse(iterator.hasPrevious());
+            for (int i=0; i < OFFSET; i++) {
+                iterator.next();
+            }
+            assertTrue(iterator.hasNext());
+            assertTrue(iterator.hasPrevious());
+            assertEquals(iterator.nextIndex(), OFFSET);
+            assertEquals(iterator.previousIndex(), OFFSET - 1);
+
+            iterator.forEachRemaining(e -> {
+                target.set(e, e + 1);
+            });
+            for (int i=OFFSET; i < data.length; i++) {
+                assertEquals(target.get(i).intValue(), source.get(i)+1);
+            }
+
+            assertFalse(iterator.hasNext());
+            assertTrue(iterator.hasPrevious());
+            assertEquals(iterator.nextIndex(), data.length);
+            assertEquals(iterator.previousIndex(), data.length - 1);
+
+            // CopyOnWriteArrayList.listIterator().remove() is unsupported
+            if (!"java.util.concurrent.CopyOnWriteArrayList".equals(listClass)) {
+                for (int i = data.length - 1; i >= 0; i--) {
+                    iterator.remove(); // must not throw
+                    if (i > 0) {
+                        iterator.previous();
+                    }
+                }
+                assertTrue(list.isEmpty());
+            }
+
+            try {
+                iterator.next();
+                fail(listClass + " iterator advanced beyond end");
+            } catch (NoSuchElementException ignore) {
+            }
+        }
+    }
+
+    @Test(enabled = false)
+    public void compareForEachPerformance() throws Exception {
+        final Integer[] data = new Integer[1000 * 100];
+        for (int i=0; i < data.length; i++) {
+            data[i] = i;
+        }
+        final List<Integer> source = Arrays.asList(data);
+
+        final String[] iterableCollectionClasses = {
+                "java.util.ArrayList", // warmup, results discarded
+                "java.util.ArrayDeque",
+                "java.util.ArrayList",
+                "java.util.HashSet",
+                "java.util.LinkedHashSet",
+                "java.util.LinkedList",
+                "java.util.PriorityQueue",
+                "java.util.TreeSet",
+                "java.util.Vector",
+                "java.util.concurrent.ConcurrentLinkedDeque",
+                "java.util.concurrent.ConcurrentLinkedQueue",
+                "java.util.concurrent.ConcurrentSkipListSet",
+                "java.util.concurrent.CopyOnWriteArrayList",
+                "java.util.concurrent.CopyOnWriteArraySet",
+                "java.util.concurrent.LinkedBlockingDeque",
+                "java.util.concurrent.LinkedBlockingQueue",
+                "java.util.concurrent.LinkedTransferQueue",
+                "java.util.concurrent.PriorityBlockingQueue"
+        };
+
+        boolean warmup = true;
+        final int ITERATIONS = 10;
+        final Integer[] target = new Integer[source.size()];
+        for (final String iterableClass : iterableCollectionClasses) {
+            final Class<? extends Collection<Integer>> type =
+                    (Class<? extends Collection<Integer>>) Class.forName(iterableClass);
+            final Constructor<? extends Collection<Integer>> copyConstructor =
+                    type.getConstructor(Collection.class);
+            final Iterable<Integer> iterable = copyConstructor.newInstance(source);
+            final Iterable<Integer> reference =
+                    Collections.unmodifiableCollection((Collection<Integer>) iterable);
+
+            for (int i=0; i < ITERATIONS; i++) {
+                final Iterator<Integer> iterator = reference.iterator();
+                final long forEachStart = System.nanoTime();
+                iterator.forEachRemaining(x -> {target[x.intValue()] = x;});
+                final long forEachEnd = System.nanoTime();
+
+                final Iterator<Integer> iterator2 = reference.iterator();
+                Integer x;
+                final long iteratorStart = System.nanoTime();
+                while (iterator2.hasNext()) {
+                    x = iterator2.next();
+                    target[x.intValue()] = x;
+                }
+                final long iteratorEnd = System.nanoTime();
+
+                if (warmup) { continue; } // warmup, discard results
+                final long forEachTime = forEachEnd - forEachStart;
+                final long iteratorTime = iteratorEnd - iteratorStart;
+                final long speedup = iteratorTime - forEachTime;
+                System.out.print(iterableClass);
+                System.out.print(" iterator: ");
+                System.out.print(iteratorTime);
+                System.out.print(", forEach: ");
+                System.out.print(forEachTime);
+                System.out.print(", speedup: ");
+                System.out.print(speedup);
+                System.out.print(" (");
+                System.out.print((speedup * 100) / iteratorTime);
+                System.out.print("%)\n");
+            }
+            if (warmup) { warmup = false; }
+            System.out.println();
+        }
+    }
+
+    @Test(enabled = false)
+    public void compareSubListForEachPerformance() throws Exception {
+        final Integer[] data = new Integer[1000 * 100];
+        for (int i = 0; i < data.length; i++) {
+            data[i] = i;
+        }
+        final List<Integer> source = Arrays.asList(data);
+
+        final String[] listClasses = {
+                "java.util.ArrayList", // warmup, results discarded
+                "java.util.ArrayList",
+                "java.util.LinkedList",
+                "java.util.Vector",
+                "java.util.concurrent.CopyOnWriteArrayList"
+        };
+
+        boolean warmup = true;
+        final int ITERATIONS = 10;
+        final Integer[] target = new Integer[source.size()];
+        for (final String listClass : listClasses) {
+            final Class<? extends List<Integer >> type =
+                    (Class<? extends List<Integer>>) Class.forName(listClass);
+            final Constructor<? extends List<Integer >> copyConstructor =
+                    type.getConstructor(Collection.class);
+            final List<Integer> iterable = copyConstructor.newInstance(source);
+            final List<Integer> reference = Collections.unmodifiableList(iterable);
+
+            for (int i = 0; i < ITERATIONS; i++) {
+                final Iterator<Integer> iterator = reference.subList(42, reference.size() - 37).iterator();
+                final long forEachStart = System.nanoTime();
+                iterator.forEachRemaining(x -> {
+                    target[x.intValue()] = x;
+                });
+                final long forEachEnd = System.nanoTime();
+
+                final Iterator<Integer> iterator2 = reference.iterator();
+                Integer x;
+                final long iteratorStart = System.nanoTime();
+                while (iterator2.hasNext()) {
+                    x = iterator2.next();
+                    target[x.intValue()] = x;
+                }
+                final long iteratorEnd = System.nanoTime();
+
+                if (warmup) { continue; } // warmup, discard results
+                final long forEachTime = forEachEnd - forEachStart;
+                final long iteratorTime = iteratorEnd - iteratorStart;
+                final long speedup = iteratorTime - forEachTime;
+                System.out.print(listClass);
+                System.out.print(" iterator: ");
+                System.out.print(iteratorTime);
+                System.out.print(", forEach: ");
+                System.out.print(forEachTime);
+                System.out.print(", speedup: ");
+                System.out.print(speedup);
+                System.out.print(" (");
+                System.out.print((speedup * 100) / iteratorTime);
+                System.out.print("%)\n");
+            }
+            if (warmup) { warmup = false; }
+            System.out.println();
+        }
+    }
+
+    static class IteratorWithRemove implements Iterator {
+
+        public boolean removed;
+
+        IteratorWithRemove() {
+            removed = false;
+        }
+
+        @Override
+        public boolean hasNext() {
+            return false;
+        }
+
+        @Override
+        public Object next() {
+            return null;
+        }
+
+        @Override
+        public void remove() {
+            removed = true;
+        }
+    }
+}
diff --git a/jdk/test/java/util/Locale/LocaleProviders.java b/jdk/test/java/util/Locale/LocaleProviders.java
index 3159b4b..e5324e4 100644
--- a/jdk/test/java/util/Locale/LocaleProviders.java
+++ b/jdk/test/java/util/Locale/LocaleProviders.java
@@ -60,6 +60,10 @@
                 bug8010666Test();
                 break;
 
+            case "bug8013086Test":
+                bug8013086Test(args[1], args[2]);
+                break;
+
             default:
                 throw new RuntimeException("Test method '"+methodName+"' not found.");
         }
@@ -114,27 +118,67 @@
         if (System.getProperty("os.name").startsWith("Windows")) {
             NumberFormat nf = NumberFormat.getInstance(Locale.US);
             try {
-                double ver = nf.parse(System.getProperty("os.version")).doubleValue();
+                double ver = nf.parse(System.getProperty("os.version"))
+                               .doubleValue();
                 System.out.printf("Windows version: %.1f\n", ver);
                 if (ver >= 6.0) {
-                    LocaleProviderAdapter lda = LocaleProviderAdapter.getAdapter(LocaleNameProvider.class, Locale.ENGLISH);
+                    LocaleProviderAdapter lda =
+                        LocaleProviderAdapter.getAdapter(
+                            LocaleNameProvider.class, Locale.ENGLISH);
                     LocaleProviderAdapter.Type type = lda.getAdapterType();
                     if (type == LocaleProviderAdapter.Type.HOST) {
+                        LocaleNameProvider lnp = lda.getLocaleNameProvider();
                         Locale mkmk = Locale.forLanguageTag("mk-MK");
                         String result = mkmk.getDisplayLanguage(Locale.ENGLISH);
-                        if (!"Macedonian (FYROM)".equals(result)) {
-                            throw new RuntimeException("Windows locale name provider did not return expected localized language name for \"mk\". Returned name was \"" + result + "\"");
+                        String hostResult =
+                            lnp.getDisplayLanguage(mkmk.getLanguage(),
+                                                   Locale.ENGLISH);
+                        System.out.printf("  Display language name for" +
+                            " (mk_MK): result(HOST): \"%s\", returned: \"%s\"\n",
+                            hostResult, result);
+                        if (result == null ||
+                            hostResult != null &&
+                            !result.equals(hostResult)) {
+                            throw new RuntimeException("Display language name" +
+                                " mismatch for \"mk\". Returned name was" +
+                                " \"" + result + "\", result(HOST): \"" +
+                                hostResult + "\"");
                         }
                         result = Locale.US.getDisplayLanguage(Locale.ENGLISH);
-                        if (!"English".equals(result)) {
-                            throw new RuntimeException("Windows locale name provider did not return expected localized language name for \"en\". Returned name was \"" + result + "\"");
+                        hostResult =
+                            lnp.getDisplayLanguage(Locale.US.getLanguage(),
+                                                   Locale.ENGLISH);
+                        System.out.printf("  Display language name for" +
+                            " (en_US): result(HOST): \"%s\", returned: \"%s\"\n",
+                            hostResult, result);
+                        if (result == null ||
+                            hostResult != null &&
+                            !result.equals(hostResult)) {
+                            throw new RuntimeException("Display language name" +
+                                " mismatch for \"en\". Returned name was" +
+                                " \"" + result + "\", result(HOST): \"" +
+                                hostResult + "\"");
                         }
-                        result = Locale.US.getDisplayCountry(Locale.ENGLISH);
-                        if (ver >= 6.1 && !"United States".equals(result)) {
-                            throw new RuntimeException("Windows locale name provider did not return expected localized country name for \"US\". Returned name was \"" + result + "\"");
+                        if (ver >= 6.1) {
+                            result = Locale.US.getDisplayCountry(Locale.ENGLISH);
+                            hostResult = lnp.getDisplayCountry(
+                                Locale.US.getCountry(), Locale.ENGLISH);
+                            System.out.printf("  Display country name for" +
+                                " (en_US): result(HOST): \"%s\", returned: \"%s\"\n",
+                                hostResult, result);
+                            if (result == null ||
+                                hostResult != null &&
+                                !result.equals(hostResult)) {
+                                throw new RuntimeException("Display country name" +
+                                    " mismatch for \"US\". Returned name was" +
+                                    " \"" + result + "\", result(HOST): \"" +
+                                    hostResult + "\"");
+                            }
                         }
                     } else {
-                        throw new RuntimeException("Windows Host LocaleProviderAdapter was not selected for English locale.");
+                        throw new RuntimeException("Windows Host" +
+                            " LocaleProviderAdapter was not selected for" +
+                            " English locale.");
                     }
                 }
             } catch (ParseException pe) {
@@ -142,4 +186,13 @@
             }
         }
     }
+
+    static void bug8013086Test(String lang, String ctry) {
+        try {
+            // Throws a NullPointerException if the test fails.
+            System.out.println(new SimpleDateFormat("z", new Locale(lang, ctry)).parse("UTC"));
+        } catch (ParseException pe) {
+            // ParseException is fine in this test, as it's not "UTC"
+}
+    }
 }
diff --git a/jdk/test/java/util/Locale/LocaleProviders.sh b/jdk/test/java/util/Locale/LocaleProviders.sh
index 63a74bb..4d8bd06 100644
--- a/jdk/test/java/util/Locale/LocaleProviders.sh
+++ b/jdk/test/java/util/Locale/LocaleProviders.sh
@@ -24,6 +24,7 @@
 #
 # @test
 # @bug 6336885 7196799 7197573 7198834 8000245 8000615 8001440 8010666
+#      8013086 8013233
 # @summary tests for "java.locale.providers" system property
 # @compile -XDignore.symbol.file LocaleProviders.java
 # @run shell/timeout=600 LocaleProviders.sh
@@ -69,7 +70,7 @@
     ;;
 esac
 
-# create an SPI implementation
+# create SPI implementations
 mk() {
   d=`dirname $1`
   if [ ! -d $d ]; then mkdir -p $d; fi
@@ -88,16 +89,38 @@
     }
 
     public Locale[] getAvailableLocales() {
-        Locale[] locales = {Locale.GERMAN, Locale.US, Locale.JAPANESE, Locale.CHINESE};
+        Locale[] locales = {Locale.US};
+        return locales;
+    }
+}
+EOF
+mk ${SPIDIR}${FS}src${FS}tznp8013086.java << EOF
+import java.util.spi.TimeZoneNameProvider;
+import java.util.Locale;
+import java.util.TimeZone;
+
+public class tznp8013086 extends TimeZoneNameProvider {
+    public String getDisplayName(String ID, boolean daylight, int style, Locale locale) {
+        if (!daylight && style==TimeZone.LONG) {
+            return "tznp8013086";
+        } else {
+            return null;
+        }
+    }
+
+    public Locale[] getAvailableLocales() {
+        Locale[] locales = {Locale.JAPAN};
         return locales;
     }
 }
 EOF
 mk ${SPIDIR}${FS}dest${FS}META-INF${FS}services${FS}java.util.spi.TimeZoneNameProvider << EOF
 tznp
+tznp8013086
 EOF
 ${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d ${SPIDIR}${FS}dest \
-    ${SPIDIR}${FS}src${FS}tznp.java
+    ${SPIDIR}${FS}src${FS}tznp.java \
+    ${SPIDIR}${FS}src${FS}tznp8013086.java
 ${COMPILEJAVA}${FS}bin${FS}jar ${TESTTOOLVMOPTS} cvf ${SPIDIR}${FS}tznp.jar -C ${SPIDIR}${FS}dest .
 
 # get the platform default locales
@@ -269,4 +292,12 @@
   runTest
 fi
 
+# testing 8013086 fix.
+METHODNAME=bug8013086Test
+PREFLIST="JRE,SPI -Djava.ext.dirs=${SPIDIR}"
+PARAM1=ja
+PARAM2=JP
+PARAM3=
+runTest
+
 exit $result
diff --git a/jdk/test/java/util/Objects/BasicObjectsTest.java b/jdk/test/java/util/Objects/BasicObjectsTest.java
index 695b57a..3a1cad9 100644
--- a/jdk/test/java/util/Objects/BasicObjectsTest.java
+++ b/jdk/test/java/util/Objects/BasicObjectsTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -23,12 +23,13 @@
 
 /*
  * @test
- * @bug 6797535 6889858 6891113
+ * @bug 6797535 6889858 6891113 8013712 8011800 8014365
  * @summary Basic tests for methods in java.util.Objects
  * @author  Joseph D. Darcy
  */
 
 import java.util.*;
+import java.util.function.*;
 
 public class BasicObjectsTest {
     public static void main(String... args) {
@@ -40,6 +41,8 @@
         errors += testToString();
         errors += testToString2();
         errors += testCompare();
+        errors += testRequireNonNull();
+        errors += testIsNull();
         errors += testNonNull();
         if (errors > 0 )
             throw new RuntimeException();
@@ -158,52 +161,75 @@
         return errors;
     }
 
+    private static int testRequireNonNull() {
+        int errors = 0;
+
+        final String RNN_1 = "1-arg requireNonNull";
+        final String RNN_2 = "2-arg requireNonNull";
+        final String RNN_3 = "Supplier requireNonNull";
+
+        Function<String, String> rnn1 = s -> Objects.requireNonNull(s);
+        Function<String, String> rnn2 = s -> Objects.requireNonNull(s, "trousers");
+        Function<String, String> rnn3 = s -> Objects.requireNonNull(s, () -> "trousers");
+
+        errors += testRNN_NonNull(rnn1, RNN_1);
+        errors += testRNN_NonNull(rnn2, RNN_2);
+        errors += testRNN_NonNull(rnn3, RNN_3);
+
+        errors += testRNN_Null(rnn1, RNN_1, null);
+        errors += testRNN_Null(rnn2, RNN_2, "trousers");
+        errors += testRNN_Null(rnn3, RNN_3, "trousers");
+        return errors;
+    }
+
+    private static int testRNN_NonNull(Function<String, String> testFunc,
+                                       String testFuncName) {
+        int errors = 0;
+        try {
+            String s = testFunc.apply("pants");
+            if (s != "pants") {
+                System.err.printf(testFuncName + " failed to return its arg");
+                errors++;
+            }
+        } catch (NullPointerException e) {
+            System.err.printf(testFuncName + " threw unexpected NPE");
+            errors++;
+        }
+        return errors;
+    }
+
+    private static int testRNN_Null(Function<String, String> testFunc,
+                                    String testFuncName,
+                                    String expectedMessage) {
+        int errors = 0;
+        try {
+            String s = testFunc.apply(null);
+            System.err.printf(testFuncName + " failed to throw NPE");
+            errors++;
+        } catch (NullPointerException e) {
+            if (e.getMessage() != expectedMessage) {
+                System.err.printf(testFuncName + " threw NPE w/ bad detail msg");
+                errors++;
+            }
+        }
+        return errors;
+    }
+
+    private static int testIsNull() {
+        int errors = 0;
+
+        errors += Objects.isNull(null) ? 0 : 1;
+        errors += Objects.isNull(Objects.class) ? 1 : 0;
+
+        return errors;
+    }
+
     private static int testNonNull() {
         int errors = 0;
-        String s;
 
-        // Test 1-arg variant
-        try {
-            s = Objects.requireNonNull("pants");
-            if (s != "pants") {
-                System.err.printf("1-arg non-null failed to return its arg");
-                errors++;
-            }
-        } catch (NullPointerException e) {
-            System.err.printf("1-arg nonNull threw unexpected NPE");
-            errors++;
-        }
+        errors += Objects.nonNull(null) ? 1 : 0;
+        errors += Objects.nonNull(Objects.class) ? 0 : 1;
 
-        try {
-            s = Objects.requireNonNull(null);
-            System.err.printf("1-arg nonNull failed to throw NPE");
-            errors++;
-        } catch (NullPointerException e) {
-            // Expected
-        }
-
-        // Test 2-arg variant
-        try {
-            s = Objects.requireNonNull("pants", "trousers");
-            if (s != "pants") {
-                System.err.printf("2-arg nonNull failed to return its arg");
-                errors++;
-            }
-        } catch (NullPointerException e) {
-            System.err.printf("2-arg nonNull threw unexpected NPE");
-            errors++;
-        }
-
-        try {
-            s = Objects.requireNonNull(null, "pantaloons");
-            System.err.printf("2-arg nonNull failed to throw NPE");
-            errors++;
-        } catch (NullPointerException e) {
-            if (e.getMessage() != "pantaloons") {
-                System.err.printf("2-arg nonNull threw NPE w/ bad detail msg");
-                errors++;
-            }
-        }
         return errors;
     }
 }
diff --git a/jdk/test/java/util/Random/RandomStreamTest.java b/jdk/test/java/util/Random/RandomStreamTest.java
new file mode 100644
index 0000000..c2edf4f
--- /dev/null
+++ b/jdk/test/java/util/Random/RandomStreamTest.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Random;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.DoubleStream;
+import java.util.stream.Stream;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * @test
+ * @run testng RandomStreamTest
+ * @summary test stream methods on Random
+ * @author Brian Goetz
+ */
+public class RandomStreamTest {
+
+    private static final int SIZE = 1000;
+
+    @DataProvider(name = "suppliers")
+    public Object[][] randomSuppliers() {
+        return new Object[][] {
+            {new Random(), SIZE},
+            {new SecureRandom(), SIZE}
+        };
+    }
+
+    @Test(dataProvider = "suppliers")
+    public void testRandomIntStream(final Random random, final int count) {
+        final List<Integer> destination = new ArrayList<>(count);
+        random.ints().limit(count).forEach(destination::add);
+        assertEquals(destination.size(), count);
+    }
+
+    @Test(dataProvider = "suppliers")
+    public void testRandomLongStream(final Random random, final int count) {
+        final List<Long> destination = new ArrayList<>(count);
+        random.longs().limit(count).forEach(destination::add);
+        assertEquals(destination.size(), count);
+    }
+
+    @Test(dataProvider = "suppliers")
+    public void testRandomDoubleStream(final Random random, final int count) {
+        final List<Double> destination = new ArrayList<>(count);
+        random.doubles().limit(count).forEach(destination::add);
+        random.doubles().limit(count).forEach(d -> assertTrue(d >= 0.0 && d < 1.0));
+        assertEquals(destination.size(), count);
+    }
+
+    @Test(dataProvider = "suppliers")
+    public void testRandomGaussianStream(final Random random, final int count) {
+        final List<Double> destination = new ArrayList<>(count);
+        random.gaussians().limit(count).forEach(destination::add);
+        assertEquals(destination.size(), count);
+    }
+
+    @Test
+    public void testIntStream() {
+        final long seed = System.currentTimeMillis();
+        final Random r1 = new Random(seed);
+        final int[] a = new int[SIZE];
+        for (int i=0; i < SIZE; i++) {
+            a[i] = r1.nextInt();
+        }
+
+        final Random r2 = new Random(seed); // same seed
+        final int[] b = r2.ints().limit(SIZE).toArray();
+        assertEquals(a, b);
+    }
+
+    @Test
+    public void testLongStream() {
+        final long seed = System.currentTimeMillis();
+        final Random r1 = new Random(seed);
+        final long[] a = new long[SIZE];
+        for (int i=0; i < SIZE; i++) {
+            a[i] = r1.nextLong();
+        }
+
+        final Random r2 = new Random(seed); // same seed
+        final long[] b = r2.longs().limit(SIZE).toArray();
+        assertEquals(a, b);
+    }
+
+    @Test
+    public void testDoubleStream() {
+        final long seed = System.currentTimeMillis();
+        final Random r1 = new Random(seed);
+        final double[] a = new double[SIZE];
+        for (int i=0; i < SIZE; i++) {
+            a[i] = r1.nextDouble();
+        }
+
+        final Random r2 = new Random(seed); // same seed
+        final double[] b = r2.doubles().limit(SIZE).toArray();
+        assertEquals(a, b);
+    }
+
+    @Test
+    public void testGaussianStream() {
+        final long seed = System.currentTimeMillis();
+        final Random r1 = new Random(seed);
+        final double[] a = new double[SIZE];
+        for (int i=0; i < SIZE; i++) {
+            a[i] = r1.nextGaussian();
+        }
+
+        final Random r2 = new Random(seed); // same seed
+        final double[] b = r2.gaussians().limit(SIZE).toArray();
+        assertEquals(a, b);
+    }
+
+    @Test
+    public void testThreadLocalIntStream() throws InterruptedException {
+        final ExecutorService e = Executors.newFixedThreadPool(10);
+        final ThreadLocalRandom tlr = ThreadLocalRandom.current();
+
+        final class RandomTask implements Runnable {
+            int[] randoms;
+
+            @Override
+            public void run() {
+                randoms = tlr.ints().limit(SIZE).toArray();
+            }
+        }
+        final RandomTask[] tasks = new RandomTask[10];
+        for (int i=0; i < tasks.length; i++) {
+            tasks[i] = new RandomTask();
+        }
+        for (int i=0; i < tasks.length; i++) {
+            e.submit(tasks[i]);
+        }
+        e.shutdown();
+        e.awaitTermination(3, TimeUnit.SECONDS);
+        for (int i=1; i < tasks.length; i++) {
+            assertFalse(Arrays.equals(tasks[0].randoms, tasks[i].randoms));
+        }
+    }
+
+    @Test
+    public void testThreadLocalLongStream() throws InterruptedException {
+        final ExecutorService e = Executors.newFixedThreadPool(10);
+        final ThreadLocalRandom tlr = ThreadLocalRandom.current();
+
+        final class RandomTask implements Runnable {
+            long[] randoms;
+
+            @Override
+            public void run() {
+                randoms = tlr.longs().limit(SIZE).toArray();
+            }
+        }
+        final RandomTask[] tasks = new RandomTask[10];
+        for (int i=0; i < tasks.length; i++) {
+            tasks[i] = new RandomTask();
+        }
+        for (int i=0; i < tasks.length; i++) {
+            e.submit(tasks[i]);
+        }
+        e.shutdown();
+        e.awaitTermination(3, TimeUnit.SECONDS);
+        for (int i=1; i < tasks.length; i++) {
+            assertFalse(Arrays.equals(tasks[0].randoms, tasks[i].randoms));
+        }
+    }
+
+    @Test
+    public void testThreadLocalDoubleStream() throws InterruptedException {
+        final ExecutorService e = Executors.newFixedThreadPool(10);
+        final ThreadLocalRandom tlr = ThreadLocalRandom.current();
+
+        final class RandomTask implements Runnable {
+            double[] randoms;
+
+            @Override
+            public void run() {
+                randoms = tlr.doubles().limit(SIZE).toArray();
+            }
+        }
+        final RandomTask[] tasks = new RandomTask[10];
+        for (int i=0; i < tasks.length; i++) {
+            tasks[i] = new RandomTask();
+        }
+        for (int i=0; i < tasks.length; i++) {
+            e.submit(tasks[i]);
+        }
+        e.shutdown();
+        e.awaitTermination(3, TimeUnit.SECONDS);
+        for (int i=1; i < tasks.length; i++) {
+            assertFalse(Arrays.equals(tasks[0].randoms, tasks[i].randoms));
+        }
+    }
+
+    @Test
+    public void testThreadLocalGaussianStream() throws InterruptedException {
+        final ExecutorService e = Executors.newFixedThreadPool(10);
+        final ThreadLocalRandom tlr = ThreadLocalRandom.current();
+
+        final class RandomTask implements Runnable {
+            double[] randoms;
+
+            @Override
+            public void run() {
+                randoms = tlr.gaussians().limit(SIZE).toArray();
+            }
+        }
+        final RandomTask[] tasks = new RandomTask[10];
+        for (int i=0; i < tasks.length; i++) {
+            tasks[i] = new RandomTask();
+        }
+        for (int i=0; i < tasks.length; i++) {
+            e.submit(tasks[i]);
+        }
+        e.shutdown();
+        e.awaitTermination(3, TimeUnit.SECONDS);
+        for (int i=1; i < tasks.length; i++) {
+            assertFalse(Arrays.equals(tasks[0].randoms, tasks[i].randoms));
+        }
+    }
+
+}
diff --git a/jdk/test/java/util/concurrent/atomic/AtomicReferenceTest.java b/jdk/test/java/util/concurrent/atomic/AtomicReferenceTest.java
new file mode 100644
index 0000000..4a455d9
--- /dev/null
+++ b/jdk/test/java/util/concurrent/atomic/AtomicReferenceTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.UnaryOperator;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+/*
+ * @test
+ * @summary Test Map default methods
+ * @run testng AtomicReferenceTest
+ * @author Jim Gish <jim.gish@oracle.com>
+ */
+public class AtomicReferenceTest {
+
+    /**
+     * Test of updateAndGet method, of class AtomicReference.
+     */
+    @Test
+    public void testUpdateAndGet() {
+        AtomicReference<Integer> instance = new AtomicReference<>(3);
+        assertEquals((int) instance.get(), 3);
+        assertEquals((int) instance.updateAndGet(x -> x + 2), 5);
+        assertEquals((int) instance.get(), 5);
+    }
+
+    /**
+     * Test of getAndUpdate method, of class AtomicReference.
+     */
+    @Test
+    public void testGetAndUpdate() {
+        AtomicReference<Integer> instance = new AtomicReference<>(3);
+        assertEquals((int) instance.get(), 3);
+        assertEquals((int) instance.getAndUpdate(x -> x + 3), 3);
+        assertEquals((int) instance.get(), 6);
+    }
+}
diff --git a/jdk/test/java/util/logging/bundlesearch/IndirectlyLoadABundle.java b/jdk/test/java/util/logging/bundlesearch/IndirectlyLoadABundle.java
index 76dc123..e81edaa 100644
--- a/jdk/test/java/util/logging/bundlesearch/IndirectlyLoadABundle.java
+++ b/jdk/test/java/util/logging/bundlesearch/IndirectlyLoadABundle.java
@@ -23,41 +23,26 @@
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.nio.file.Paths;
+import java.util.logging.Logger;
 
 /**
  * This class is used to ensure that a resource bundle loadable by a classloader
- * is on the caller's stack, but not on the classpath or TCCL to ensure that
- * Logger.getLogger() can't load the bundle via a stack search
+ * is on the caller's stack, but not on the classpath or TCCL.  It tests that
+ * Logger.getLogger() can load the bundle via the immediate caller's classloader
  *
  * @author Jim Gish
  */
 public class IndirectlyLoadABundle {
 
-    private final static String rbName = "StackSearchableResource";
+    private final static String rbName = "CallerSearchableResource";
 
     public boolean loadAndTest() throws Throwable {
-        // Find out where we are running from so we can setup the URLClassLoader URLs
-        // test.src and test.classes will be set if running in jtreg, but probably
-        // not otherwise
-        String testDir = System.getProperty("test.src", System.getProperty("user.dir"));
-        String testClassesDir = System.getProperty("test.classes",
-                System.getProperty("user.dir"));
-        String sep = System.getProperty("file.separator");
-
-        URL[] urls = new URL[2];
-
-        // Allow for both jtreg and standalone cases here
-        urls[0] = Paths.get(testDir, "resources").toUri().toURL();
-        urls[1] = Paths.get(testClassesDir).toUri().toURL();
-
-        System.out.println("INFO: urls[0] = " + urls[0]);
-        System.out.println("INFO: urls[1] = " + urls[1]);
-
         // Make sure we can find it via the URLClassLoader
-        URLClassLoader yetAnotherResourceCL = new URLClassLoader(urls, null);
+        URLClassLoader yetAnotherResourceCL = new URLClassLoader(getURLs(), null);
         if (!testForValidResourceSetup(yetAnotherResourceCL)) {
             throw new Exception("Couldn't directly load bundle " + rbName
                     + " as expected. Test config problem");
@@ -70,23 +55,109 @@
                     + " able to. Test config problem");
         }
 
-        Class<?> loadItUpClazz = Class.forName("LoadItUp", true, yetAnotherResourceCL);
+        Class<?> loadItUpClazz = Class.forName("LoadItUp1", true,
+                                               yetAnotherResourceCL);
         ClassLoader actual = loadItUpClazz.getClassLoader();
         if (actual != yetAnotherResourceCL) {
-            throw new Exception("LoadItUp was loaded by an unexpected CL: " + actual);
+            throw new Exception("LoadItUp1 was loaded by an unexpected CL: " + actual);
         }
         Object loadItUp = loadItUpClazz.newInstance();
-        Method testMethod = loadItUpClazz.getMethod("test", String.class);
+        Method testMethod = loadItUpClazz.getMethod("getLogger", String.class, String.class);
         try {
-            return (Boolean) testMethod.invoke(loadItUp, rbName);
+            return (Logger)testMethod.invoke(loadItUp, "NestedLogger1", rbName) != null;
         } catch (InvocationTargetException ex) {
             throw ex.getTargetException();
         }
     }
 
+    public boolean testGetAnonymousLogger() throws Throwable {
+        // Test getAnonymousLogger()
+        URLClassLoader loadItUpCL = new URLClassLoader(getURLs(), null);
+        Class<?> loadItUpClazz = Class.forName("LoadItUp1", true, loadItUpCL);
+        ClassLoader actual = loadItUpClazz.getClassLoader();
+        if (actual != loadItUpCL) {
+            throw new Exception("LoadItUp1 was loaded by an unexpected CL: "
+                                 + actual);
+        }
+        Object loadItUpAnon = loadItUpClazz.newInstance();
+        Method testAnonMethod = loadItUpClazz.getMethod("getAnonymousLogger",
+                                                        String.class);
+        try {
+            return (Logger)testAnonMethod.invoke(loadItUpAnon, rbName) != null;
+        } catch (InvocationTargetException ex) {
+            throw ex.getTargetException();
+        }
+    }
+
+
+    public boolean testGetLoggerGetLoggerWithBundle() throws Throwable {
+        // test getLogger("NestedLogger2"); followed by
+        // getLogger("NestedLogger2", rbName) to see if the bundle is found
+        //
+        URL[] urls = getURLs();
+        if (getLoggerWithNewCL(urls, "NestedLogger2", null)) {
+            return getLoggerWithNewCL(urls, "NestedLogger2", rbName);
+
+        } else {
+            throw new Exception("TEST FAILED: first call to getLogger() failed "
+                                 + " in IndirectlyLoadABundle."
+                                 + "testGetLoggerGetLoggerWithBundle");
+        }
+    }
+
+    private URL[] getURLs() throws MalformedURLException {
+        // Find out where we are running from so we can setup the URLClassLoader URLs
+        // test.src and test.classes will be set if running in jtreg, but probably
+        // not otherwise
+        String testDir = System.getProperty("test.src", System.getProperty("user.dir"));
+        String testClassesDir = System.getProperty("test.classes",
+                                                   System.getProperty("user.dir"));
+        URL[] urls = new URL[2];
+        // Allow for both jtreg and standalone cases here
+        urls[0] = Paths.get(testDir, "resources").toUri().toURL();
+        urls[1] = Paths.get(testClassesDir).toUri().toURL();
+
+        return urls;
+    }
+
+    private boolean getLoggerWithNewCL(URL[] urls, String loggerName,
+                                         String bundleName) throws Throwable {
+        Logger result = null;;
+        // Test getLogger("foo"); getLogger("foo", "rbName");
+        // First do the getLogger() call with no bundle name
+        URLClassLoader getLoggerCL = new URLClassLoader(urls, null);
+        Class<?> loadItUpClazz1 = Class.forName("LoadItUp1", true, getLoggerCL);
+        ClassLoader actual = loadItUpClazz1.getClassLoader();
+        if (actual != getLoggerCL) {
+            throw new Exception("LoadItUp1 was loaded by an unexpected CL: "
+                                 + actual);
+        }
+        Object loadItUp1 = loadItUpClazz1.newInstance();
+        if (bundleName != null) {
+            Method getLoggerMethod = loadItUpClazz1.getMethod("getLogger",
+                                                              String.class,
+                                                              String.class);
+            try {
+                result = (Logger) getLoggerMethod.invoke(loadItUp1, loggerName,
+                                                         bundleName);
+            } catch (InvocationTargetException ex) {
+                throw ex.getTargetException();
+            }
+        } else {
+            Method getLoggerMethod = loadItUpClazz1.getMethod("getLogger",
+                                                              String.class);
+            try {
+                result = (Logger) getLoggerMethod.invoke(loadItUp1, loggerName);
+            } catch (InvocationTargetException ex) {
+                throw ex.getTargetException();
+            }
+        }
+        return result != null;
+    }
+
     private boolean testForValidResourceSetup(ClassLoader cl) {
-        // First make sure the test environment is setup properly and the bundle actually
-        // exists
+        // First make sure the test environment is setup properly and the bundle
+        // actually exists
         return ResourceBundleSearchTest.isOnClassPath(rbName, cl);
     }
 }
diff --git a/jdk/test/java/util/logging/bundlesearch/LoadItUp1.java b/jdk/test/java/util/logging/bundlesearch/LoadItUp1.java
new file mode 100644
index 0000000..26d64dc
--- /dev/null
+++ b/jdk/test/java/util/logging/bundlesearch/LoadItUp1.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.util.logging.Logger;
+
+/*
+ * This class is loaded onto the call stack when the getLogger methods are
+ * called and then the classes classloader can be used to find a bundle in
+ * the same directory as the class.  However, Logger is not allowed
+ * to find the bundle by looking up the stack for this classloader.
+ * We verify that this cannot happen.
+ *
+ * @author Jim Gish
+ */
+public class LoadItUp1 {
+    public Logger getAnonymousLogger(String rbName) throws Exception {
+        // we should not be able to find the resource in this directory via
+        // getLogger calls.  The only way that would be possible given this setup
+        // is that if Logger.getLogger searched up the call stack
+        return Logger.getAnonymousLogger(rbName);
+    }
+
+    public Logger getLogger(String loggerName) {
+        return Logger.getLogger(loggerName);
+    }
+
+    public Logger getLogger(String loggerName,String bundleName) {
+        return Logger.getLogger(loggerName, bundleName);
+    }
+}
diff --git a/jdk/test/java/util/logging/bundlesearch/LoadItUp.java b/jdk/test/java/util/logging/bundlesearch/LoadItUp2.java
similarity index 74%
rename from jdk/test/java/util/logging/bundlesearch/LoadItUp.java
rename to jdk/test/java/util/logging/bundlesearch/LoadItUp2.java
index d47b9a3..25cde2d 100644
--- a/jdk/test/java/util/logging/bundlesearch/LoadItUp.java
+++ b/jdk/test/java/util/logging/bundlesearch/LoadItUp2.java
@@ -24,15 +24,15 @@
 import java.util.logging.Logger;
 
 /*
- * This class is loaded onto the call stack when the test method is called
- * and then its classloader can be used to find a property bundle in the same
- * directory as the class.  However, Logger is not allowed
- * to find the bundle by looking up the stack for this classloader.
- * We verify that this cannot happen.
+ * This class is loaded onto the call stack by LoadItUp2Invoker from a separate
+ * classloader.  LoadItUp2Invoker was loaded by a class loader that does have
+ * access to the bundle, but the class loader used to load this class does not.
+ * Thus the logging code should not be able to see the resource bundle unless
+ * it has more than a single level stack crawl, which is not allowed.
  *
  * @author Jim Gish
  */
-public class LoadItUp {
+public class LoadItUp2 {
 
     private final static boolean DEBUG = false;
 
@@ -46,16 +46,16 @@
     private boolean lookupBundle(String rbName) {
         // See if Logger.getLogger can find the resource in this directory
         try {
-            Logger aLogger = Logger.getLogger("NestedLogger", rbName);
+            Logger aLogger = Logger.getLogger("NestedLogger2", rbName);
         } catch (MissingResourceException re) {
             if (DEBUG) {
                 System.out.println(
-                    "As expected, LoadItUp.lookupBundle() did not find the bundle "
+                    "As expected, LoadItUp2.lookupBundle() did not find the bundle "
                     + rbName);
             }
             return false;
         }
-        System.out.println("FAILED: LoadItUp.lookupBundle() found the bundle "
+        System.out.println("FAILED: LoadItUp2.lookupBundle() found the bundle "
                 + rbName + " using a stack search.");
         return true;
     }
diff --git a/jdk/test/java/util/logging/bundlesearch/LoadItUp2Invoker.java b/jdk/test/java/util/logging/bundlesearch/LoadItUp2Invoker.java
new file mode 100644
index 0000000..fe79506
--- /dev/null
+++ b/jdk/test/java/util/logging/bundlesearch/LoadItUp2Invoker.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+/**
+ * This class is loaded by a class loader that can see the resource. It creates
+ * a new classloader for LoadItUp2 which cannot see the resource.  So, 2 levels
+ * up the call chain we have a class/classloader that can see the resource, but
+ * 1 level up the class/classloader cannot.
+ *
+ * @author Jim Gish
+ */
+public class LoadItUp2Invoker {
+    private URLClassLoader cl;
+    private String rbName;
+    private Object loadItUp2;
+    private Method testMethod;
+
+    public void setup(URL[] urls, String rbName) throws
+                       ReflectiveOperationException {
+        this.cl = new URLClassLoader(urls, null);
+        this.rbName = rbName;
+        // Using this new classloader, load the actual test class
+        // which is now two levels removed from the original caller
+        Class<?> loadItUp2Clazz = Class.forName("LoadItUp2", true , cl);
+        this.loadItUp2 = loadItUp2Clazz.newInstance();
+        this.testMethod = loadItUp2Clazz.getMethod("test", String.class);
+    }
+
+    public Boolean test() throws Throwable {
+        try {
+            return (Boolean) testMethod.invoke(loadItUp2, rbName);
+        } catch (InvocationTargetException ex) {
+            throw ex.getTargetException();
+        }
+    }
+}
diff --git a/jdk/test/java/util/logging/bundlesearch/ResourceBundleSearchTest.java b/jdk/test/java/util/logging/bundlesearch/ResourceBundleSearchTest.java
index 00f1840..ee3de2d 100644
--- a/jdk/test/java/util/logging/bundlesearch/ResourceBundleSearchTest.java
+++ b/jdk/test/java/util/logging/bundlesearch/ResourceBundleSearchTest.java
@@ -23,11 +23,11 @@
 
 /*
  * @test
- * @bug     8002070
+ * @bug     8002070 8013382
  * @summary Remove the stack search for a resource bundle Logger to use
  * @author  Jim Gish
- * @build  ResourceBundleSearchTest IndirectlyLoadABundle LoadItUp
- * @run main ResourceBundleSearchTest
+ * @build  ResourceBundleSearchTest IndirectlyLoadABundle LoadItUp1 LoadItUp2 TwiceIndirectlyLoadABundle LoadItUp2Invoker
+ * @run main/othervm ResourceBundleSearchTest
  */
 import java.net.URL;
 import java.net.URLClassLoader;
@@ -39,6 +39,12 @@
 import java.util.ResourceBundle;
 import java.util.logging.Logger;
 
+/**
+ * This class tests various scenarios of loading resource bundles from
+ * java.util.logging.  Since jtreg uses the logging system, it is necessary to
+ * run these tests using othervm mode to ensure no interference from logging
+ * initialization by jtreg
+ */
 public class ResourceBundleSearchTest {
 
     private final static boolean DEBUG = false;
@@ -60,15 +66,11 @@
         // ensure we are using en as the default Locale so we can find the resource
         Locale.setDefault(Locale.ENGLISH);
 
-        String testClasses = System.getProperty("test.classes");
-        System.out.println( "test.classes = " + testClasses );
-
         ClassLoader myClassLoader = ClassLoader.getSystemClassLoader();
 
         // Find out where we are running from so we can setup the URLClassLoader URL
         String userDir = System.getProperty("user.dir");
         String testDir = System.getProperty("test.src", userDir);
-        String sep = System.getProperty("file.separator");
 
         URL[] urls = new URL[1];
 
@@ -77,30 +79,41 @@
 
         // Test 1 - can we find a Logger bundle from doing a stack search?
         // We shouldn't be able to
-        assertFalse(testGetBundleFromStackSearch(), "testGetBundleFromStackSearch");
+        assertFalse(testGetBundleFromStackSearch(), "1-testGetBundleFromStackSearch");
 
         // Test 2 - can we find a Logger bundle off of the Thread context class
         // loader? We should be able to.
-        assertTrue(
-                testGetBundleFromTCCL(TCCL_TEST_BUNDLE, rbClassLoader),
-                "testGetBundleFromTCCL");
+        assertTrue(testGetBundleFromTCCL(TCCL_TEST_BUNDLE, rbClassLoader),
+                   "2-testGetBundleFromTCCL");
 
         // Test 3 - Can we find a Logger bundle from the classpath?  We should be
-        // able to, but ....
-        // We check to see if the bundle is on the classpath or not so that this
-        // will work standalone.  In the case of jtreg/samevm,
-        // the resource bundles are not on the classpath.  Running standalone
-        // (or othervm), they are
+        // able to.  We'll first check to make sure the setup is correct and
+        // it actually is on the classpath before checking whether logging
+        // can see it there.
         if (isOnClassPath(PROP_RB_NAME, myClassLoader)) {
             debug("We should be able to see " + PROP_RB_NAME + " on the classpath");
             assertTrue(testGetBundleFromSystemClassLoader(PROP_RB_NAME),
-                    "testGetBundleFromSystemClassLoader");
+                       "3-testGetBundleFromSystemClassLoader");
         } else {
-            debug("We should not be able to see " + PROP_RB_NAME + " on the classpath");
-            assertFalse(testGetBundleFromSystemClassLoader(PROP_RB_NAME),
-                    "testGetBundleFromSystemClassLoader");
+            throw new Exception("TEST SETUP FAILURE: Cannot see " + PROP_RB_NAME
+                                 + " on the classpath");
         }
 
+        // Test 4 - we should be able to find a bundle from the caller's
+        // classloader, but only one level up.
+        assertTrue(testGetBundleFromCallersClassLoader(),
+                   "4-testGetBundleFromCallersClassLoader");
+
+        // Test 5 - this ensures that getAnonymousLogger(String rbName)
+        // can find the bundle from the caller's classloader
+        assertTrue(testGetAnonymousLogger(), "5-testGetAnonymousLogger");
+
+        // Test 6 - first call getLogger("myLogger").
+        // Then call getLogger("myLogger","bundleName") from a different ClassLoader
+        // Make sure we find the bundle
+        assertTrue(testGetBundleFromSecondCallersClassLoader(),
+                   "6-testGetBundleFromSecondCallersClassLoader");
+
         report();
     }
 
@@ -112,7 +125,7 @@
                 System.out.println(msg);
             }
             throw new Exception(numFail + " out of " + (numPass + numFail)
-                    + " tests failed.");
+                                 + " tests failed.");
         }
     }
 
@@ -122,7 +135,7 @@
         } else {
             numFail++;
             System.out.println("FAILED: " + testName
-                    + " was supposed to return true but did NOT!");
+                               + " was supposed to return true but did NOT!");
         }
     }
 
@@ -132,13 +145,20 @@
         } else {
             numFail++;
             System.out.println("FAILED: " + testName
-                    + " was supposed to return false but did NOT!");
+                               + " was supposed to return false but did NOT!");
         }
     }
 
     public boolean testGetBundleFromStackSearch() throws Throwable {
         // This should fail.  This was the old functionality to search up the
         // caller's call stack
+        TwiceIndirectlyLoadABundle indirectLoader = new TwiceIndirectlyLoadABundle();
+        return indirectLoader.loadAndTest();
+    }
+
+    public boolean testGetBundleFromCallersClassLoader() throws Throwable {
+        // This should pass.  This exercises getting the bundle using the
+        // class loader of the caller (one level up)
         IndirectlyLoadABundle indirectLoader = new IndirectlyLoadABundle();
         return indirectLoader.loadAndTest();
     }
@@ -193,14 +213,29 @@
                     bundleName);
         } catch (MissingResourceException re) {
             msgs.add("INFO: testGetBundleFromSystemClassLoader() did not find bundle "
-                    + bundleName);
+                     + bundleName);
             return false;
         }
         msgs.add("INFO: testGetBundleFromSystemClassLoader() found the bundle "
-                + bundleName);
+                 + bundleName);
         return true;
     }
 
+    private boolean testGetAnonymousLogger() throws Throwable {
+        // This should pass.  This exercises getting the bundle using the
+        // class loader of the caller (one level up) when calling
+        // Logger.getAnonymousLogger(String rbName)
+        IndirectlyLoadABundle indirectLoader = new IndirectlyLoadABundle();
+        return indirectLoader.testGetAnonymousLogger();
+    }
+
+    private boolean testGetBundleFromSecondCallersClassLoader() throws Throwable {
+        // This should pass.  This exercises getting the bundle using the
+        // class loader of the caller (one level up)
+        IndirectlyLoadABundle indirectLoader = new IndirectlyLoadABundle();
+        return indirectLoader.testGetLoggerGetLoggerWithBundle();
+    }
+
     public static class LoggingThread extends Thread {
 
         boolean foundBundle = false;
@@ -227,13 +262,13 @@
                 // this should succeed if the bundle is on the system classpath.
                 try {
                     Logger aLogger = Logger.getLogger(ResourceBundleSearchTest.newLoggerName(),
-                            bundleName);
-                    msg = "INFO: LoggingRunnable() found the bundle " + bundleName
-                            + (setTCCL ? " with " : " without ") + "setting the TCCL";
+                                                      bundleName);
+                    msg = "INFO: LoggingThread.run() found the bundle " + bundleName
+                          + (setTCCL ? " with " : " without ") + "setting the TCCL";
                     foundBundle = true;
                 } catch (MissingResourceException re) {
-                    msg = "INFO: LoggingRunnable() did not find the bundle " + bundleName
-                            + (setTCCL ? " with " : " without ") + "setting the TCCL";
+                    msg = "INFO: LoggingThread.run() did not find the bundle " + bundleName
+                          + (setTCCL ? " with " : " without ") + "setting the TCCL";
                     foundBundle = false;
                 }
             } catch (Throwable e) {
diff --git a/jdk/test/java/util/logging/bundlesearch/TwiceIndirectlyLoadABundle.java b/jdk/test/java/util/logging/bundlesearch/TwiceIndirectlyLoadABundle.java
new file mode 100644
index 0000000..e3dbc55
--- /dev/null
+++ b/jdk/test/java/util/logging/bundlesearch/TwiceIndirectlyLoadABundle.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Paths;
+
+/**
+ * This class constructs a scenario where a bundle is accessible on the call
+ * stack two levels up from the call to getLogger(), but not on the immediate
+ * caller.  This tests that getLogger() isn't doing a stack crawl more than one
+ * level up to find a bundle.
+ *
+ * @author Jim Gish
+ */
+public class TwiceIndirectlyLoadABundle {
+
+    private final static String rbName = "StackSearchableResource";
+
+    public boolean loadAndTest() throws Throwable {
+        // Find out where we are running from so we can setup the URLClassLoader URLs
+        // test.src and test.classes will be set if running in jtreg, but probably
+        // not otherwise
+        String testDir = System.getProperty("test.src", System.getProperty("user.dir"));
+        String testClassesDir = System.getProperty("test.classes",
+                                                   System.getProperty("user.dir"));
+        URL[] urls = new URL[2];
+
+        // Allow for both jtreg and standalone cases here
+        // Unlike the 1-level test where we can get the bundle from the caller's
+        // class loader, for this one we don't want to expose the resource directory
+        // to the next class.  That way we're invoking the LoadItUp2Invoker class
+        // from this class that does have access to the resources (two levels
+        // up the call stack), but the Invoker itself won't have access to resource
+        urls[0] = Paths.get(testDir,"resources").toUri().toURL();
+        urls[1] = Paths.get(testClassesDir).toUri().toURL();
+
+        // Make sure we can find it via the URLClassLoader
+        URLClassLoader yetAnotherResourceCL = new URLClassLoader(urls, null);
+        Class<?> loadItUp2InvokerClazz = Class.forName("LoadItUp2Invoker", true,
+                                                       yetAnotherResourceCL);
+        ClassLoader actual = loadItUp2InvokerClazz.getClassLoader();
+        if (actual != yetAnotherResourceCL) {
+            throw new Exception("LoadItUp2Invoker was loaded by an unexpected CL: "
+                                 + actual);
+        }
+        Object loadItUp2Invoker = loadItUp2InvokerClazz.newInstance();
+
+        Method setupMethod = loadItUp2InvokerClazz.getMethod("setup",
+                urls.getClass(), String.class);
+        try {
+            // For the next class loader we create, we want to leave off
+            // the resources.  That way loadItUp2Invoker will have access to
+            // them, but the next class won't.
+            URL[] noResourceUrl = new URL[1];
+            noResourceUrl[0] = urls[1];  // from above -- just the test classes
+            setupMethod.invoke(loadItUp2Invoker, noResourceUrl, rbName);
+        } catch (InvocationTargetException ex) {
+            throw ex.getTargetException();
+        }
+
+        Method testMethod = loadItUp2InvokerClazz.getMethod("test");
+        try {
+            return (Boolean) testMethod.invoke(loadItUp2Invoker);
+        } catch (InvocationTargetException ex) {
+            throw ex.getTargetException();
+        }
+    }
+}
diff --git a/jdk/make/sun/org/Makefile b/jdk/test/java/util/logging/bundlesearch/resources/CallerSearchableResource_en.properties
similarity index 63%
rename from jdk/make/sun/org/Makefile
rename to jdk/test/java/util/logging/bundlesearch/resources/CallerSearchableResource_en.properties
index a992cde..17ba443 100644
--- a/jdk/make/sun/org/Makefile
+++ b/jdk/test/java/util/logging/bundlesearch/resources/CallerSearchableResource_en.properties
@@ -1,39 +1,25 @@
-#
-# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+# 
+# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
+# 
 # This code is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
+# published by the Free Software Foundation.
+# 
 # This code is distributed in the hope that it will be useful, but WITHOUT
 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 # version 2 for more details (a copy is included in the LICENSE file that
 # accompanied this code).
-#
+# 
 # You should have received a copy of the GNU General Public License version
 # 2 along with this work; if not, write to the Free Software Foundation,
 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
+# 
 # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 # or visit www.oracle.com if you need additional information or have any
 # questions.
 #
-
-#
-# Makefile for building Mozilla modules
-#
-
-BUILDDIR = ../..
-PRODUCT = org
-include $(BUILDDIR)/common/Defs.gmk
-
-SUBDIRS =  mozilla
-include $(BUILDDIR)/common/Subdirs.gmk
-
-all build clean clobber::
-	$(SUBDIRS-loop)
-
+sample1=translation #4 for sample1
+sample2=translation #4 for sample2
+supports-test=ResourceBundleSearchTest
diff --git a/jdk/test/java/util/regex/POSIX_Unicode.java b/jdk/test/java/util/regex/POSIX_Unicode.java
index da691fe..817e445 100644
--- a/jdk/test/java/util/regex/POSIX_Unicode.java
+++ b/jdk/test/java/util/regex/POSIX_Unicode.java
@@ -125,6 +125,10 @@
         return (ch & 0xfffe) == 0xfffe || (ch >= 0xfdd0 && ch <= 0xfdef);
     }
 
+    public static boolean isJoinControl(int ch) {
+        return (ch == 0x200C || ch == 0x200D);
+    }
+
     //  \p{alpha}
     //  \p{gc=Mark}
     //  \p{digit}
@@ -136,6 +140,7 @@
                   (1 << Character.COMBINING_SPACING_MARK) |
                   (1 << Character.CONNECTOR_PUNCTUATION)) >> Character.getType(ch)) & 1)
                != 0 ||
-               isDigit(ch);
+               isDigit(ch) ||
+               isJoinControl(ch);
     }
 }
diff --git a/jdk/test/java/util/regex/RegExTest.java b/jdk/test/java/util/regex/RegExTest.java
index bc345ed..f0563d9 100644
--- a/jdk/test/java/util/regex/RegExTest.java
+++ b/jdk/test/java/util/regex/RegExTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -33,7 +33,7 @@
  * 5013885 5003322 4988891 5098443 5110268 6173522 4829857 5027748 6376940
  * 6358731 6178785 6284152 6231989 6497148 6486934 6233084 6504326 6635133
  * 6350801 6676425 6878475 6919132 6931676 6948903 6990617 7014645 7039066
- * 7067045 7014640 7189363 8007395
+ * 7067045 7014640 7189363 8007395 8013252 8013254 8012646
  */
 
 import java.util.regex.*;
@@ -41,6 +41,7 @@
 import java.io.*;
 import java.util.*;
 import java.nio.CharBuffer;
+import java.util.function.Predicate;
 
 /**
  * This is a test class created to check the operation of
@@ -145,6 +146,7 @@
         linebreakTest();
         branchTest();
         groupCurlyNotFoundSuppTest();
+        patternAsPredicate();
         if (failure) {
             throw new
                 RuntimeException("RegExTest failed, 1st failure: " +
@@ -3390,7 +3392,9 @@
     private static void check(Pattern p, String s, String g, String expected) {
         Matcher m = p.matcher(s);
         m.find();
-        if (!m.group(g).equals(expected))
+        if (!m.group(g).equals(expected) ||
+            s.charAt(m.start(g)) != expected.charAt(0) ||
+            s.charAt(m.end(g) - 1) != expected.charAt(expected.length() - 1))
             failCount++;
     }
 
@@ -3420,19 +3424,42 @@
         failCount++;
     }
 
-    private static void checkExpectedFail(Matcher m, String g) {
+    private static void checkExpectedIAE(Matcher m, String g) {
         m.find();
         try {
             m.group(g);
-        } catch (IllegalArgumentException iae) {
+        } catch (IllegalArgumentException x) {
             //iae.printStackTrace();
-            return;
-        } catch (NullPointerException npe) {
-            return;
+            try {
+                m.start(g);
+            } catch (IllegalArgumentException xx) {
+                try {
+                    m.start(g);
+                } catch (IllegalArgumentException xxx) {
+                    return;
+                }
+            }
         }
         failCount++;
     }
 
+    private static void checkExpectedNPE(Matcher m) {
+        m.find();
+        try {
+            m.group(null);
+        } catch (NullPointerException x) {
+            try {
+                m.start(null);
+            } catch (NullPointerException xx) {
+                try {
+                    m.end(null);
+                } catch (NullPointerException xxx) {
+                    return;
+                }
+            }
+        }
+        failCount++;
+    }
 
     private static void namedGroupCaptureTest() throws Exception {
         check(Pattern.compile("x+(?<gname>y+)z+"),
@@ -3559,10 +3586,9 @@
         checkExpectedFail("(?<6groupnamestartswithdigit>abc)(def)");
         checkExpectedFail("(?<gname>abc)(def)\\k<gnameX>");
         checkExpectedFail("(?<gname>abc)(?<gname>def)\\k<gnameX>");
-        checkExpectedFail(Pattern.compile("(?<gname>abc)(def)").matcher("abcdef"),
-                          "gnameX");
-        checkExpectedFail(Pattern.compile("(?<gname>abc)(def)").matcher("abcdef"),
-                          null);
+        checkExpectedIAE(Pattern.compile("(?<gname>abc)(def)").matcher("abcdef"),
+                         "gnameX");
+        checkExpectedNPE(Pattern.compile("(?<gname>abc)(def)").matcher("abcdef"));
         report("NamedGroupCapture");
     }
 
@@ -3759,6 +3785,7 @@
         Matcher spaceP  = Pattern.compile("\\p{IsWhiteSpace}").matcher("");
         Matcher definedP = Pattern.compile("\\p{IsAssigned}").matcher("");
         Matcher nonCCPP = Pattern.compile("\\p{IsNoncharacterCodePoint}").matcher("");
+        Matcher joinCrtl = Pattern.compile("\\p{IsJoinControl}").matcher("");
 
         // javaMethod
         Matcher lowerJ  = Pattern.compile("\\p{javaLowerCase}").matcher("");
@@ -3829,7 +3856,8 @@
                 Character.isIdeographic(cp) != ideogP.reset(str).matches() ||
                 Character.isIdeographic(cp) != ideogJ.reset(str).matches() ||
                 (Character.UNASSIGNED == type) == definedP.reset(str).matches() ||
-                POSIX_Unicode.isNoncharacterCodePoint(cp) != nonCCPP.reset(str).matches())
+                POSIX_Unicode.isNoncharacterCodePoint(cp) != nonCCPP.reset(str).matches() ||
+                POSIX_Unicode.isJoinControl(cp) != joinCrtl.reset(str).matches())
                 failCount++;
         }
 
@@ -3971,4 +3999,19 @@
         report("GroupCurly NotFoundSupp");
     }
 
+    // This test is for 8012646
+    private static void patternAsPredicate() throws Exception {
+        Predicate<String> p = Pattern.compile("[a-z]+").asPredicate();
+
+        if (p.test("")) {
+            failCount++;
+        }
+        if (!p.test("word")) {
+            failCount++;
+        }
+        if (p.test("1234")) {
+            failCount++;
+        }
+        report("Pattern.asPredicate");
+    }
 }
diff --git a/jdk/test/java/util/stream/bootlib/TEST.properties b/jdk/test/java/util/stream/bootlib/TEST.properties
new file mode 100644
index 0000000..a50c2e8
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/TEST.properties
@@ -0,0 +1,3 @@
+# This file identifies root(s) of the test-ng hierarchy.
+
+bootclasspath.dirs = .
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/CollectorOps.java b/jdk/test/java/util/stream/bootlib/java/util/stream/CollectorOps.java
new file mode 100644
index 0000000..c849415
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/CollectorOps.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import org.testng.Assert;
+
+import java.util.Spliterator;
+import java.util.function.IntFunction;
+
+/** Test helper class for java.util.stream test framework */
+public final class CollectorOps {
+    private CollectorOps() { }
+
+    public static <E_IN> StatefulTestOp<E_IN> collector() {
+        return new StatefulCollector<>(0, StreamShape.REFERENCE);
+    }
+
+    /* Utility classes for collecting output of intermediate pipeline stages */
+    public static class StatefulCollector<E_IN> implements StatefulTestOp<E_IN> {
+        private final int opFlags;
+        private final StreamShape inputShape;
+
+        public StatefulCollector(int opFlags, StreamShape inputShape) {
+            this.opFlags = opFlags;
+            this.inputShape = inputShape;
+        }
+
+        @Override
+        public StreamShape inputShape() {
+            return inputShape;
+        }
+
+        @Override
+        public StreamShape outputShape() {
+            return inputShape;
+        }
+
+        @Override
+        public int opGetFlags() {
+            return opFlags;
+        }
+
+        @Override
+        public Sink<E_IN> opWrapSink(int flags, boolean parallel, Sink<E_IN> sink) {
+            return sink;
+        }
+
+        @Override
+        public <P_IN> Node<E_IN> opEvaluateParallel(PipelineHelper<E_IN> helper,
+                                                    Spliterator<P_IN> spliterator,
+                                                    IntFunction<E_IN[]> generator) {
+            return helper.evaluate(spliterator, false, generator);
+        }
+    }
+
+    public static class TestParallelSizedOp<T> extends StatefulCollector<T> {
+        public TestParallelSizedOp() {
+            this(StreamShape.REFERENCE);
+        }
+
+        protected TestParallelSizedOp(StreamShape shape) {
+            super(0, shape);
+        }
+
+        @Override
+        public <P_IN> Node<T> opEvaluateParallel(PipelineHelper<T> helper,
+                                                 Spliterator<P_IN> spliterator,
+                                                 IntFunction<T[]> generator) {
+            int flags = helper.getStreamAndOpFlags();
+
+            Assert.assertTrue(StreamOpFlag.SIZED.isKnown(flags));
+            return super.opEvaluateParallel(helper, spliterator, generator);
+        }
+
+        public static class OfInt extends TestParallelSizedOp<Integer> {
+            public OfInt() {
+                super(StreamShape.INT_VALUE);
+            }
+        }
+
+        public static class OfLong extends TestParallelSizedOp<Long> {
+            public OfLong() {
+                super(StreamShape.LONG_VALUE);
+            }
+        }
+
+        public static class OfDouble extends TestParallelSizedOp<Double> {
+            public OfDouble() {
+                super(StreamShape.DOUBLE_VALUE);
+            }
+        }
+    }
+}
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/DoubleStreamTestDataProvider.java b/jdk/test/java/util/stream/bootlib/java/util/stream/DoubleStreamTestDataProvider.java
new file mode 100644
index 0000000..da10875
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/DoubleStreamTestDataProvider.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import org.testng.annotations.DataProvider;
+
+import java.util.*;
+import java.util.Spliterators;
+import java.util.function.Supplier;
+
+/** TestNG DataProvider for double-valued streams */
+public class DoubleStreamTestDataProvider {
+    private static final double[] to0 = new double[0];
+    private static final double[] to1 = new double[1];
+    private static final double[] to10 = new double[10];
+    private static final double[] to100 = new double[100];
+    private static final double[] to1000 = new double[1000];
+    private static final double[] reversed = new double[100];
+    private static final double[] ones = new double[100];
+    private static final double[] twice = new double[200];
+    private static final double[] pseudoRandom;
+
+    private static final Object[][] testData;
+    private static final Object[][] spliteratorTestData;
+
+    static {
+        double[][] arrays = {to0, to1, to10, to100, to1000};
+        for (double[] arr : arrays) {
+            for (int i = 0; i < arr.length; i++) {
+                arr[i] = i;
+            }
+        }
+        for (int i = 0; i < reversed.length; i++) {
+            reversed[i] = reversed.length - i;
+        }
+        for (int i = 0; i < ones.length; i++) {
+            ones[i] = 1;
+        }
+        System.arraycopy(to100, 0, twice, 0, to100.length);
+        System.arraycopy(to100, 0, twice, to100.length, to100.length);
+        pseudoRandom = new double[LambdaTestHelpers.LONG_STRING.length()];
+        for (int i = 0; i < LambdaTestHelpers.LONG_STRING.length(); i++) {
+            pseudoRandom[i] = (double) LambdaTestHelpers.LONG_STRING.charAt(i);
+        }
+    }
+
+    static final Object[][] arrays = {
+            {"empty", to0},
+            {"0..1", to1},
+            {"0..10", to10},
+            {"0..100", to100},
+            {"0..1000", to1000},
+            {"100x[1]", ones},
+            {"2x[0..100]", twice},
+            {"reverse 0..100", reversed},
+            {"pseudorandom", pseudoRandom}
+    };
+
+    static {
+        {
+            List<Object[]> list = new ArrayList<>();
+            for (Object[] data : arrays) {
+                final Object name = data[0];
+                final double[] doubles = (double[]) data[1];
+
+                list.add(new Object[]{"array:" + name,
+                        TestData.Factory.ofArray("array:" + name, doubles)});
+
+                SpinedBuffer.OfDouble isl = new SpinedBuffer.OfDouble();
+                for (double i : doubles) {
+                    isl.accept(i);
+                }
+                list.add(new Object[]{"SpinedList:" + name,
+                        TestData.Factory.ofSpinedBuffer("SpinedList:" + name, isl)});
+
+                list.add(streamDataDescr("Primitives.range(0,l): " + doubles.length,
+                                         () -> DoubleStream.range(0, doubles.length)));
+                list.add(streamDataDescr("Primitives.range(0,l,2): " + doubles.length,
+                                         () -> DoubleStream.range(0, doubles.length, 2)));
+                list.add(streamDataDescr("Primitives.range(0,l,3): " + doubles.length,
+                                         () -> DoubleStream.range(0, doubles.length, 3)));
+                list.add(streamDataDescr("Primitives.range(0,l,7): " + doubles.length,
+                                         () -> DoubleStream.range(0, doubles.length, 7)));
+            }
+            testData = list.toArray(new Object[0][]);
+        }
+
+        {
+            List<Object[]> spliterators = new ArrayList<>();
+            for (Object[] data : arrays) {
+                final Object name = data[0];
+                final double[] doubles = (double[]) data[1];
+
+                SpinedBuffer.OfDouble isl = new SpinedBuffer.OfDouble();
+                for (double i : doubles) {
+                    isl.accept(i);
+                }
+
+                spliterators.add(splitDescr("Arrays.s(array):" + name,
+                                            () -> Arrays.spliterator(doubles)));
+                spliterators.add(splitDescr("Arrays.s(array,o,l):" + name,
+                                            () -> Arrays.spliterator(doubles, 0, doubles.length / 2)));
+
+                spliterators.add(splitDescr("SpinedBuffer.s():" + name,
+                                            () -> isl.spliterator()));
+
+                spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator(), size):" + name,
+                                            () -> Spliterators.spliterator(isl.iterator(), doubles.length, 0)));
+                spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator()):" + name,
+                                            () -> Spliterators.spliteratorUnknownSize(isl.iterator(), 0)));
+
+                spliterators.add(splitDescr("Primitives.range(0,l):" + name,
+                                            () -> DoubleStream.range(0, doubles.length).spliterator()));
+                spliterators.add(splitDescr("Primitives.range(0,l,2):" + name,
+                                            () -> DoubleStream.range(0, doubles.length, 2).spliterator()));
+                spliterators.add(splitDescr("Primitives.range(0,l,3):" + name,
+                                            () -> DoubleStream.range(0, doubles.length, 3).spliterator()));
+                spliterators.add(splitDescr("Primitives.range(0,l,7):" + name,
+                                            () -> DoubleStream.range(0, doubles.length, 7).spliterator()));
+                // Need more!
+            }
+            spliteratorTestData = spliterators.toArray(new Object[0][]);
+        }
+
+    }
+
+    static <T> Object[] streamDataDescr(String description, Supplier<DoubleStream> s) {
+        return new Object[] { description, TestData.Factory.ofDoubleSupplier(description, s) };
+    }
+
+    static <T> Object[] splitDescr(String description, Supplier<Spliterator.OfDouble> s) {
+        return new Object[] { description, s };
+    }
+
+    // Return an array of ( String name, DoubleStreamTestData )
+    @DataProvider(name = "DoubleStreamTestData")
+    public static Object[][] makeDoubleStreamTestData() {
+        return testData;
+    }
+
+    // returns an array of (String name, Supplier<PrimitiveSpliterator<Double>>)
+    @DataProvider(name = "DoubleSpliterator")
+    public static Object[][] spliteratorProvider() {
+        return spliteratorTestData;
+    }
+}
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/DoubleStreamTestScenario.java b/jdk/test/java/util/stream/bootlib/java/util/stream/DoubleStreamTestScenario.java
new file mode 100644
index 0000000..5e431b1
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/DoubleStreamTestScenario.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import java.util.PrimitiveIterator;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.function.DoubleConsumer;
+import java.util.function.Function;
+
+/**
+ * Test scenarios for double streams.
+ *
+ * Each scenario is provided with a data source, a function that maps a fresh
+ * stream (as provided by the data source) to a new stream, and a sink to
+ * receive results.  Each scenario describes a different way of computing the
+ * stream contents.  The test driver will ensure that all scenarios produce
+ * the same output (modulo allowable differences in ordering).
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public enum DoubleStreamTestScenario implements OpTestCase.BaseStreamTestScenario {
+
+    STREAM_FOR_EACH(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            DoubleStream s = m.apply(data.stream());
+            if (s.isParallel()) {
+                s = s.sequential();
+            }
+            s.forEach(b);
+        }
+    },
+
+    STREAM_TO_ARRAY(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            for (double t : m.apply(data.stream()).toArray()) {
+                b.accept(t);
+            }
+        }
+    },
+
+    STREAM_ITERATOR(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            for (PrimitiveIterator.OfDouble seqIter = m.apply(data.stream()).iterator(); seqIter.hasNext(); )
+                b.accept(seqIter.nextDouble());
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate in pull mode
+    STREAM_SPLITERATOR(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            for (Spliterator.OfDouble spl = m.apply(data.stream()).spliterator(); spl.tryAdvance(b); ) {
+            }
+        }
+    },
+
+    // Wrap as stream, spliterate, then split a few times mixing advances with forEach
+    STREAM_SPLITERATOR_WITH_MIXED_TRAVERSE_AND_SPLIT(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            SpliteratorTestHelper.mixedTraverseAndSplit(b, m.apply(data.stream()).spliterator());
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate in pull mode
+    STREAM_SPLITERATOR_FOREACH(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            m.apply(data.stream()).spliterator().forEachRemaining(b);
+        }
+    },
+
+    PAR_STREAM_SEQUENTIAL_FOR_EACH(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            m.apply(data.parallelStream()).sequential().forEach(b);
+        }
+    },
+
+    // Wrap as parallel stream + forEachOrdered
+    PAR_STREAM_FOR_EACH_ORDERED(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            // @@@ Want to explicitly select ordered equalator
+            m.apply(data.parallelStream()).forEachOrdered(b);
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate sequentially
+    PAR_STREAM_SPLITERATOR(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            for (Spliterator.OfDouble spl = m.apply(data.parallelStream()).spliterator(); spl.tryAdvance(b); ) {
+            }
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate sequentially
+    PAR_STREAM_SPLITERATOR_FOREACH(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            m.apply(data.parallelStream()).spliterator().forEachRemaining(b);
+        }
+    },
+
+    PAR_STREAM_TO_ARRAY(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            for (double t : m.apply(data.parallelStream()).toArray())
+                b.accept(t);
+        }
+    },
+
+    // Wrap as parallel stream, get the spliterator, wrap as a stream + toArray
+    PAR_STREAM_SPLITERATOR_STREAM_TO_ARRAY(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            DoubleStream s = m.apply(data.parallelStream());
+            Spliterator.OfDouble sp = s.spliterator();
+            DoubleStream ss = StreamSupport.doubleParallelStream(() -> sp,
+                                                                 StreamOpFlag.toCharacteristics(OpTestCase.getStreamFlags(s))
+                                                                 | (sp.getExactSizeIfKnown() < 0 ? 0 : Spliterator.SIZED));
+            for (double t : ss.toArray())
+                b.accept(t);
+        }
+    },
+
+    PAR_STREAM_TO_ARRAY_CLEAR_SIZED(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            S_IN pipe1 = (S_IN) OpTestCase.chain(data.parallelStream(),
+                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
+            DoubleStream pipe2 = m.apply(pipe1);
+
+            for (double t : pipe2.toArray())
+                b.accept(t);
+        }
+    },;
+
+    private boolean isParallel;
+
+    DoubleStreamTestScenario(boolean isParallel) {
+        this.isParallel = isParallel;
+    }
+
+    public StreamShape getShape() {
+        return StreamShape.DOUBLE_VALUE;
+    }
+
+    public boolean isParallel() {
+        return isParallel;
+    }
+
+    public <T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
+    void run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, S_OUT> m) {
+        _run(data, (DoubleConsumer) b, (Function<S_IN, DoubleStream>) m);
+    }
+
+    abstract <T, S_IN extends BaseStream<T, S_IN>>
+    void _run(TestData<T, S_IN> data, DoubleConsumer b, Function<S_IN, DoubleStream> m);
+
+}
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/FlagDeclaringOp.java b/jdk/test/java/util/stream/bootlib/java/util/stream/FlagDeclaringOp.java
new file mode 100644
index 0000000..a9882c8
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/FlagDeclaringOp.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+/**
+ * An operation that injects or clears flags but otherwise performs no operation on elements.
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class FlagDeclaringOp<T> implements StatelessTestOp<T, T> {
+    private final int flags;
+    private final StreamShape shape;
+
+    public FlagDeclaringOp(int flags) {
+        this(flags, StreamShape.REFERENCE);
+    }
+
+    public FlagDeclaringOp(int flags, StreamShape shape) {
+        this.flags = flags;
+        this.shape = shape;
+    }
+
+    @Override
+    public StreamShape outputShape() {
+        return shape;
+    }
+
+    @Override
+    public StreamShape inputShape() {
+        return shape;
+    }
+
+    @Override
+    public int opGetFlags() {
+        return flags;
+    }
+
+    @Override
+    public Sink<T> opWrapSink(int flags, boolean parallel, Sink sink) {
+        return sink;
+    }
+}
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestDataProvider.java b/jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestDataProvider.java
new file mode 100644
index 0000000..3ef2acf
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestDataProvider.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import org.testng.annotations.DataProvider;
+
+import java.util.*;
+import java.util.Spliterators;
+import java.util.function.Supplier;
+
+/** TestNG DataProvider for int-valued streams */
+public class IntStreamTestDataProvider {
+    private static final int[] to0 = new int[0];
+    private static final int[] to1 = new int[1];
+    private static final int[] to10 = new int[10];
+    private static final int[] to100 = new int[100];
+    private static final int[] to1000 = new int[1000];
+    private static final int[] reversed = new int[100];
+    private static final int[] ones = new int[100];
+    private static final int[] twice = new int[200];
+    private static final int[] pseudoRandom;
+
+    private static final Object[][] testData;
+    private static final Object[][] spliteratorTestData;
+
+    static {
+        int[][] arrays = {to0, to1, to10, to100, to1000};
+        for (int[] arr : arrays) {
+            for (int i = 0; i < arr.length; i++) {
+                arr[i] = i;
+            }
+        }
+        for (int i = 0; i < reversed.length; i++) {
+            reversed[i] = reversed.length - i;
+        }
+        for (int i = 0; i < ones.length; i++) {
+            ones[i] = 1;
+        }
+        System.arraycopy(to100, 0, twice, 0, to100.length);
+        System.arraycopy(to100, 0, twice, to100.length, to100.length);
+        pseudoRandom = new int[LambdaTestHelpers.LONG_STRING.length()];
+        for (int i = 0; i < LambdaTestHelpers.LONG_STRING.length(); i++) {
+            pseudoRandom[i] = (int) LambdaTestHelpers.LONG_STRING.charAt(i);
+        }
+    }
+
+    static final Object[][] arrays = {
+            {"empty", to0},
+            {"0..1", to1},
+            {"0..10", to10},
+            {"0..100", to100},
+            {"0..1000", to1000},
+            {"100x[1]", ones},
+            {"2x[0..100]", twice},
+            {"reverse 0..100", reversed},
+            {"pseudorandom", pseudoRandom}
+    };
+
+    static {
+        {
+            List<Object[]> list = new ArrayList<>();
+            for (Object[] data : arrays) {
+                final Object name = data[0];
+                final int[] ints = (int[]) data[1];
+
+                list.add(new Object[]{"array:" +
+                                      name, TestData.Factory.ofArray("array:" + name, ints)});
+
+                SpinedBuffer.OfInt isl = new SpinedBuffer.OfInt();
+                for (int i : ints) {
+                    isl.accept(i);
+                }
+                list.add(new Object[]{"SpinedList:" + name,
+                         TestData.Factory.ofSpinedBuffer("SpinedList:" + name, isl)});
+
+                list.add(streamDataDescr("IntStream.intRange(0,l): " + ints.length,
+                                         () -> IntStream.range(0, ints.length)));
+                list.add(streamDataDescr("IntStream.intRange(0,l,2): " + ints.length,
+                                         () -> IntStream.range(0, ints.length, 2)));
+                list.add(streamDataDescr("IntStream.intRange(0,l,3): " + ints.length,
+                                         () -> IntStream.range(0, ints.length, 3)));
+                list.add(streamDataDescr("IntStream.intRange(0,l,7): " + ints.length,
+                                         () -> IntStream.range(0, ints.length, 7)));
+            }
+            testData = list.toArray(new Object[0][]);
+        }
+
+        {
+            List<Object[]> spliterators = new ArrayList<>();
+            for (Object[] data : arrays) {
+                final Object name = data[0];
+                final int[] ints = (int[]) data[1];
+
+                SpinedBuffer.OfInt isl = new SpinedBuffer.OfInt();
+                for (int i : ints) {
+                    isl.accept(i);
+                }
+
+                spliterators.add(splitDescr("Arrays.s(array):" + name,
+                                            () -> Arrays.spliterator(ints)));
+                spliterators.add(splitDescr("Arrays.s(array,o,l):" + name,
+                                            () -> Arrays.spliterator(ints, 0, ints.length / 2)));
+
+                spliterators.add(splitDescr("SpinedBuffer.s():" + name,
+                                            () -> isl.spliterator()));
+
+                spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator(), size):" + name,
+                                            () -> Spliterators.spliterator(isl.iterator(), ints.length, 0)));
+                spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator()):" + name,
+                                            () -> Spliterators.spliteratorUnknownSize(isl.iterator(), 0)));
+
+                spliterators.add(splitDescr("IntStream.intRange(0,l):" + name,
+                                            () -> IntStream.range(0, ints.length).spliterator()));
+                spliterators.add(splitDescr("IntStream.intRange(0,l,2):" + name,
+                                            () -> IntStream.range(0, ints.length, 2).spliterator()));
+                spliterators.add(splitDescr("IntStream.intRange(0,l,3):" + name,
+                                            () -> IntStream.range(0, ints.length, 3).spliterator()));
+                spliterators.add(splitDescr("IntStream.intRange(0,l,7):" + name,
+                                            () -> IntStream.range(0, ints.length, 7).spliterator()));
+
+                // Need more!
+            }
+            spliteratorTestData = spliterators.toArray(new Object[0][]);
+        }
+
+    }
+
+    static <T> Object[] streamDataDescr(String description, Supplier<IntStream> s) {
+        return new Object[] { description, TestData.Factory.ofIntSupplier(description, s) };
+    }
+
+    static <T> Object[] splitDescr(String description, Supplier<Spliterator.OfInt> s) {
+        return new Object[] { description, s };
+    }
+
+    // Return an array of ( String name, IntStreamTestData )
+    @DataProvider(name = "IntStreamTestData")
+    public static Object[][] makeIntStreamTestData() {
+        return testData;
+    }
+
+    // returns an array of (String name, Supplier<PrimitiveSpliterator<Integer>>)
+    @DataProvider(name = "IntSpliterator")
+    public static Object[][] spliteratorProvider() {
+        return spliteratorTestData;
+    }
+}
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestScenario.java b/jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestScenario.java
new file mode 100644
index 0000000..c12a4ec
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestScenario.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import java.util.PrimitiveIterator;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.IntConsumer;
+
+/**
+ * Test scenarios for int streams.
+ *
+ * Each scenario is provided with a data source, a function that maps a fresh
+ * stream (as provided by the data source) to a new stream, and a sink to
+ * receive results.  Each scenario describes a different way of computing the
+ * stream contents.  The test driver will ensure that all scenarios produce
+ * the same output (modulo allowable differences in ordering).
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public enum IntStreamTestScenario implements OpTestCase.BaseStreamTestScenario {
+
+    STREAM_FOR_EACH(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, IntConsumer b, Function<S_IN, IntStream> m) {
+            IntStream s = m.apply(data.stream());
+            if (s.isParallel()) {
+                s = s.sequential();
+            }
+            s.forEach(b);
+        }
+    },
+
+    STREAM_TO_ARRAY(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, IntConsumer b, Function<S_IN, IntStream> m) {
+            for (int t : m.apply(data.stream()).toArray()) {
+                b.accept(t);
+            }
+        }
+    },
+
+    STREAM_ITERATOR(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, IntConsumer b, Function<S_IN, IntStream> m) {
+            for (PrimitiveIterator.OfInt seqIter = m.apply(data.stream()).iterator(); seqIter.hasNext(); )
+                b.accept(seqIter.nextInt());
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate in pull mode
+    STREAM_SPLITERATOR(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, IntConsumer b, Function<S_IN, IntStream> m) {
+            for (Spliterator.OfInt spl = m.apply(data.stream()).spliterator(); spl.tryAdvance(b); ) {
+            }
+        }
+    },
+
+    // Wrap as stream, spliterate, then split a few times mixing advances with forEach
+    STREAM_SPLITERATOR_WITH_MIXED_TRAVERSE_AND_SPLIT(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, IntConsumer b, Function<S_IN, IntStream> m) {
+            SpliteratorTestHelper.mixedTraverseAndSplit(b, m.apply(data.stream()).spliterator());
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate in pull mode
+    STREAM_SPLITERATOR_FOREACH(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, IntConsumer b, Function<S_IN, IntStream> m) {
+            m.apply(data.stream()).spliterator().forEachRemaining(b);
+        }
+    },
+
+    PAR_STREAM_SEQUENTIAL_FOR_EACH(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, IntConsumer b, Function<S_IN, IntStream> m) {
+            m.apply(data.parallelStream()).sequential().forEach(b);
+        }
+    },
+
+    // Wrap as parallel stream + forEachOrdered
+    PAR_STREAM_FOR_EACH_ORDERED(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, IntConsumer b, Function<S_IN, IntStream> m) {
+            // @@@ Want to explicitly select ordered equalator
+            m.apply(data.parallelStream()).forEachOrdered(b);
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate sequentially
+    PAR_STREAM_SPLITERATOR(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, IntConsumer b, Function<S_IN, IntStream> m) {
+            for (Spliterator.OfInt spl = m.apply(data.parallelStream()).spliterator(); spl.tryAdvance(b); ) {
+            }
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate sequentially
+    PAR_STREAM_SPLITERATOR_FOREACH(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, IntConsumer b, Function<S_IN, IntStream> m) {
+            m.apply(data.parallelStream()).spliterator().forEachRemaining(b);
+        }
+    },
+
+    PAR_STREAM_TO_ARRAY(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, IntConsumer b, Function<S_IN, IntStream> m) {
+            for (int t : m.apply(data.parallelStream()).toArray())
+                b.accept(t);
+        }
+    },
+
+    // Wrap as parallel stream, get the spliterator, wrap as a stream + toArray
+    PAR_STREAM_SPLITERATOR_STREAM_TO_ARRAY(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, IntConsumer b, Function<S_IN, IntStream> m) {
+            IntStream s = m.apply(data.parallelStream());
+            Spliterator.OfInt sp = s.spliterator();
+            IntStream ss = StreamSupport.intParallelStream(() -> sp,
+                                                           StreamOpFlag.toCharacteristics(OpTestCase.getStreamFlags(s))
+                                                           | (sp.getExactSizeIfKnown() < 0 ? 0 : Spliterator.SIZED));
+            for (int t : ss.toArray())
+                b.accept(t);
+        }
+    },
+
+    PAR_STREAM_TO_ARRAY_CLEAR_SIZED(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, IntConsumer b, Function<S_IN, IntStream> m) {
+            S_IN pipe1 = (S_IN) OpTestCase.chain(data.parallelStream(),
+                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
+            IntStream pipe2 = m.apply(pipe1);
+
+            for (int t : pipe2.toArray())
+                b.accept(t);
+        }
+    },;
+
+    private boolean isParallel;
+
+    IntStreamTestScenario(boolean isParallel) {
+        this.isParallel = isParallel;
+    }
+
+    public StreamShape getShape() {
+        return StreamShape.INT_VALUE;
+    }
+
+    public boolean isParallel() {
+        return isParallel;
+    }
+
+    public <T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
+    void run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, S_OUT> m) {
+        _run(data, (IntConsumer) b, (Function<S_IN, IntStream>) m);
+    }
+
+    abstract <T, S_IN extends BaseStream<T, S_IN>>
+    void _run(TestData<T, S_IN> data, IntConsumer b, Function<S_IN, IntStream> m);
+
+}
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/IntermediateTestOp.java b/jdk/test/java/util/stream/bootlib/java/util/stream/IntermediateTestOp.java
new file mode 100644
index 0000000..1ed04c7
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/IntermediateTestOp.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+/**
+ * A base type for test operations
+ */
+interface IntermediateTestOp<E_IN, E_OUT> {
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public static<T> AbstractPipeline chain(AbstractPipeline upstream,
+                                            IntermediateTestOp<?, T> op) {
+        if (op instanceof StatelessTestOp)
+            return StatelessTestOp.chain(upstream, (StatelessTestOp) op);
+
+        if (op instanceof StatefulTestOp)
+            return StatefulTestOp.chain(upstream, (StatefulTestOp) op);
+
+        throw new IllegalStateException("Unknown test op type: " + op.getClass().getName());
+    }
+}
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/LambdaTestHelpers.java b/jdk/test/java/util/stream/bootlib/java/util/stream/LambdaTestHelpers.java
new file mode 100644
index 0000000..f1d8ffe
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/LambdaTestHelpers.java
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import java.util.*;
+import java.util.function.BiConsumer;
+import java.util.function.BiPredicate;
+import java.util.function.BinaryOperator;
+import java.util.function.Consumer;
+import java.util.function.DoubleBinaryOperator;
+import java.util.function.DoubleConsumer;
+import java.util.function.DoublePredicate;
+import java.util.function.Function;
+import java.util.function.IntBinaryOperator;
+import java.util.function.IntConsumer;
+import java.util.function.IntFunction;
+import java.util.function.IntPredicate;
+import java.util.function.IntUnaryOperator;
+import java.util.function.LongBinaryOperator;
+import java.util.function.LongConsumer;
+import java.util.function.LongPredicate;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * LambdaTestHelpers -- assertion methods and useful objects for lambda test cases
+ */
+public class LambdaTestHelpers {
+    public static final String LONG_STRING = "When in the Course of human events it becomes necessary for one people to dissolve the political bands which have connected them with another and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Nature's God entitle them, a decent respect to the opinions of mankind requires that they should declare the causes which impel them to the separation.";
+
+    @SuppressWarnings("rawtypes")
+    public static final Consumer bEmpty = x -> {  };
+    @SuppressWarnings("rawtypes")
+    public static final IntConsumer bIntEmpty = x -> {  };
+    @SuppressWarnings("rawtypes")
+    public static final BiConsumer bBiEmpty = (x,y) -> { };
+    @SuppressWarnings("rawtypes")
+    public static final Consumer bHashCode = x -> { Objects.hashCode(x); };
+    @SuppressWarnings("rawtypes")
+    public static final BiConsumer bBiHashCode = (x,y) -> { Objects.hash(x, y); };
+    public static final Function<Integer, Integer> mZero = x -> 0;
+    public static final Function<Integer, Integer> mId = x -> x;
+    public static final Function<Integer, Integer> mDoubler = x -> x * 2;
+    public static final Function<Integer, Stream<Integer>> mfId = e -> Collections.singletonList(e).stream();
+    public static final Function<Integer, Stream<Integer>> mfNull = e -> Collections.<Integer>emptyList().stream();
+    public static final Function<Integer, Stream<Integer>> mfLt = e -> {
+        List<Integer> l = new ArrayList<>();
+        for (int i=0; i<e; i++)
+            l.add(i);
+        return l.stream();
+    };
+    public static final ToIntFunction<Integer> imDoubler = x -> x * 2;
+    public static final ToLongFunction<Long> lmDoubler = x -> x * 2;
+    public static final ToDoubleFunction<Double> dmDoubler = x -> x * 2;
+    public static final Predicate<Integer> pFalse = x -> false;
+    public static final Predicate<Integer> pTrue = x -> true;
+    public static final Predicate<Integer> pEven = x -> 0 == x % 2;
+    public static final Predicate<Integer> pOdd = x -> 1 == x % 2;
+    public static final IntPredicate ipFalse = x -> false;
+    public static final IntPredicate ipTrue = x -> true;
+    public static final IntPredicate ipEven = x -> 0 == x % 2;
+    public static final IntPredicate ipOdd = x -> 1 == x % 2;
+    public static final LongPredicate lpFalse = x -> false;
+    public static final LongPredicate lpTrue = x -> true;
+    public static final LongPredicate lpEven = x -> 0 == x % 2;
+    public static final LongPredicate lpOdd = x -> 1 == x % 2;
+    public static final DoublePredicate dpFalse = x -> false;
+    public static final DoublePredicate dpTrue = x -> true;
+    public static final DoublePredicate dpEven = x -> 0 == ((long) x) % 2;
+    public static final DoublePredicate dpOdd = x -> 1 == ((long) x) % 2;
+    public static final BinaryOperator<Integer> rPlus = (x, y) -> x+y;
+    public static final BinaryOperator<Integer> rMax = (x, y) -> Math.max(x, y);
+    public static final BinaryOperator<Integer> rMin = (x, y) -> Math.min(x,y);
+    public static final IntBinaryOperator irPlus = (x, y) -> x+y;
+    public static final IntBinaryOperator irMax = (x, y) -> Math.max(x, y);
+    public static final IntBinaryOperator irMin = (x, y) -> Math.min(x,y);
+    public static final IntUnaryOperator irDoubler = x -> x * 2;
+    public static final LongBinaryOperator lrPlus = (x, y) -> x+y;
+    public static final DoubleBinaryOperator drPlus = (x, y) -> x+y;
+    public static final Comparator<Integer> cInteger = (a, b) -> Integer.compare(a, b);
+    public static final BiPredicate<?, ?> bipFalse = (x, y) -> false;
+    public static final BiPredicate<?, ?> bipTrue = (x, y) -> true;
+    public static final BiPredicate<Integer, Integer> bipBothEven = (x, y) -> 0 == (x % 2 + y % 2);
+    public static final BiPredicate<Integer, Integer> bipBothOdd = (x, y) -> 2 == (x % 2 + y % 2);
+    public static final BiPredicate<?, ?> bipSameString = (x, y) -> String.valueOf(x).equals(String.valueOf(y));
+
+    public static final IntFunction<Integer[]> integerArrayGenerator = s -> new Integer[s];
+
+    public static final IntFunction<Object[]> objectArrayGenerator = s -> new Object[s];
+
+    public static final Function<String, Stream<Character>> flattenChars = string -> {
+        List<Character> l = new ArrayList<>();
+        for (int i=0; i<string.length(); i++)
+            l.add(string.charAt(i));
+        return l.stream();
+    };
+
+    public static final Function<String, IntStream> flattenInt
+            = string -> IntStream.range(0, string.length()).map(string::charAt);
+
+    public static <T, R> Function<T, R> forPredicate(Predicate<? super T> predicate, R forTrue, R forFalse) {
+        Objects.requireNonNull(predicate);
+
+        return t -> predicate.test(t) ? forTrue : forFalse;
+    }
+
+    public static <T> Function<T, T> identity() {
+        return t -> t;
+    }
+
+    public static<V, T, R> Function<V, R> compose(Function<? super T, ? extends R> after, Function<? super V, ? extends T> before) {
+        Objects.requireNonNull(before);
+        return (V v) -> after.apply(before.apply(v));
+    }
+
+    public static List<Integer> empty() {
+        ArrayList<Integer> list = new ArrayList<>();
+        list.add(null);
+        return list;
+    }
+
+    public static List<Integer> countTo(int n) {
+        return range(1, n);
+    }
+
+    public static List<Integer> range(int l, int u) {
+        ArrayList<Integer> list = new ArrayList<>(u - l + 1);
+        for (int i=l; i<=u; i++) {
+            list.add(i);
+        }
+        return list;
+    }
+
+    public static List<Integer> repeat(int value, int n) {
+        ArrayList<Integer> list = new ArrayList<>(n);
+        for (int i=1; i<=n; i++) {
+            list.add(value);
+        }
+        return list;
+    }
+
+    public static List<Double> asDoubles(List<Integer> integers) {
+        ArrayList<Double> list = new ArrayList<>();
+        for (Integer i : integers) {
+            list.add((double) i);
+        }
+        return list;
+    }
+
+    public static List<Long> asLongs(List<Integer> integers) {
+        ArrayList<Long> list = new ArrayList<>();
+        for (Integer i : integers) {
+            list.add((long) i);
+        }
+        return list;
+    }
+
+    public static void assertCountSum(Stream<? super Integer> it, int count, int sum) {
+        assertCountSum(it.iterator(), count, sum);
+    }
+
+    public static void assertCountSum(Iterable<? super Integer> it, int count, int sum) {
+        assertCountSum(it.iterator(), count, sum);
+    }
+
+    public static void assertCountSum(Iterator<? super Integer> it, int count, int sum) {
+        int c = 0;
+        int s = 0;
+        while (it.hasNext()) {
+            int i = (Integer) it.next();
+            c++;
+            s += i;
+        }
+
+        assertEquals(c, count);
+        assertEquals(s, sum);
+    }
+
+    public static void assertConcat(Iterator<Character> it, String result) {
+        StringBuilder sb = new StringBuilder();
+        while (it.hasNext()) {
+            sb.append(it.next());
+        }
+
+        assertEquals(result, sb.toString());
+    }
+
+    public static<T extends Comparable<? super T>> void assertSorted(Iterator<T> i) {
+        i = toBoxedList(i).iterator();
+
+        if (!i.hasNext())
+            return;
+        T last = i.next();
+        while (i.hasNext()) {
+            T t = i.next();
+            assertTrue(last.compareTo(t) <= 0);
+            assertTrue(t.compareTo(last) >= 0);
+            last = t;
+        }
+    }
+
+    public static<T> void assertSorted(Iterator<T> i, Comparator<? super T> comp) {
+        if (i instanceof PrimitiveIterator.OfInt
+                || i instanceof PrimitiveIterator.OfDouble
+                || i instanceof PrimitiveIterator.OfLong) {
+            i = toBoxedList(i).iterator();
+        }
+
+        if (!i.hasNext())
+            return;
+        T last = i.next();
+        while (i.hasNext()) {
+            T t = i.next();
+            assertTrue(comp.compare(last, t) <= 0);
+            assertTrue(comp.compare(t, last) >= 0);
+            last = t;
+        }
+    }
+
+    public static<T extends Comparable<? super T>> void assertSorted(Iterable<T> iter) {
+        assertSorted(iter.iterator());
+    }
+
+    public static<T> void assertSorted(Iterable<T> iter, Comparator<? super T> comp) {
+        assertSorted(iter.iterator(), comp);
+    }
+
+    public static <T> void assertUnique(Iterable<T> iter) {
+        assertUnique(iter.iterator());
+    }
+
+    public static<T> void assertUnique(Iterator<T> iter) {
+        if (!iter.hasNext()) {
+            return;
+        }
+
+        if (iter instanceof PrimitiveIterator.OfInt
+            || iter instanceof PrimitiveIterator.OfDouble
+            || iter instanceof PrimitiveIterator.OfLong) {
+            iter = toBoxedList(iter).iterator();
+        }
+
+        Set<T> uniq = new HashSet<>();
+        while(iter.hasNext()) {
+            T each = iter.next();
+            assertTrue(!uniq.contains(each));
+            uniq.add(each);
+        }
+    }
+
+    public static<T> void assertContents(Iterable<T> actual, Iterable<T> expected) {
+        if (actual instanceof Collection && expected instanceof Collection) {
+            assertEquals(actual, expected);
+        } else {
+            assertContents(actual.iterator(), expected.iterator());
+        }
+    }
+
+    public static<T> void assertContents(Iterator<T> actual, Iterator<T> expected) {
+        assertEquals(toBoxedList(actual), toBoxedList(expected));
+    }
+
+    @SafeVarargs
+    @SuppressWarnings("varargs")
+    public static<T> void assertContents(Iterator<T> actual, T... expected) {
+        assertContents(actual, Arrays.asList(expected).iterator());
+    }
+
+    /**
+     * The all consuming consumer (rampant capitalist) that can accepting a reference or any primitive value.
+     */
+    private static interface OmnivorousConsumer<T>
+            extends Consumer<T>, IntConsumer, LongConsumer, DoubleConsumer { }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public static<T> Consumer<T> toBoxingConsumer(Consumer<? super T> c) {
+        return (Consumer<T>) new OmnivorousConsumer() {
+            @Override
+            public void accept(Object t) {
+                c.accept((T) t);
+            }
+
+            @Override
+            public void accept(int t) {
+                accept((Object) t);
+            }
+
+            @Override
+            public void accept(long t) {
+                accept((Object) t);
+            }
+
+            @Override
+            public void accept(double t) {
+                accept((Object) t);
+            }
+        };
+    }
+
+    /**
+     * Convert an iterator to a list using forEach with an implementation of
+     * {@link java.util.stream.LambdaTestHelpers.OmnivorousConsumer}.
+     *
+     * This ensures equality comparisons for test results do not trip
+     * the boxing trip-wires.
+     */
+    private static<T> List<T> toBoxedList(Iterator<T> it) {
+        List<T> l = new ArrayList<>();
+        it.forEachRemaining(toBoxingConsumer(l::add));
+        return l;
+    }
+
+    /**
+     * Convert a spliterator to a list using forEach with an implementation of
+     * {@link java.util.stream.LambdaTestHelpers.OmnivorousConsumer}.
+     *
+     * This ensures equality comparisons for test results do not trip
+     * the boxing trip-wires.
+     */
+    public static<T> List<T> toBoxedList(Spliterator<T> sp) {
+        List<T> l = new ArrayList<>();
+        sp.forEachRemaining(toBoxingConsumer(l::add));
+        return l;
+    }
+
+    /**
+     * Convert an iterator to a multi-set, represented as a Map, using forEach with an implementation of
+     * {@link java.util.stream.LambdaTestHelpers.OmnivorousConsumer}.
+     *
+     * This ensures equality comparisons for test results do not trip
+     * the boxing trip-wires.
+     */
+    @SuppressWarnings("unchecked")
+    private static<T> Map<T, Integer> toBoxedMultiset(Iterator<T> it) {
+        Map<Object, Integer> result = new HashMap<>();
+
+        it.forEachRemaining(new OmnivorousConsumer<T>() {
+            @Override
+            public void accept(T t) {
+                add(t);
+            }
+
+            @Override
+            public void accept(int value) {
+                add(value);
+            }
+
+            @Override
+            public void accept(long value) {
+                add(value);
+            }
+
+            @Override
+            public void accept(double value) {
+                add(value);
+            }
+
+            void add(Object o) {
+                if (result.containsKey(o))
+                    result.put(o, result.get(o) + 1);
+                else
+                    result.put(o, 1);
+            }
+
+        });
+
+        return (Map<T, Integer>) result;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static void assertContentsEqual(Object a, Object b) {
+        if (a instanceof Iterable && b instanceof Iterable)
+            assertContents((Iterable) a, (Iterable) b);
+        else
+            assertEquals(a, b);
+    }
+
+    public static<T> void assertContentsUnordered(Iterable<T> actual, Iterable<T> expected) {
+        assertContentsUnordered(actual.iterator(), expected.iterator());
+    }
+
+    public static<T> void assertContentsUnordered(Iterator<T> actual, Iterator<T> expected) {
+        assertEquals(toBoxedMultiset(actual), toBoxedMultiset(expected));
+    }
+
+    public static void launderAssertion(Runnable r, Supplier<String> additionalInfo) {
+        try {
+            r.run();
+        }
+        catch (AssertionError ae) {
+            AssertionError cloned = new AssertionError(ae.getMessage() + String.format("%n%s", additionalInfo.get()));
+            cloned.setStackTrace(ae.getStackTrace());
+            if (ae.getCause() != null)
+                cloned.initCause(ae.getCause());
+            throw cloned;
+        }
+    }
+
+    public static <T, S extends BaseStream<T, S>>
+    List<Function<S, S>> permuteStreamFunctions(List<Function<S, S>> opFunctions) {
+        List<List<Function<S, S>>> opFunctionPermutations = perm(opFunctions);
+
+        List<Function<S, S>> appliedFunctions = new ArrayList<>();
+        for (List<Function<S, S>> fs : opFunctionPermutations) {
+            Function<S, S> applied = s -> {
+                for (Function<S, S> f : fs) {
+                    s = f.apply(s);
+                }
+                return s;
+            };
+            appliedFunctions.add(applied);
+        }
+
+        return appliedFunctions;
+    }
+
+    private static <T> List<T> sub(List<T> l, int index) {
+        List<T> subL = new ArrayList<>(l);
+        subL.remove(index);
+        return subL;
+    }
+
+    public static <T> List<List<T>> perm(List<T> l) {
+        List<List<T>> result = new ArrayList<>();
+        for (int i = 0; i < l.size(); i++) {
+            for (List<T> perm : perm(sub(l, i))) {
+                perm.add(0, l.get(i));
+                result.add(perm);
+            }
+        }
+        result.add(new ArrayList<T>());
+
+        return result;
+    }
+
+    public static String flagsToString(int flags) {
+        StringJoiner sj = new StringJoiner(", ", "StreamOpFlag[", "]");
+        if (StreamOpFlag.DISTINCT.isKnown(flags)) sj.add("IS_DISTINCT");
+        if (StreamOpFlag.ORDERED.isKnown(flags)) sj.add("IS_ORDERED");
+        if (StreamOpFlag.SIZED.isKnown(flags)) sj.add("IS_SIZED");
+        if (StreamOpFlag.SORTED.isKnown(flags)) sj.add("IS_SORTED");
+        if (StreamOpFlag.SHORT_CIRCUIT.isKnown(flags)) sj.add("IS_SHORT_CIRCUIT");
+        return sj.toString();
+    }
+}
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/LongStreamTestDataProvider.java b/jdk/test/java/util/stream/bootlib/java/util/stream/LongStreamTestDataProvider.java
new file mode 100644
index 0000000..f37a110
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/LongStreamTestDataProvider.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import org.testng.annotations.DataProvider;
+
+import java.util.*;
+import java.util.Spliterators;
+import java.util.function.Supplier;
+
+/** TestNG DataProvider for long-valued streams */
+public class LongStreamTestDataProvider {
+    private static final long[] to0 = new long[0];
+    private static final long[] to1 = new long[1];
+    private static final long[] to10 = new long[10];
+    private static final long[] to100 = new long[100];
+    private static final long[] to1000 = new long[1000];
+    private static final long[] reversed = new long[100];
+    private static final long[] ones = new long[100];
+    private static final long[] twice = new long[200];
+    private static final long[] pseudoRandom;
+
+    private static final Object[][] testData;
+    private static final Object[][] spliteratorTestData;
+
+    static {
+        long[][] arrays = {to0, to1, to10, to100, to1000};
+        for (long[] arr : arrays) {
+            for (int i = 0; i < arr.length; i++) {
+                arr[i] = i;
+            }
+        }
+        for (int i = 0; i < reversed.length; i++) {
+            reversed[i] = reversed.length - i;
+        }
+        for (int i = 0; i < ones.length; i++) {
+            ones[i] = 1;
+        }
+        System.arraycopy(to100, 0, twice, 0, to100.length);
+        System.arraycopy(to100, 0, twice, to100.length, to100.length);
+        pseudoRandom = new long[LambdaTestHelpers.LONG_STRING.length()];
+        for (int i = 0; i < LambdaTestHelpers.LONG_STRING.length(); i++) {
+            pseudoRandom[i] = (long) LambdaTestHelpers.LONG_STRING.charAt(i);
+        }
+    }
+
+    static final Object[][] arrays = {
+            {"empty", to0},
+            {"0..1", to1},
+            {"0..10", to10},
+            {"0..100", to100},
+            {"0..1000", to1000},
+            {"100x[1]", ones},
+            {"2x[0..100]", twice},
+            {"reverse 0..100", reversed},
+            {"pseudorandom", pseudoRandom}
+    };
+
+    static {
+        {
+            List<Object[]> list = new ArrayList<>();
+            for (Object[] data : arrays) {
+                final Object name = data[0];
+                final long[] longs = (long[]) data[1];
+
+                list.add(new Object[]{"array:" + name,
+                        TestData.Factory.ofArray("array:" + name, longs)});
+
+                SpinedBuffer.OfLong isl = new SpinedBuffer.OfLong();
+                for (long i : longs) {
+                    isl.accept(i);
+                }
+                list.add(new Object[]{"SpinedList:" + name,
+                        TestData.Factory.ofSpinedBuffer("SpinedList:" + name, isl)});
+
+                list.add(streamDataDescr("LongStream.longRange(0,l): " + longs.length,
+                                         () -> LongStream.range(0, longs.length)));
+                list.add(streamDataDescr("LongStream.longRange(0,l,2): " + longs.length,
+                                         () -> LongStream.range(0, longs.length, 2)));
+                list.add(streamDataDescr("LongStream.longRange(0,l,3): " + longs.length,
+                                         () -> LongStream.range(0, longs.length, 3)));
+                list.add(streamDataDescr("LongStream.longRange(0,l,7): " + longs.length,
+                                         () -> LongStream.range(0, longs.length, 7)));
+            }
+            testData = list.toArray(new Object[0][]);
+        }
+
+        {
+            List<Object[]> spliterators = new ArrayList<>();
+            for (Object[] data : arrays) {
+                final Object name = data[0];
+                final long[] longs = (long[]) data[1];
+
+                SpinedBuffer.OfLong isl = new SpinedBuffer.OfLong();
+                for (long i : longs) {
+                    isl.accept(i);
+                }
+
+                spliterators.add(splitDescr("Arrays.s(array):" + name,
+                                            () -> Arrays.spliterator(longs)));
+                spliterators.add(splitDescr("Arrays.s(array,o,l):" + name,
+                                            () -> Arrays.spliterator(longs, 0, longs.length / 2)));
+
+                spliterators.add(splitDescr("SpinedBuffer.s():" + name,
+                                            () -> isl.spliterator()));
+
+                spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator(), size):" + name,
+                                            () -> Spliterators.spliterator(isl.iterator(), longs.length, 0)));
+                spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator()):" + name,
+                                            () -> Spliterators.spliteratorUnknownSize(isl.iterator(), 0)));
+
+                spliterators.add(splitDescr("LongStream.longRange(0,l):" + name,
+                                            () -> LongStream.range(0, longs.length).spliterator()));
+                spliterators.add(splitDescr("LongStream.longRange(0,l,2):" + name,
+                                            () -> LongStream.range(0, longs.length, 2).spliterator()));
+                spliterators.add(splitDescr("LongStream.longRange(0,l,3):" + name,
+                                            () -> LongStream.range(0, longs.length, 3).spliterator()));
+                spliterators.add(splitDescr("LongStream.longRange(0,l,7):" + name,
+                                            () -> LongStream.range(0, longs.length, 7).spliterator()));
+                // Need more!
+            }
+            spliteratorTestData = spliterators.toArray(new Object[0][]);
+        }
+
+    }
+
+    static <T> Object[] streamDataDescr(String description, Supplier<LongStream> s) {
+        return new Object[] { description, TestData.Factory.ofLongSupplier(description, s) };
+    }
+
+    static <T> Object[] splitDescr(String description, Supplier<Spliterator.OfLong> s) {
+        return new Object[] { description, s };
+    }
+
+    // Return an array of ( String name, LongStreamTestData )
+    @DataProvider(name = "LongStreamTestData")
+    public static Object[][] makeLongStreamTestData() {
+        return testData;
+    }
+
+    // returns an array of (String name, Supplier<PrimitiveSpliterator<Long>>)
+    @DataProvider(name = "LongSpliterator")
+    public static Object[][] spliteratorProvider() {
+        return spliteratorTestData;
+    }
+}
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/LongStreamTestScenario.java b/jdk/test/java/util/stream/bootlib/java/util/stream/LongStreamTestScenario.java
new file mode 100644
index 0000000..c32d6e8
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/LongStreamTestScenario.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import java.util.PrimitiveIterator;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.LongConsumer;
+
+/**
+ * Test scenarios for long streams.
+ *
+ * Each scenario is provided with a data source, a function that maps a fresh
+ * stream (as provided by the data source) to a new stream, and a sink to
+ * receive results.  Each scenario describes a different way of computing the
+ * stream contents.  The test driver will ensure that all scenarios produce
+ * the same output (modulo allowable differences in ordering).
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public enum LongStreamTestScenario implements OpTestCase.BaseStreamTestScenario {
+
+    STREAM_FOR_EACH(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, LongConsumer b, Function<S_IN, LongStream> m) {
+            LongStream s = m.apply(data.stream());
+            if (s.isParallel()) {
+                s = s.sequential();
+            }
+            s.forEach(b);
+        }
+    },
+
+    STREAM_TO_ARRAY(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, LongConsumer b, Function<S_IN, LongStream> m) {
+            for (long t : m.apply(data.stream()).toArray()) {
+                b.accept(t);
+            }
+        }
+    },
+
+    STREAM_ITERATOR(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, LongConsumer b, Function<S_IN, LongStream> m) {
+            for (PrimitiveIterator.OfLong seqIter = m.apply(data.stream()).iterator(); seqIter.hasNext(); )
+                b.accept(seqIter.nextLong());
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate in pull mode
+    STREAM_SPLITERATOR(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, LongConsumer b, Function<S_IN, LongStream> m) {
+            for (Spliterator.OfLong spl = m.apply(data.stream()).spliterator(); spl.tryAdvance(b); ) {
+            }
+        }
+    },
+
+    // Wrap as stream, spliterate, then split a few times mixing advances with forEach
+    STREAM_SPLITERATOR_WITH_MIXED_TRAVERSE_AND_SPLIT(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, LongConsumer b, Function<S_IN, LongStream> m) {
+            SpliteratorTestHelper.mixedTraverseAndSplit(b, m.apply(data.stream()).spliterator());
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate in pull mode
+    STREAM_SPLITERATOR_FOREACH(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, LongConsumer b, Function<S_IN, LongStream> m) {
+            m.apply(data.stream()).spliterator().forEachRemaining(b);
+        }
+    },
+
+    PAR_STREAM_SEQUENTIAL_FOR_EACH(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, LongConsumer b, Function<S_IN, LongStream> m) {
+            m.apply(data.parallelStream()).sequential().forEach(b);
+        }
+    },
+
+    // Wrap as parallel stream + forEachOrdered
+    PAR_STREAM_FOR_EACH_ORDERED(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, LongConsumer b, Function<S_IN, LongStream> m) {
+            // @@@ Want to explicitly select ordered equalator
+            m.apply(data.parallelStream()).forEachOrdered(b);
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate sequentially
+    PAR_STREAM_SPLITERATOR(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, LongConsumer b, Function<S_IN, LongStream> m) {
+            for (Spliterator.OfLong spl = m.apply(data.parallelStream()).spliterator(); spl.tryAdvance(b); ) {
+            }
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate sequentially
+    PAR_STREAM_SPLITERATOR_FOREACH(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, LongConsumer b, Function<S_IN, LongStream> m) {
+            m.apply(data.parallelStream()).spliterator().forEachRemaining(b);
+        }
+    },
+
+    PAR_STREAM_TO_ARRAY(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, LongConsumer b, Function<S_IN, LongStream> m) {
+            for (long t : m.apply(data.parallelStream()).toArray())
+                b.accept(t);
+        }
+    },
+
+    // Wrap as parallel stream, get the spliterator, wrap as a stream + toArray
+    PAR_STREAM_SPLITERATOR_STREAM_TO_ARRAY(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, LongConsumer b, Function<S_IN, LongStream> m) {
+            LongStream s = m.apply(data.parallelStream());
+            Spliterator.OfLong sp = s.spliterator();
+            LongStream ss = StreamSupport.longParallelStream(() -> sp,
+                                                             StreamOpFlag.toCharacteristics(OpTestCase.getStreamFlags(s))
+                                                             | (sp.getExactSizeIfKnown() < 0 ? 0 : Spliterator.SIZED));
+            for (long t : ss.toArray())
+                b.accept(t);
+        }
+    },
+
+    PAR_STREAM_TO_ARRAY_CLEAR_SIZED(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, LongConsumer b, Function<S_IN, LongStream> m) {
+            S_IN pipe1 = (S_IN) OpTestCase.chain(data.parallelStream(),
+                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
+            LongStream pipe2 = m.apply(pipe1);
+
+            for (long t : pipe2.toArray())
+                b.accept(t);
+        }
+    },;
+
+    private boolean isParallel;
+
+    LongStreamTestScenario(boolean isParallel) {
+        this.isParallel = isParallel;
+    }
+
+    public StreamShape getShape() {
+        return StreamShape.LONG_VALUE;
+    }
+
+    public boolean isParallel() {
+        return isParallel;
+    }
+
+    public <T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
+    void run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, S_OUT> m) {
+        _run(data, (LongConsumer) b, (Function<S_IN, LongStream>) m);
+    }
+
+    abstract <T, S_IN extends BaseStream<T, S_IN>>
+    void _run(TestData<T, S_IN> data, LongConsumer b, Function<S_IN, LongStream> m);
+
+}
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java b/jdk/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java
new file mode 100644
index 0000000..763b883
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java
@@ -0,0 +1,633 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Base class for streams test cases.  Provides 'exercise' methods for taking
+ * lambdas that construct and modify streams, and evaluates them in different
+ * ways and asserts that they produce equivalent results.
+ */
+@Test
+public abstract class OpTestCase extends Assert {
+
+    private final Map<StreamShape, Set<? extends BaseStreamTestScenario>> testScenarios;
+
+    protected OpTestCase() {
+        testScenarios = new EnumMap<>(StreamShape.class);
+        testScenarios.put(StreamShape.REFERENCE, Collections.unmodifiableSet(EnumSet.allOf(StreamTestScenario.class)));
+        testScenarios.put(StreamShape.INT_VALUE, Collections.unmodifiableSet(EnumSet.allOf(IntStreamTestScenario.class)));
+        testScenarios.put(StreamShape.LONG_VALUE, Collections.unmodifiableSet(EnumSet.allOf(LongStreamTestScenario.class)));
+        testScenarios.put(StreamShape.DOUBLE_VALUE, Collections.unmodifiableSet(EnumSet.allOf(DoubleStreamTestScenario.class)));
+    }
+
+    @SuppressWarnings("rawtypes")
+    public static int getStreamFlags(BaseStream s) {
+        return ((AbstractPipeline) s).getStreamFlags();
+    }
+
+    // Exercise stream operations
+
+    public interface BaseStreamTestScenario {
+        StreamShape getShape();
+
+        boolean isParallel();
+
+        abstract <T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
+        void run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, S_OUT> m);
+    }
+
+    public <T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
+    Collection<U> exerciseOps(TestData<T, S_IN> data, Function<S_IN, S_OUT> m) {
+        return withData(data).stream(m).exercise();
+    }
+
+    // Run multiple versions of exercise(), returning the result of the first, and asserting that others return the same result
+    // If the first version is s -> s.foo(), can be used with s -> s.mapToInt(i -> i).foo().mapToObj(i -> i) to test all shape variants
+    @SafeVarargs
+    public final<T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
+    Collection<U> exerciseOpsMulti(TestData<T, S_IN> data,
+                                   Function<S_IN, S_OUT>... ms) {
+        Collection<U> result = null;
+        for (Function<S_IN, S_OUT> m : ms) {
+            if (result == null)
+                result = withData(data).stream(m).exercise();
+            else {
+                Collection<U> r2 = withData(data).stream(m).exercise();
+                assertEquals(result, r2);
+            }
+        }
+        return result;
+    }
+
+    // Run multiple versions of exercise() for an Integer stream, returning the result of the first, and asserting that others return the same result
+    // Automates the conversion between Stream<Integer> and {Int,Long,Double}Stream and back, so client sites look like you are passing the same
+    // lambda four times, but in fact they are four different lambdas since they are transforming four different kinds of streams
+    public final
+    Collection<Integer> exerciseOpsInt(TestData.OfRef<Integer> data,
+                                       Function<Stream<Integer>, Stream<Integer>> mRef,
+                                       Function<IntStream, IntStream> mInt,
+                                       Function<LongStream, LongStream> mLong,
+                                       Function<DoubleStream, DoubleStream> mDouble) {
+        @SuppressWarnings({ "rawtypes", "unchecked" })
+        Function<Stream<Integer>, Stream<Integer>>[] ms = new Function[4];
+        ms[0] = mRef;
+        ms[1] = s -> mInt.apply(s.mapToInt(e -> e)).mapToObj(e -> e);
+        ms[2] = s -> mLong.apply(s.mapToLong(e -> e)).mapToObj(e -> (int) e);
+        ms[3] = s -> mDouble.apply(s.mapToDouble(e -> e)).mapToObj(e -> (int) e);
+        return exerciseOpsMulti(data, ms);
+    }
+
+    public <T, U, S_OUT extends BaseStream<U, S_OUT>>
+    Collection<U> exerciseOps(Collection<T> data, Function<Stream<T>, S_OUT> m) {
+        TestData.OfRef<T> data1 = TestData.Factory.ofCollection("Collection of type " + data.getClass().getName(), data);
+        return withData(data1).stream(m).exercise();
+    }
+
+    public <T, U, S_OUT extends BaseStream<U, S_OUT>, I extends Iterable<U>>
+    Collection<U> exerciseOps(Collection<T> data, Function<Stream<T>, S_OUT> m, I expected) {
+        TestData.OfRef<T> data1 = TestData.Factory.ofCollection("Collection of type " + data.getClass().getName(), data);
+        return withData(data1).stream(m).expectedResult(expected).exercise();
+    }
+
+    @SuppressWarnings("unchecked")
+    public <U, S_OUT extends BaseStream<U, S_OUT>>
+    Collection<U> exerciseOps(int[] data, Function<IntStream, S_OUT> m) {
+        return withData(TestData.Factory.ofArray("int array", data)).stream(m).exercise();
+    }
+
+    public Collection<Integer> exerciseOps(int[] data, Function<IntStream, IntStream> m, int[] expected) {
+        TestData.OfInt data1 = TestData.Factory.ofArray("int array", data);
+        return withData(data1).stream(m).expectedResult(expected).exercise();
+    }
+
+    public <T, S_IN extends BaseStream<T, S_IN>> DataStreamBuilder<T, S_IN> withData(TestData<T, S_IN> data) {
+        Objects.requireNonNull(data);
+        return new DataStreamBuilder<>(data);
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public class DataStreamBuilder<T, S_IN extends BaseStream<T, S_IN>> {
+        final TestData<T, S_IN> data;
+
+        private DataStreamBuilder(TestData<T, S_IN> data) {
+            this.data = Objects.requireNonNull(data);
+        }
+
+        public <U, S_OUT extends BaseStream<U, S_OUT>>
+        ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> ops(IntermediateTestOp... ops) {
+            return new ExerciseDataStreamBuilder<>(data, (S_IN s) -> (S_OUT) chain(s, ops));
+        }
+
+        public <U, S_OUT extends BaseStream<U, S_OUT>> ExerciseDataStreamBuilder<T, U, S_IN, S_OUT>
+        stream(Function<S_IN, S_OUT> m) {
+            return new ExerciseDataStreamBuilder<>(data, m);
+        }
+
+        public <U, S_OUT extends BaseStream<U, S_OUT>> ExerciseDataStreamBuilder<T, U, S_IN, S_OUT>
+        stream(Function<S_IN, S_OUT> m, IntermediateTestOp<U, U> additionalOp) {
+            return new ExerciseDataStreamBuilder<>(data, s -> (S_OUT) chain(m.apply(s), additionalOp));
+        }
+
+        public <R> ExerciseDataTerminalBuilder<T, T, R, S_IN, S_IN>
+        terminal(Function<S_IN, R> terminalF) {
+            return new ExerciseDataTerminalBuilder<>(data, s -> s, terminalF);
+        }
+
+        public <U, R, S_OUT extends BaseStream<U, S_OUT>> ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT>
+        terminal(Function<S_IN, S_OUT> streamF, Function<S_OUT, R> terminalF) {
+            return new ExerciseDataTerminalBuilder<>(data, streamF, terminalF);
+        }
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public class ExerciseDataStreamBuilder<T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>> {
+        final TestData<T, S_IN> data;
+        final Function<S_IN, S_OUT> m;
+        final StreamShape shape;
+
+        Set<BaseStreamTestScenario> testSet = new HashSet<>();
+
+        Collection<U> refResult;
+        boolean isOrdered;
+
+        Consumer<TestData<T, S_IN>> before = LambdaTestHelpers.bEmpty;
+
+        Consumer<TestData<T, S_IN>> after = LambdaTestHelpers.bEmpty;
+
+        BiConsumer<Iterable<U>, Iterable<U>> sequentialEqualityAsserter = LambdaTestHelpers::assertContentsEqual;
+        BiConsumer<Iterable<U>, Iterable<U>> parallelEqualityAsserter = LambdaTestHelpers::assertContentsEqual;
+
+        private ExerciseDataStreamBuilder(TestData<T, S_IN> data, Function<S_IN, S_OUT> m) {
+            this.data = data;
+
+            this.m = Objects.requireNonNull(m);
+
+            this.shape = ((AbstractPipeline<?, U, ?>) m.apply(data.stream())).getOutputShape();
+
+            // Have to initiate from the output shape of the last stream
+            // This means the stream mapper is required first rather than last
+            testSet.addAll(testScenarios.get(shape));
+        }
+
+        public BiConsumer<Iterable<U>, Iterable<U>> getEqualityAsserter(BaseStreamTestScenario t) {
+            return t.isParallel() ? parallelEqualityAsserter : sequentialEqualityAsserter;
+        }
+
+        //
+
+        public <I extends Iterable<U>> ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> expectedResult(I expectedResult) {
+            List<U> l = new ArrayList<>();
+            expectedResult.forEach(l::add);
+            refResult = l;
+            return this;
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> expectedResult(int[] expectedResult) {
+            List l = new ArrayList();
+            for (int anExpectedResult : expectedResult) {
+                l.add(anExpectedResult);
+            }
+            refResult = l;
+            return this;
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> expectedResult(long[] expectedResult) {
+            List l = new ArrayList();
+            for (long anExpectedResult : expectedResult) {
+                l.add(anExpectedResult);
+            }
+            refResult = l;
+            return this;
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> expectedResult(double[] expectedResult) {
+            List l = new ArrayList();
+            for (double anExpectedResult : expectedResult) {
+                l.add(anExpectedResult);
+            }
+            refResult = l;
+            return this;
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> before(Consumer<TestData<T, S_IN>> before) {
+            this.before = Objects.requireNonNull(before);
+            return this;
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> after(Consumer<TestData<T, S_IN>> after) {
+            this.after = Objects.requireNonNull(after);
+            return this;
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> without(BaseStreamTestScenario... tests) {
+            return without(Arrays.asList(tests));
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> without(Collection<? extends BaseStreamTestScenario> tests) {
+            for (BaseStreamTestScenario ts : tests) {
+                if (ts.getShape() == shape) {
+                    testSet.remove(ts);
+                }
+            }
+
+            if (testSet.isEmpty()) {
+                throw new IllegalStateException("Test scenario set is empty");
+            }
+
+            return this;
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> with(BaseStreamTestScenario... tests) {
+            return with(Arrays.asList(tests));
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> with(Collection<? extends BaseStreamTestScenario> tests) {
+            testSet = new HashSet<>();
+
+            for (BaseStreamTestScenario ts : tests) {
+                if (ts.getShape() == shape) {
+                    testSet.add(ts);
+                }
+            }
+
+            if (testSet.isEmpty()) {
+                throw new IllegalStateException("Test scenario set is empty");
+            }
+
+            return this;
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> sequentialEqualityAsserter(BiConsumer<Iterable<U>, Iterable<U>> equalator) {
+            this.sequentialEqualityAsserter = equalator;
+            return this;
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> parallelEqualityAsserter(BiConsumer<Iterable<U>, Iterable<U>> equalator) {
+            this.parallelEqualityAsserter = equalator;
+            return this;
+        }
+
+        // Build method
+
+        private long count(StreamShape shape, BaseStream s) {
+            switch (shape) {
+                case REFERENCE:    return ((Stream) s).count();
+                case INT_VALUE:    return ((IntStream) s).count();
+                case LONG_VALUE:   return ((LongStream) s).count();
+                case DOUBLE_VALUE: return ((DoubleStream) s).count();
+                default: throw new IllegalStateException("Unknown shape: " + shape);
+            }
+        }
+
+        public Collection<U> exercise() {
+            if (refResult == null) {
+                // Induce the reference result
+                before.accept(data);
+                S_OUT sOut = m.apply(data.stream());
+                isOrdered = StreamOpFlag.ORDERED.isKnown(((AbstractPipeline) sOut).getStreamFlags());
+                Node<U> refNodeResult = ((AbstractPipeline<?, U, ?>) sOut).evaluateToArrayNode(size -> (U[]) new Object[size]);
+                refResult = LambdaTestHelpers.toBoxedList(refNodeResult.spliterator());
+                after.accept(data);
+                S_OUT anotherCopy = m.apply(data.stream());
+                long count = count(((AbstractPipeline) anotherCopy).getOutputShape(), anotherCopy);
+                assertEquals(count, refNodeResult.count());
+            }
+
+            List<Error> errors = new ArrayList<>();
+            for (BaseStreamTestScenario test : testSet) {
+                try {
+                    before.accept(data);
+
+                    List<U> result = new ArrayList<>();
+                    test.run(data, LambdaTestHelpers.<U>toBoxingConsumer(result::add), m);
+
+                    Runnable asserter = () -> getEqualityAsserter(test).accept(result, refResult);
+                    if (test.isParallel() && !isOrdered)
+                        asserter = () -> LambdaTestHelpers.assertContentsUnordered(result, refResult);
+                    LambdaTestHelpers.launderAssertion(
+                            asserter,
+                            () -> String.format("%n%s: %s != %s", test, refResult, result));
+
+                    after.accept(data);
+//                } catch (AssertionError ae) {
+//                    errors.add(ae);
+                } catch (Throwable t) {
+                    errors.add(new Error(String.format("%s: %s", test, t), t));
+                }
+            }
+
+            if (!errors.isEmpty()) {
+                StringBuilder sb = new StringBuilder();
+                int i = 1;
+                for (Error t : errors) {
+                    sb.append(i++).append(": ");
+                    if (t instanceof AssertionError) {
+                        sb.append(t).append("\n");
+                    }
+                    else {
+                        StringWriter sw = new StringWriter();
+                        PrintWriter pw = new PrintWriter(sw);
+
+                        t.getCause().printStackTrace(pw);
+                        pw.flush();
+                        sb.append(t).append("\n").append(sw);
+                    }
+                }
+                sb.append("--");
+
+                fail(String.format("%d failure(s) for test data: %s\n%s", i - 1, data.toString(), sb));
+            }
+
+            return refResult;
+        }
+    }
+
+    // Exercise terminal operations
+
+    static enum TerminalTestScenario {
+        SINGLE_SEQUENTIAL,
+        SINGLE_SEQUENTIAL_SHORT_CIRCUIT,
+        SINGLE_PARALLEL,
+        ALL_SEQUENTIAL,
+        ALL_SEQUENTIAL_SHORT_CIRCUIT,
+        ALL_PARALLEL,
+        ALL_PARALLEL_SEQUENTIAL,
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public class ExerciseDataTerminalBuilder<T, U, R, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>> {
+        final TestData<T, S_IN> data;
+        final Function<S_IN, S_OUT> streamF;
+        final Function<S_OUT, R> terminalF;
+
+        R refResult;
+
+        Set<TerminalTestScenario> testSet = EnumSet.allOf(TerminalTestScenario.class);
+
+        Function<S_OUT, BiConsumer<R, R>> sequentialEqualityAsserter = s -> LambdaTestHelpers::assertContentsEqual;
+        Function<S_OUT, BiConsumer<R, R>> parallelEqualityAsserter = s -> LambdaTestHelpers::assertContentsEqual;
+
+        private ExerciseDataTerminalBuilder(TestData<T, S_IN> data, Function<S_IN, S_OUT> streamF, Function<S_OUT, R> terminalF) {
+            this.data = data;
+            this.streamF = Objects.requireNonNull(streamF);
+            this.terminalF = Objects.requireNonNull(terminalF);
+        }
+
+        //
+
+        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> expectedResult(R expectedResult) {
+            this.refResult = expectedResult;
+            return this;
+        }
+
+        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> equalator(BiConsumer<R, R> equalityAsserter) {
+            this.sequentialEqualityAsserter = s -> equalityAsserter;
+            this.parallelEqualityAsserter = s -> equalityAsserter;
+            return this;
+        }
+
+        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> sequentialEqualityAsserter(BiConsumer<R, R> equalityAsserter) {
+            this.sequentialEqualityAsserter = s -> equalityAsserter;
+            return this;
+        }
+
+        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> parallelEqualityAsserter(BiConsumer<R, R> equalityAsserter) {
+            this.parallelEqualityAsserter = s -> equalityAsserter;
+            return this;
+        }
+
+        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> parallelEqualityAsserter(Function<S_OUT, BiConsumer<R, R>> equalatorProvider) {
+            this.parallelEqualityAsserter = equalatorProvider;
+            return this;
+        }
+
+        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> without(TerminalTestScenario... tests) {
+            return without(Arrays.asList(tests));
+        }
+
+        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> without(Collection<TerminalTestScenario> tests) {
+            testSet.removeAll(tests);
+            if (testSet.isEmpty()) {
+                throw new IllegalStateException("Terminal test scenario set is empty");
+            }
+            return this;
+        }
+
+        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> with(TerminalTestScenario... tests) {
+            return with(Arrays.asList(tests));
+        }
+
+        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> with(Collection<TerminalTestScenario> tests) {
+            testSet.addAll(tests);
+            return this;
+        }
+
+        // Build method
+
+        public R exercise() {
+            S_OUT out = streamF.apply(data.stream());
+            AbstractPipeline ap = (AbstractPipeline) out;
+            StreamShape shape = ap.getOutputShape();
+
+            Node<U> node = ap.evaluateToArrayNode(size -> (U[]) new Object[size]);
+            if (refResult == null) {
+                // Sequentially collect the output that will be input to the terminal op
+                refResult = terminalF.apply((S_OUT) createPipeline(shape, node.spliterator(),
+                                                                   StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SIZED,
+                                                                   false));
+            } else if (testSet.contains(TerminalTestScenario.SINGLE_SEQUENTIAL)) {
+                S_OUT source = (S_OUT) createPipeline(shape, node.spliterator(),
+                                                      StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SIZED,
+                                                      false);
+                BiConsumer<R, R> asserter = sequentialEqualityAsserter.apply(source);
+                R result = terminalF.apply(source);
+                LambdaTestHelpers.launderAssertion(() -> asserter.accept(refResult, result),
+                                                   () -> String.format("Single sequential: %s != %s", refResult, result));
+            }
+
+            if (testSet.contains(TerminalTestScenario.SINGLE_SEQUENTIAL_SHORT_CIRCUIT)) {
+                S_OUT source = (S_OUT) createPipeline(shape, node.spliterator(),
+                                                      StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SIZED,
+                                                      false);
+                // Force short-curcuit
+                source = (S_OUT) chain(source, new ShortCircuitOp<U>(shape));
+                BiConsumer<R, R> asserter = sequentialEqualityAsserter.apply(source);
+                R result = terminalF.apply(source);
+                LambdaTestHelpers.launderAssertion(() -> asserter.accept(refResult, result),
+                                                   () -> String.format("Single sequential pull: %s != %s", refResult, result));
+            }
+
+            if (testSet.contains(TerminalTestScenario.SINGLE_PARALLEL)) {
+                S_OUT source = (S_OUT) createPipeline(shape, node.spliterator(),
+                                                      StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SIZED,
+                                                      true);
+                BiConsumer<R, R> asserter = parallelEqualityAsserter.apply(source);
+                R result = terminalF.apply(source);
+                LambdaTestHelpers.launderAssertion(() -> asserter.accept(refResult, result),
+                                                   () -> String.format("Single parallel: %s != %s", refResult, result));
+            }
+
+            if (testSet.contains(TerminalTestScenario.ALL_SEQUENTIAL)) {
+                // This may forEach or tryAdvance depending on the terminal op implementation
+                S_OUT source = streamF.apply(data.stream());
+                BiConsumer<R, R> asserter = sequentialEqualityAsserter.apply(source);
+                R result = terminalF.apply(source);
+                LambdaTestHelpers.launderAssertion(() -> asserter.accept(refResult, result),
+                                                   () -> String.format("All sequential: %s != %s", refResult, result));
+            }
+
+            if (testSet.contains(TerminalTestScenario.ALL_SEQUENTIAL_SHORT_CIRCUIT)) {
+                S_OUT source = streamF.apply(data.stream());
+                // Force short-curcuit
+                source = (S_OUT) chain(source, new ShortCircuitOp<U>(shape));
+                BiConsumer<R, R> asserter = sequentialEqualityAsserter.apply(source);
+                R result = terminalF.apply(source);
+                LambdaTestHelpers.launderAssertion(() -> asserter.accept(refResult, result),
+                                                   () -> String.format("All sequential pull: %s != %s", refResult, result));
+            }
+
+            if (testSet.contains(TerminalTestScenario.ALL_PARALLEL)) {
+                S_OUT source = streamF.apply(data.parallelStream());
+                BiConsumer<R, R> asserter = parallelEqualityAsserter.apply(source);
+                R result = terminalF.apply(source);
+                LambdaTestHelpers.launderAssertion(() -> asserter.accept(refResult, result),
+                                                   () -> String.format("All parallel: %s != %s", refResult, result));
+            }
+
+            if (testSet.contains(TerminalTestScenario.ALL_PARALLEL_SEQUENTIAL)) {
+                S_OUT source = streamF.apply(data.parallelStream());
+                BiConsumer<R, R> asserter = parallelEqualityAsserter.apply(source);
+                R result = terminalF.apply(source.sequential());
+                LambdaTestHelpers.launderAssertion(() -> asserter.accept(refResult, result),
+                                                   () -> String.format("All parallel then sequential: %s != %s", refResult, result));
+            }
+
+            return refResult;
+        }
+
+        AbstractPipeline createPipeline(StreamShape shape, Spliterator s, int flags, boolean parallel) {
+            switch (shape) {
+                case REFERENCE:    return new ReferencePipeline.Head<>(s, flags, parallel);
+                case INT_VALUE:    return new IntPipeline.Head(s, flags, parallel);
+                case LONG_VALUE:   return new LongPipeline.Head(s, flags, parallel);
+                case DOUBLE_VALUE: return new DoublePipeline.Head(s, flags, parallel);
+                default: throw new IllegalStateException("Unknown shape: " + shape);
+            }
+        }
+    }
+
+    public <T, R> R exerciseTerminalOps(Collection<T> data, Function<Stream<T>, R> m, R expected) {
+        TestData.OfRef<T> data1
+                = TestData.Factory.ofCollection("Collection of type " + data.getClass().getName(), data);
+        return withData(data1).terminal(m).expectedResult(expected).exercise();
+    }
+
+    public <T, R, S_IN extends BaseStream<T, S_IN>> R
+    exerciseTerminalOps(TestData<T, S_IN> data,
+                        Function<S_IN, R> terminalF) {
+        return withData(data).terminal(terminalF).exercise();
+    }
+
+    public <T, U, R, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>> R
+    exerciseTerminalOps(TestData<T, S_IN> data,
+                        Function<S_IN, S_OUT> streamF,
+                        Function<S_OUT, R> terminalF) {
+        return withData(data).terminal(streamF, terminalF).exercise();
+    }
+
+    //
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    private static <T> AbstractPipeline<?, T, ?> chain(AbstractPipeline upstream, IntermediateTestOp<?, T> op) {
+        return (AbstractPipeline<?, T, ?>) IntermediateTestOp.chain(upstream, op);
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    private static AbstractPipeline<?, ?, ?> chain(AbstractPipeline pipe, IntermediateTestOp... ops) {
+        for (IntermediateTestOp op : ops)
+            pipe = chain(pipe, op);
+        return pipe;
+    }
+
+    @SuppressWarnings("rawtypes")
+    private static <T> AbstractPipeline<?, T, ?> chain(BaseStream pipe, IntermediateTestOp<?, T> op) {
+        return chain((AbstractPipeline) pipe, op);
+    }
+
+    @SuppressWarnings("rawtypes")
+    public static AbstractPipeline<?, ?, ?> chain(BaseStream pipe, IntermediateTestOp... ops) {
+        return chain((AbstractPipeline) pipe, ops);
+    }
+
+    // Test data
+
+    private class ShortCircuitOp<T> implements StatelessTestOp<T,T> {
+        private final StreamShape shape;
+
+        private ShortCircuitOp(StreamShape shape) {
+            this.shape = shape;
+        }
+
+        @Override
+        public Sink<T> opWrapSink(int flags, boolean parallel, Sink<T> sink) {
+            return sink;
+        }
+
+        @Override
+        public int opGetFlags() {
+            return StreamOpFlag.IS_SHORT_CIRCUIT;
+        }
+
+        @Override
+        public StreamShape outputShape() {
+            return shape;
+        }
+
+        @Override
+        public StreamShape inputShape() {
+            return shape;
+        }
+    }
+}
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/SpliteratorTestHelper.java b/jdk/test/java/util/stream/bootlib/java/util/stream/SpliteratorTestHelper.java
new file mode 100644
index 0000000..8cadf5f
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/SpliteratorTestHelper.java
@@ -0,0 +1,654 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Spliterator;
+import java.util.function.*;
+
+import static org.testng.Assert.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+/**
+ * Assertion methods for spliterators, to be called from other tests
+ */
+public class SpliteratorTestHelper {
+
+    public static void testSpliterator(Supplier<Spliterator<Integer>> supplier) {
+        testSpliterator(supplier, (Consumer<Integer> b) -> b);
+    }
+
+    public static void testIntSpliterator(Supplier<Spliterator.OfInt> supplier) {
+        class BoxingAdapter implements Consumer<Integer>, IntConsumer {
+            private final Consumer<Integer> b;
+
+            BoxingAdapter(Consumer<Integer> b) {
+                this.b = b;
+            }
+
+            @Override
+            public void accept(Integer value) {
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public void accept(int value) {
+                b.accept(value);
+            }
+        }
+
+        testSpliterator(supplier, c -> new BoxingAdapter(c));
+    }
+
+    public static void testLongSpliterator(Supplier<Spliterator.OfLong> supplier) {
+        class BoxingAdapter implements Consumer<Long>, LongConsumer {
+            private final Consumer<Long> b;
+
+            BoxingAdapter(Consumer<Long> b) {
+                this.b = b;
+            }
+
+            @Override
+            public void accept(Long value) {
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public void accept(long value) {
+                b.accept(value);
+            }
+        }
+
+        testSpliterator(supplier, c -> new BoxingAdapter(c));
+    }
+
+    public static void testDoubleSpliterator(Supplier<Spliterator.OfDouble> supplier) {
+        class BoxingAdapter implements Consumer<Double>, DoubleConsumer {
+            private final Consumer<Double> b;
+
+            BoxingAdapter(Consumer<Double> b) {
+                this.b = b;
+            }
+
+            @Override
+            public void accept(Double value) {
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public void accept(double value) {
+                b.accept(value);
+            }
+        }
+
+        testSpliterator(supplier, c -> new BoxingAdapter(c));
+    }
+
+    static <T, S extends Spliterator<T>> void testSpliterator(Supplier<S> supplier,
+                                                              UnaryOperator<Consumer<T>> boxingAdapter) {
+        ArrayList<T> fromForEach = new ArrayList<>();
+        Spliterator<T> spliterator = supplier.get();
+        Consumer<T> addToFromForEach = boxingAdapter.apply(fromForEach::add);
+        spliterator.forEachRemaining(addToFromForEach);
+
+        Collection<T> exp = Collections.unmodifiableList(fromForEach);
+
+        testForEach(exp, supplier, boxingAdapter);
+        testTryAdvance(exp, supplier, boxingAdapter);
+        testMixedTryAdvanceForEach(exp, supplier, boxingAdapter);
+        testMixedTraverseAndSplit(exp, supplier, boxingAdapter);
+        testSplitAfterFullTraversal(supplier, boxingAdapter);
+        testSplitOnce(exp, supplier, boxingAdapter);
+        testSplitSixDeep(exp, supplier, boxingAdapter);
+        testSplitUntilNull(exp, supplier, boxingAdapter);
+    }
+
+    //
+
+    private static <T, S extends Spliterator<T>> void testForEach(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter) {
+        S spliterator = supplier.get();
+        long sizeIfKnown = spliterator.getExactSizeIfKnown();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        ArrayList<T> fromForEach = new ArrayList<>();
+        spliterator = supplier.get();
+        Consumer<T> addToFromForEach = boxingAdapter.apply(fromForEach::add);
+        spliterator.forEachRemaining(addToFromForEach);
+
+        // Assert that forEach now produces no elements
+        spliterator.forEachRemaining(boxingAdapter.apply(
+                e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
+        // Assert that tryAdvance now produce no elements
+        spliterator.tryAdvance(boxingAdapter.apply(
+                e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
+
+        // assert that size, tryAdvance, and forEach are consistent
+        if (sizeIfKnown >= 0) {
+            assertEquals(sizeIfKnown, exp.size());
+        }
+        assertEquals(fromForEach.size(), exp.size());
+
+        assertContents(fromForEach, exp, isOrdered);
+    }
+
+    private static <T, S extends Spliterator<T>> void testTryAdvance(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter) {
+        S spliterator = supplier.get();
+        long sizeIfKnown = spliterator.getExactSizeIfKnown();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        spliterator = supplier.get();
+        ArrayList<T> fromTryAdvance = new ArrayList<>();
+        Consumer<T> addToFromTryAdvance = boxingAdapter.apply(fromTryAdvance::add);
+        while (spliterator.tryAdvance(addToFromTryAdvance)) { }
+
+        // Assert that forEach now produces no elements
+        spliterator.forEachRemaining(boxingAdapter.apply(
+                e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
+        // Assert that tryAdvance now produce no elements
+        spliterator.tryAdvance(boxingAdapter.apply(
+                e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
+
+        // assert that size, tryAdvance, and forEach are consistent
+        if (sizeIfKnown >= 0) {
+            assertEquals(sizeIfKnown, exp.size());
+        }
+        assertEquals(fromTryAdvance.size(), exp.size());
+
+        assertContents(fromTryAdvance, exp, isOrdered);
+    }
+
+    private static <T, S extends Spliterator<T>> void testMixedTryAdvanceForEach(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter) {
+        S spliterator = supplier.get();
+        long sizeIfKnown = spliterator.getExactSizeIfKnown();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        // tryAdvance first few elements, then forEach rest
+        ArrayList<T> dest = new ArrayList<>();
+        spliterator = supplier.get();
+        Consumer<T> addToDest = boxingAdapter.apply(dest::add);
+        for (int i = 0; i < 10 && spliterator.tryAdvance(addToDest); i++) { }
+        spliterator.forEachRemaining(addToDest);
+
+        // Assert that forEach now produces no elements
+        spliterator.forEachRemaining(boxingAdapter.apply(
+                e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
+        // Assert that tryAdvance now produce no elements
+        spliterator.tryAdvance(boxingAdapter.apply(
+                e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
+
+        if (sizeIfKnown >= 0) {
+            assertEquals(sizeIfKnown, dest.size());
+        }
+        assertEquals(dest.size(), exp.size());
+
+        if (isOrdered) {
+            assertEquals(dest, exp);
+        }
+        else {
+            assertContentsUnordered(dest, exp);
+        }
+    }
+
+    private static <T, S extends Spliterator<T>> void testMixedTraverseAndSplit(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter) {
+        S spliterator = supplier.get();
+        long sizeIfKnown = spliterator.getExactSizeIfKnown();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        // tryAdvance first few elements, then forEach rest
+        ArrayList<T> dest = new ArrayList<>();
+        spliterator = supplier.get();
+        Consumer<T> b = boxingAdapter.apply(dest::add);
+
+        Spliterator<T> spl1, spl2, spl3;
+        spliterator.tryAdvance(b);
+        spl2 = spliterator.trySplit();
+        if (spl2 != null) {
+            spl2.tryAdvance(b);
+            spl1 = spl2.trySplit();
+            if (spl1 != null) {
+                spl1.tryAdvance(b);
+                spl1.forEachRemaining(b);
+            }
+            spl2.tryAdvance(b);
+            spl2.forEachRemaining(b);
+        }
+        spliterator.tryAdvance(b);
+        spl3 = spliterator.trySplit();
+        if (spl3 != null) {
+            spl3.tryAdvance(b);
+            spl3.forEachRemaining(b);
+        }
+        spliterator.tryAdvance(b);
+        spliterator.forEachRemaining(b);
+
+        if (sizeIfKnown >= 0) {
+            assertEquals(sizeIfKnown, dest.size());
+        }
+        assertEquals(dest.size(), exp.size());
+
+        if (isOrdered) {
+            assertEquals(dest, exp);
+        }
+        else {
+            assertContentsUnordered(dest, exp);
+        }
+    }
+
+    private static <T, S extends Spliterator<T>> void testSplitAfterFullTraversal(
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter) {
+        // Full traversal using tryAdvance
+        Spliterator<T> spliterator = supplier.get();
+        while (spliterator.tryAdvance(boxingAdapter.apply(e -> { }))) { }
+        Spliterator<T> split = spliterator.trySplit();
+        assertNull(split);
+
+        // Full traversal using forEach
+        spliterator = supplier.get();
+        spliterator.forEachRemaining(boxingAdapter.apply(e -> {
+        }));
+        split = spliterator.trySplit();
+        assertNull(split);
+
+        // Full traversal using tryAdvance then forEach
+        spliterator = supplier.get();
+        spliterator.tryAdvance(boxingAdapter.apply(e -> { }));
+        spliterator.forEachRemaining(boxingAdapter.apply(e -> {
+        }));
+        split = spliterator.trySplit();
+        assertNull(split);
+    }
+
+    private static <T, S extends Spliterator<T>> void testSplitOnce(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter) {
+        S spliterator = supplier.get();
+        long sizeIfKnown = spliterator.getExactSizeIfKnown();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        ArrayList<T> fromSplit = new ArrayList<>();
+        Spliterator<T> s1 = supplier.get();
+        Spliterator<T> s2 = s1.trySplit();
+        long s1Size = s1.getExactSizeIfKnown();
+        long s2Size = (s2 != null) ? s2.getExactSizeIfKnown() : 0;
+        Consumer<T> addToFromSplit = boxingAdapter.apply(fromSplit::add);
+        if (s2 != null)
+            s2.forEachRemaining(addToFromSplit);
+        s1.forEachRemaining(addToFromSplit);
+
+        if (sizeIfKnown >= 0) {
+            assertEquals(sizeIfKnown, fromSplit.size());
+            if (s1Size >= 0 && s2Size >= 0)
+                assertEquals(sizeIfKnown, s1Size + s2Size);
+        }
+        assertContents(fromSplit, exp, isOrdered);
+    }
+
+    private static <T, S extends Spliterator<T>> void testSplitSixDeep(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter) {
+        S spliterator = supplier.get();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        for (int depth=0; depth < 6; depth++) {
+            List<T> dest = new ArrayList<>();
+            spliterator = supplier.get();
+
+            assertSpliterator(spliterator);
+
+            // verify splitting with forEach
+            splitSixDeepVisitor(depth, 0, dest, spliterator, boxingAdapter, spliterator.characteristics(), false);
+            assertContents(dest, exp, isOrdered);
+
+            // verify splitting with tryAdvance
+            dest.clear();
+            spliterator = supplier.get();
+            splitSixDeepVisitor(depth, 0, dest, spliterator, boxingAdapter, spliterator.characteristics(), true);
+            assertContents(dest, exp, isOrdered);
+        }
+    }
+
+    private static <T, S extends Spliterator<T>>
+    void splitSixDeepVisitor(int depth, int curLevel,
+                             List<T> dest, S spliterator, UnaryOperator<Consumer<T>> boxingAdapter,
+                             int rootCharacteristics, boolean useTryAdvance) {
+        if (curLevel < depth) {
+            long beforeSize = spliterator.getExactSizeIfKnown();
+            Spliterator<T> split = spliterator.trySplit();
+            if (split != null) {
+                assertSpliterator(split, rootCharacteristics);
+                assertSpliterator(spliterator, rootCharacteristics);
+
+                if ((rootCharacteristics & Spliterator.SUBSIZED) != 0 &&
+                    (rootCharacteristics & Spliterator.SIZED) != 0) {
+                    assertEquals(beforeSize, split.estimateSize() + spliterator.estimateSize());
+                }
+                splitSixDeepVisitor(depth, curLevel + 1, dest, split, boxingAdapter, rootCharacteristics, useTryAdvance);
+            }
+            splitSixDeepVisitor(depth, curLevel + 1, dest, spliterator, boxingAdapter, rootCharacteristics, useTryAdvance);
+        }
+        else {
+            long sizeIfKnown = spliterator.getExactSizeIfKnown();
+            if (useTryAdvance) {
+                Consumer<T> addToDest = boxingAdapter.apply(dest::add);
+                int count = 0;
+                while (spliterator.tryAdvance(addToDest)) {
+                    ++count;
+                }
+
+                if (sizeIfKnown >= 0)
+                    assertEquals(sizeIfKnown, count);
+
+                // Assert that forEach now produces no elements
+                spliterator.forEachRemaining(boxingAdapter.apply(
+                        e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
+
+                Spliterator<T> split = spliterator.trySplit();
+                assertNull(split);
+            }
+            else {
+                List<T> leafDest = new ArrayList<>();
+                Consumer<T> addToLeafDest = boxingAdapter.apply(leafDest::add);
+                spliterator.forEachRemaining(addToLeafDest);
+
+                if (sizeIfKnown >= 0)
+                    assertEquals(sizeIfKnown, leafDest.size());
+
+                // Assert that forEach now produces no elements
+                spliterator.tryAdvance(boxingAdapter.apply(
+                        e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
+
+                Spliterator<T> split = spliterator.trySplit();
+                assertNull(split);
+
+                dest.addAll(leafDest);
+            }
+        }
+    }
+
+    private static <T, S extends Spliterator<T>> void testSplitUntilNull(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter) {
+        Spliterator<T> s = supplier.get();
+        boolean isOrdered = s.hasCharacteristics(Spliterator.ORDERED);
+        assertSpliterator(s);
+
+        List<T> splits = new ArrayList<>();
+        Consumer<T> c = boxingAdapter.apply(splits::add);
+
+        testSplitUntilNull(new SplitNode<T>(c, s));
+        assertContents(splits, exp, isOrdered);
+    }
+
+    private static class SplitNode<T> {
+        // Constant for every node
+        final Consumer<T> c;
+        final int rootCharacteristics;
+
+        final Spliterator<T> s;
+
+        SplitNode(Consumer<T> c, Spliterator<T> s) {
+            this(c, s.characteristics(), s);
+        }
+
+        private SplitNode(Consumer<T> c, int rootCharacteristics, Spliterator<T> s) {
+            this.c = c;
+            this.rootCharacteristics = rootCharacteristics;
+            this.s = s;
+        }
+
+        SplitNode<T> fromSplit(Spliterator<T> split) {
+            return new SplitNode<>(c, rootCharacteristics, split);
+        }
+    }
+
+    /**
+     * Set the maximum stack capacity to 0.25MB. This should be more than enough to detect a bad spliterator
+     * while not unduly disrupting test infrastructure given the test data sizes that are used are small.
+     * Note that j.u.c.ForkJoinPool sets the max queue size to 64M (1 << 26).
+     */
+    private static final int MAXIMUM_STACK_CAPACITY = 1 << 18; // 0.25MB
+
+    private static <T> void testSplitUntilNull(SplitNode<T> e) {
+        // Use an explicit stack to avoid a StackOverflowException when testing a Spliterator
+        // that when repeatedly split produces a right-balanced (and maybe degenerate) tree, or
+        // for a spliterator that is badly behaved.
+        Deque<SplitNode<T>> stack = new ArrayDeque<>();
+        stack.push(e);
+
+        int iteration = 0;
+        while (!stack.isEmpty()) {
+            assertTrue(iteration++ < MAXIMUM_STACK_CAPACITY, "Exceeded maximum stack modification count of 1 << 18");
+
+            e = stack.pop();
+            Spliterator<T> parentAndRightSplit = e.s;
+
+            long parentEstimateSize = parentAndRightSplit.estimateSize();
+            assertTrue(parentEstimateSize >= 0,
+                       String.format("Split size estimate %d < 0", parentEstimateSize));
+
+            long parentSize = parentAndRightSplit.getExactSizeIfKnown();
+            Spliterator<T> leftSplit = parentAndRightSplit.trySplit();
+            if (leftSplit == null) {
+                parentAndRightSplit.forEachRemaining(e.c);
+                continue;
+            }
+
+            assertSpliterator(leftSplit, e.rootCharacteristics);
+            assertSpliterator(parentAndRightSplit, e.rootCharacteristics);
+
+            if (parentEstimateSize != Long.MAX_VALUE && leftSplit.estimateSize() > 0
+                && parentAndRightSplit.estimateSize() > 0) {
+                assertTrue(leftSplit.estimateSize() < parentEstimateSize,
+                           String.format("Left split size estimate %d >= parent split size estimate %d",
+                                         leftSplit.estimateSize(), parentEstimateSize));
+                assertTrue(parentAndRightSplit.estimateSize() < parentEstimateSize,
+                           String.format("Right split size estimate %d >= parent split size estimate %d",
+                                         leftSplit.estimateSize(), parentEstimateSize));
+            }
+            else {
+                assertTrue(leftSplit.estimateSize() <= parentEstimateSize,
+                           String.format("Left split size estimate %d > parent split size estimate %d",
+                                         leftSplit.estimateSize(), parentEstimateSize));
+                assertTrue(parentAndRightSplit.estimateSize() <= parentEstimateSize,
+                           String.format("Right split size estimate %d > parent split size estimate %d",
+                                         leftSplit.estimateSize(), parentEstimateSize));
+            }
+
+            long leftSize = leftSplit.getExactSizeIfKnown();
+            long rightSize = parentAndRightSplit.getExactSizeIfKnown();
+            if (parentSize >= 0 && leftSize >= 0 && rightSize >= 0)
+                assertEquals(parentSize, leftSize + rightSize,
+                             String.format("exact left split size %d + exact right split size %d != parent exact split size %d",
+                                           leftSize, rightSize, parentSize));
+
+            // Add right side to stack first so left side is popped off first
+            stack.push(e.fromSplit(parentAndRightSplit));
+            stack.push(e.fromSplit(leftSplit));
+        }
+    }
+
+    private static void assertSpliterator(Spliterator<?> s, int rootCharacteristics) {
+        if ((rootCharacteristics & Spliterator.SUBSIZED) != 0) {
+            assertTrue(s.hasCharacteristics(Spliterator.SUBSIZED),
+                       "Child split is not SUBSIZED when root split is SUBSIZED");
+        }
+        assertSpliterator(s);
+    }
+
+    private static void assertSpliterator(Spliterator<?> s) {
+        if (s.hasCharacteristics(Spliterator.SUBSIZED)) {
+            assertTrue(s.hasCharacteristics(Spliterator.SIZED));
+        }
+        if (s.hasCharacteristics(Spliterator.SIZED)) {
+            assertTrue(s.estimateSize() != Long.MAX_VALUE);
+            assertTrue(s.getExactSizeIfKnown() >= 0);
+        }
+        try {
+            s.getComparator();
+            assertTrue(s.hasCharacteristics(Spliterator.SORTED));
+        } catch (IllegalStateException e) {
+            assertFalse(s.hasCharacteristics(Spliterator.SORTED));
+        }
+    }
+
+    private static<T> void assertContents(Collection<T> actual, Collection<T> expected, boolean isOrdered) {
+        if (isOrdered) {
+            assertEquals(actual, expected);
+        }
+        else {
+            assertContentsUnordered(actual, expected);
+        }
+    }
+
+    private static<T> void assertContentsUnordered(Iterable<T> actual, Iterable<T> expected) {
+        assertEquals(toBoxedMultiset(actual), toBoxedMultiset(expected));
+    }
+
+    private static <T> Map<T, Integer> toBoxedMultiset(Iterable<T> c) {
+        Map<T, Integer> result = new HashMap<>();
+        c.forEach(e -> {
+            if (result.containsKey(e)) result.put(e, result.get(e) + 1);
+            else result.put(e, 1);
+        });
+        return result;
+    }
+
+    static<U> void mixedTraverseAndSplit(Consumer<U> b, Spliterator<U> splTop) {
+        Spliterator<U> spl1, spl2, spl3;
+        splTop.tryAdvance(b);
+        spl2 = splTop.trySplit();
+        if (spl2 != null) {
+            spl2.tryAdvance(b);
+            spl1 = spl2.trySplit();
+            if (spl1 != null) {
+                spl1.tryAdvance(b);
+                spl1.forEachRemaining(b);
+            }
+            spl2.tryAdvance(b);
+            spl2.forEachRemaining(b);
+        }
+        splTop.tryAdvance(b);
+        spl3 = splTop.trySplit();
+        if (spl3 != null) {
+            spl3.tryAdvance(b);
+            spl3.forEachRemaining(b);
+        }
+        splTop.tryAdvance(b);
+        splTop.forEachRemaining(b);
+    }
+
+    static void mixedTraverseAndSplit(IntConsumer b, Spliterator.OfInt splTop) {
+        Spliterator.OfInt spl1, spl2, spl3;
+        splTop.tryAdvance(b);
+        spl2 = splTop.trySplit();
+        if (spl2 != null) {
+            spl2.tryAdvance(b);
+            spl1 = spl2.trySplit();
+            if (spl1 != null) {
+                spl1.tryAdvance(b);
+                spl1.forEachRemaining(b);
+            }
+            spl2.tryAdvance(b);
+            spl2.forEachRemaining(b);
+        }
+        splTop.tryAdvance(b);
+        spl3 = splTop.trySplit();
+        if (spl3 != null) {
+            spl3.tryAdvance(b);
+            spl3.forEachRemaining(b);
+        }
+        splTop.tryAdvance(b);
+        splTop.forEachRemaining(b);
+    }
+    static void mixedTraverseAndSplit(LongConsumer b, Spliterator.OfLong splTop) {
+        Spliterator.OfLong spl1, spl2, spl3;
+        splTop.tryAdvance(b);
+        spl2 = splTop.trySplit();
+        if (spl2 != null) {
+            spl2.tryAdvance(b);
+            spl1 = spl2.trySplit();
+            if (spl1 != null) {
+                spl1.tryAdvance(b);
+                spl1.forEachRemaining(b);
+            }
+            spl2.tryAdvance(b);
+            spl2.forEachRemaining(b);
+        }
+        splTop.tryAdvance(b);
+        spl3 = splTop.trySplit();
+        if (spl3 != null) {
+            spl3.tryAdvance(b);
+            spl3.forEachRemaining(b);
+        }
+        splTop.tryAdvance(b);
+        splTop.forEachRemaining(b);
+    }
+
+    static void mixedTraverseAndSplit(DoubleConsumer b, Spliterator.OfDouble splTop) {
+        Spliterator.OfDouble spl1, spl2, spl3;
+        splTop.tryAdvance(b);
+        spl2 = splTop.trySplit();
+        if (spl2 != null) {
+            spl2.tryAdvance(b);
+            spl1 = spl2.trySplit();
+            if (spl1 != null) {
+                spl1.tryAdvance(b);
+                spl1.forEachRemaining(b);
+            }
+            spl2.tryAdvance(b);
+            spl2.forEachRemaining(b);
+        }
+        splTop.tryAdvance(b);
+        spl3 = splTop.trySplit();
+        if (spl3 != null) {
+            spl3.tryAdvance(b);
+            spl3.forEachRemaining(b);
+        }
+        splTop.tryAdvance(b);
+        splTop.forEachRemaining(b);
+    }
+}
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/StatefulTestOp.java b/jdk/test/java/util/stream/bootlib/java/util/stream/StatefulTestOp.java
new file mode 100644
index 0000000..5414cfd
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/StatefulTestOp.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import java.util.Spliterator;
+import java.util.function.IntFunction;
+
+/**
+ * The base type for a stateful test operation.
+ */
+interface StatefulTestOp<E> extends IntermediateTestOp<E, E> {
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public static<T> AbstractPipeline chain(AbstractPipeline upstream,
+                                            StatefulTestOp op) {
+        switch (op.outputShape()) {
+            case REFERENCE:
+                return new ReferencePipeline.StatefulOp<Object, T>(upstream, op.inputShape(), op.opGetFlags()) {
+                    @Override
+                    Sink opWrapSink(int flags, Sink sink) {
+                        return op.opWrapSink(flags, isParallel(), sink);
+                    }
+
+                    @Override
+                    <P_IN> Spliterator<T> opEvaluateParallelLazy(PipelineHelper<T> helper,
+                                                                 Spliterator<P_IN> spliterator) {
+                        return op.opEvaluateParallelLazy(helper, spliterator);
+                    }
+
+                    @Override
+                    <P_IN> Node<T> opEvaluateParallel(PipelineHelper<T> helper,
+                                                      Spliterator<P_IN> spliterator,
+                                                      IntFunction<T[]> generator) {
+                        return op.opEvaluateParallel(helper, spliterator, generator);
+                    }
+                };
+            case INT_VALUE:
+                return new IntPipeline.StatefulOp<Object>(upstream, op.inputShape(), op.opGetFlags()) {
+                    @Override
+                    Sink opWrapSink(int flags, Sink sink) {
+                        return op.opWrapSink(flags, isParallel(), sink);
+                    }
+
+                    @Override
+                    <P_IN> Spliterator<Integer> opEvaluateParallelLazy(PipelineHelper<Integer> helper,
+                                                                 Spliterator<P_IN> spliterator) {
+                        return op.opEvaluateParallelLazy(helper, spliterator);
+                    }
+
+                    @Override
+                    <P_IN> Node<Integer> opEvaluateParallel(PipelineHelper<Integer> helper,
+                                                            Spliterator<P_IN> spliterator,
+                                                            IntFunction<Integer[]> generator) {
+                        return (Node<Integer>) op.opEvaluateParallel(helper, spliterator, generator);
+                    }
+                };
+            case LONG_VALUE:
+                return new LongPipeline.StatefulOp<Object>(upstream, op.inputShape(), op.opGetFlags()) {
+                    @Override
+                    Sink opWrapSink(int flags, Sink sink) {
+                        return op.opWrapSink(flags, isParallel(), sink);
+                    }
+
+                    @Override
+                    <P_IN> Spliterator<Long> opEvaluateParallelLazy(PipelineHelper<Long> helper,
+                                                                 Spliterator<P_IN> spliterator) {
+                        return op.opEvaluateParallelLazy(helper, spliterator);
+                    }
+
+                    @Override
+                    <P_IN> Node<Long> opEvaluateParallel(PipelineHelper<Long> helper,
+                                                         Spliterator<P_IN> spliterator,
+                                                         IntFunction<Long[]> generator) {
+                        return (Node<Long>) op.opEvaluateParallel(helper, spliterator, generator);
+                    }
+                };
+            case DOUBLE_VALUE:
+                return new DoublePipeline.StatefulOp<Object>(upstream, op.inputShape(), op.opGetFlags()) {
+                    @Override
+                    Sink opWrapSink(int flags, Sink sink) {
+                        return op.opWrapSink(flags, isParallel(), sink);
+                    }
+
+                    @Override
+                    <P_IN> Spliterator<Double> opEvaluateParallelLazy(PipelineHelper<Double> helper,
+                                                                    Spliterator<P_IN> spliterator) {
+                        return op.opEvaluateParallelLazy(helper, spliterator);
+                    }
+
+                    @Override
+                    <P_IN> Node<Double> opEvaluateParallel(PipelineHelper<Double> helper,
+                                                           Spliterator<P_IN> spliterator,
+                                                           IntFunction<Double[]> generator) {
+                        return (Node<Double>) op.opEvaluateParallel(helper, spliterator, generator);
+                    }
+                };
+            default: throw new IllegalStateException(op.outputShape().toString());
+        }
+    }
+
+    default StreamShape inputShape() { return StreamShape.REFERENCE; }
+
+    default StreamShape outputShape() { return StreamShape.REFERENCE; }
+
+    default int opGetFlags() { return 0; }
+
+    Sink<E> opWrapSink(int flags, boolean parallel, Sink<E> sink);
+
+    @SuppressWarnings("unchecked")
+    default <P_IN> Spliterator<E> opEvaluateParallelLazy(PipelineHelper<E> helper,
+                                                         Spliterator<P_IN> spliterator) {
+        return opEvaluateParallel(helper, spliterator, i -> (E[]) new Object[i]).spliterator();
+    }
+
+    <P_IN> Node<E> opEvaluateParallel(PipelineHelper<E> helper,
+                                      Spliterator<P_IN> spliterator,
+                                      IntFunction<E[]> generator);
+}
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/StatelessTestOp.java b/jdk/test/java/util/stream/bootlib/java/util/stream/StatelessTestOp.java
new file mode 100644
index 0000000..77460b7
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/StatelessTestOp.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+/**
+ * The base type of a stateless test operation
+ */
+interface StatelessTestOp<E_IN, E_OUT> extends IntermediateTestOp<E_IN, E_OUT> {
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public static<T> AbstractPipeline chain(AbstractPipeline upstream,
+                                            StatelessTestOp<?, T> op) {
+        int flags = op.opGetFlags();
+        switch (op.outputShape()) {
+            case REFERENCE:
+                return new ReferencePipeline.StatelessOp<Object, T>(upstream, op.inputShape(), flags) {
+                    public Sink opWrapSink(int flags, Sink<T> sink) {
+                        return op.opWrapSink(flags, isParallel(), sink);
+                    }
+                };
+            case INT_VALUE:
+                return new IntPipeline.StatelessOp<Object>(upstream, op.inputShape(), flags) {
+                    public Sink opWrapSink(int flags, Sink sink) {
+                        return op.opWrapSink(flags, isParallel(), sink);
+                    }
+                };
+            case LONG_VALUE:
+                return new LongPipeline.StatelessOp<Object>(upstream, op.inputShape(), flags) {
+                    @Override
+                    Sink opWrapSink(int flags, Sink sink) {
+                        return op.opWrapSink(flags, isParallel(), sink);
+                    }
+                };
+            case DOUBLE_VALUE:
+                return new DoublePipeline.StatelessOp<Object>(upstream, op.inputShape(), flags) {
+                    @Override
+                    Sink opWrapSink(int flags, Sink sink) {
+                        return op.opWrapSink(flags, isParallel(), sink);
+                    }
+                };
+            default: throw new IllegalStateException(op.outputShape().toString());
+        }
+    }
+
+    default StreamShape inputShape() { return StreamShape.REFERENCE; }
+
+    default StreamShape outputShape() { return StreamShape.REFERENCE; }
+
+    default int opGetFlags() { return 0; }
+
+    Sink<E_IN> opWrapSink(int flags, boolean parallel, Sink<E_OUT> sink);
+}
+
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/StreamOpFlagTestHelper.java b/jdk/test/java/util/stream/bootlib/java/util/stream/StreamOpFlagTestHelper.java
new file mode 100644
index 0000000..11ed0f1
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/StreamOpFlagTestHelper.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import java.util.EnumSet;
+
+public class StreamOpFlagTestHelper {
+
+    /** EnumSet containing stream flags */
+    private static final EnumSet<StreamOpFlag> allStreamFlags;
+
+    static {
+        allStreamFlags = EnumSet.allOf(StreamOpFlag.class);
+        for (StreamOpFlag f : EnumSet.allOf(StreamOpFlag.class))
+            if (!f.isStreamFlag())
+                allStreamFlags.remove(f);
+    }
+
+
+    static EnumSet<StreamOpFlag> allStreamFlags() {
+        // EnumSet is mutable
+        return allStreamFlags.clone();
+    }
+
+    public static boolean isStreamOrdered(Stream<?> s) {
+        return StreamOpFlag.ORDERED.isKnown(OpTestCase.getStreamFlags(s));
+    }
+}
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/StreamTestDataProvider.java b/jdk/test/java/util/stream/bootlib/java/util/stream/StreamTestDataProvider.java
new file mode 100644
index 0000000..08a71c4
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/StreamTestDataProvider.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import org.testng.annotations.DataProvider;
+
+import java.util.*;
+import java.util.Spliterators;
+import java.util.function.Supplier;
+
+/**
+ * StreamTestDataProvider
+ *
+ * @author Brian Goetz
+ */
+/** TestNG DataProvider for ref-valued streams */
+public class StreamTestDataProvider {
+    private static final Integer[] to0 = new Integer[0];
+    private static final Integer[] to1 = new Integer[1];
+    private static final Integer[] to10 = new Integer[10];
+    private static final Integer[] to100 = new Integer[100];
+    private static final Integer[] to1000 = new Integer[1000];
+    private static final Integer[] reversed = new Integer[100];
+    private static final Integer[] ones = new Integer[100];
+    private static final Integer[] twice = new Integer[200];
+    private static final Integer[] pseudoRandom;
+
+    private static final Object[][] testData;
+    private static final Object[][] withNullTestData;
+    private static final Object[][] spliteratorTestData;
+
+    static {
+        Integer[][] arrays = {to0, to1, to10, to100, to1000};
+        for (Integer[] arr : arrays) {
+            for (int i = 0; i < arr.length; i++) {
+                arr[i] = i;
+            }
+        }
+        for (int i = 0; i < reversed.length; i++) {
+            reversed[i] = reversed.length - i;
+        }
+        for (int i = 0; i < ones.length; i++) {
+            ones[i] = 1;
+        }
+        System.arraycopy(to100, 0, twice, 0, to100.length);
+        System.arraycopy(to100, 0, twice, to100.length, to100.length);
+        pseudoRandom = new Integer[LambdaTestHelpers.LONG_STRING.length()];
+        for (int i = 0; i < LambdaTestHelpers.LONG_STRING.length(); i++) {
+            pseudoRandom[i] = (int) LambdaTestHelpers.LONG_STRING.charAt(i);
+        }
+    }
+
+    static final Object[][] arrays = {
+            {"empty", to0},
+            {"0..1", to1},
+            {"0..10", to10},
+            {"0..100", to100},
+            {"0..1000", to1000},
+            {"100x[1]", ones},
+            {"2x[0..100]", twice},
+            {"reverse 0..100", reversed},
+            {"pseudorandom", pseudoRandom}
+    };
+
+    static {
+        {
+            List<Object[]> list = new ArrayList<>();
+            for (Object[] data : arrays) {
+                final Object name = data[0];
+                final Integer[] ints = (Integer[])data[1];
+                final List<Integer> intsAsList = Arrays.asList(ints);
+
+                list.add(arrayDataDescr("array:" + name, ints));
+                list.add(collectionDataDescr("ArrayList.asList:" + name, intsAsList));
+                list.add(collectionDataDescr("ArrayList:" + name, new ArrayList<>(intsAsList)));
+                list.add(streamDataDescr("DelegatingStream(ArrayList):" + name,
+                                         () -> new ArrayList<>(intsAsList).stream()));
+                List<Integer> aList = new ArrayList<>(intsAsList);
+                list.add(collectionDataDescr("ArrayList.Sublist:" + name,
+                                             (ints.length) <= 1 ? aList.subList(0, 0) : aList.subList(1, ints.length / 2)));
+                list.add(collectionDataDescr("LinkedList:" + name, new LinkedList<>(intsAsList)));
+                list.add(collectionDataDescr("HashSet:" + name, new HashSet<>(intsAsList)));
+                list.add(collectionDataDescr("LinkedHashSet:" + name, new LinkedHashSet<>(intsAsList)));
+                list.add(collectionDataDescr("TreeSet:" + name, new TreeSet<>(intsAsList)));
+                SpinedBuffer<Integer> spinedBuffer = new SpinedBuffer<>();
+                intsAsList.forEach(spinedBuffer);
+                list.add(sbDataDescr("SpinedBuffer:" + name, spinedBuffer));
+
+                // @@@ Add more
+            }
+            testData = list.toArray(new Object[0][]);
+        }
+
+        // Simple combination of numbers and null values, probably excessive but may catch
+        // errors for initialization/termination/sequence
+        // @@@ This is separate from the other data for now until nulls are consitently supported by
+        // all operations
+        {
+            List<Object[]> list = new ArrayList<>();
+            int size = 5;
+            for (int i = 0; i < (1 << size) - 2; i++) {
+                Integer[] content = new Integer[size];
+                for (int e = 0; e < size; e++) {
+                    content[e] = (i & (1 << e)) > 0 ? e + 1 : null;
+                }
+
+                // ORDERED
+                list.add(arrayDataDescr("array:" + i, content));
+                // not ORDERED, DISTINCT
+                list.add(collectionDataDescr("HashSet:" + i, new HashSet<>(Arrays.asList(content))));
+            }
+
+            withNullTestData = list.toArray(new Object[0][]);
+        }
+
+        {
+            List<Object[]> spliterators = new ArrayList<>();
+            for (Object[] data : arrays) {
+                final Object name = data[0];
+                final Integer[] ints = (Integer[])data[1];
+
+                spliterators.add(splitDescr("Arrays.s(array):" + name,
+                                            () -> Arrays.spliterator(ints)));
+                spliterators.add(splitDescr("arrays.s(array,o,l):" + name,
+                                            () -> Arrays.spliterator(ints, 0, ints.length/2)));
+                spliterators.add(splitDescr("SpinedBuffer.s():" + name,
+                                            () -> {
+                                                SpinedBuffer<Integer> sb = new SpinedBuffer<>();
+                                                for (Integer i : ints)
+                                                    sb.accept(i);
+                                                return sb.spliterator();
+                                            }));
+                spliterators.add(splitDescr("Iterators.s(Arrays.s(array).iterator(), size):" + name,
+                                            () -> Spliterators.spliterator(Arrays.asList(ints).iterator(), ints.length, 0)));
+                spliterators.add(splitDescr("Iterators.s(Arrays.s(array).iterator()):" + name,
+                                            () -> Spliterators.spliteratorUnknownSize(Arrays.asList(ints).iterator(), 0)));
+                // @@@ Add map and collection spliterators when spliterator() is exposed on Collection or Iterable
+            }
+            spliteratorTestData = spliterators.toArray(new Object[0][]);
+        }
+    }
+
+    static <T> Object[] arrayDataDescr(String description, T[] data) {
+        return new Object[] { description, TestData.Factory.ofArray(description, data)};
+    }
+
+    static <T> Object[] streamDataDescr(String description, Supplier<Stream<T>> supplier) {
+        return new Object[] { description, TestData.Factory.ofSupplier(description, supplier)};
+    }
+
+    static <T> Object[] collectionDataDescr(String description, Collection<T> data) {
+        return new Object[] { description, TestData.Factory.ofCollection(description, data)};
+    }
+
+    static <T> Object[] sbDataDescr(String description, SpinedBuffer<T> data) {
+        return new Object[] { description, TestData.Factory.ofSpinedBuffer(description, data)};
+    }
+
+    static <T> Object[] splitDescr(String description, Supplier<Spliterator<T>> ss) {
+        return new Object[] { description, ss };
+    }
+
+    // Return an array of ( String name, StreamTestData<Integer> )
+    @DataProvider(name = "StreamTestData<Integer>")
+    public static Object[][] makeStreamTestData() {
+        return testData;
+    }
+
+    @DataProvider(name = "withNull:StreamTestData<Integer>")
+    public static Object[][] makeStreamWithNullTestData() {
+        return withNullTestData;
+    }
+
+    // returns an array of (String name, Supplier<Spliterator<Integer>>)
+    @DataProvider(name = "Spliterator<Integer>")
+    public static Object[][] spliteratorProvider() {
+        return spliteratorTestData;
+    }
+}
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/StreamTestScenario.java b/jdk/test/java/util/stream/bootlib/java/util/stream/StreamTestScenario.java
new file mode 100644
index 0000000..c7f09ea
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/StreamTestScenario.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import java.util.Iterator;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+/**
+ * Test scenarios for reference streams.
+ *
+ * Each scenario is provided with a data source, a function that maps a fresh
+ * stream (as provided by the data source) to a new stream, and a sink to
+ * receive results.  Each scenario describes a different way of computing the
+ * stream contents.  The test driver will ensure that all scenarios produce
+ * the same output (modulo allowable differences in ordering).
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public enum StreamTestScenario implements OpTestCase.BaseStreamTestScenario {
+
+    STREAM_FOR_EACH(false) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            Stream<U> s = m.apply(data.stream());
+            if (s.isParallel()) {
+                s = s.sequential();
+            }
+            s.forEach(b);
+        }
+    },
+
+    // Collec to list
+    STREAM_COLLECT(false) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            for (U t : m.apply(data.stream()).collect(Collectors.toList())) {
+                b.accept(t);
+            }
+        }
+    },
+
+    // To array
+    STREAM_TO_ARRAY(false) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            for (Object t : m.apply(data.stream()).toArray()) {
+                b.accept((U) t);
+            }
+        }
+    },
+
+    // Wrap as stream, and iterate in pull mode
+    STREAM_ITERATOR(false) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            for (Iterator<U> seqIter = m.apply(data.stream()).iterator(); seqIter.hasNext(); )
+                b.accept(seqIter.next());
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate in pull mode
+    STREAM_SPLITERATOR(false) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            for (Spliterator<U> spl = m.apply(data.stream()).spliterator(); spl.tryAdvance(b); ) { }
+        }
+    },
+
+    // Wrap as stream, spliterate, then split a few times mixing advances with forEach
+    STREAM_SPLITERATOR_WITH_MIXED_TRAVERSE_AND_SPLIT(false) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            SpliteratorTestHelper.mixedTraverseAndSplit(b, m.apply(data.stream()).spliterator());
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate in pull mode
+    STREAM_SPLITERATOR_FOREACH(false) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            m.apply(data.stream()).spliterator().forEachRemaining(b);
+        }
+    },
+
+    // Wrap as parallel stream + sequential
+    PAR_STREAM_SEQUENTIAL_FOR_EACH(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            m.apply(data.parallelStream()).sequential().forEach(b);
+        }
+    },
+
+    // Wrap as parallel stream + forEachOrdered
+    PAR_STREAM_FOR_EACH_ORDERED(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            // @@@ Want to explicitly select ordered equalator
+            m.apply(data.parallelStream()).forEachOrdered(b);
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate sequentially
+    PAR_STREAM_SPLITERATOR(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            for (Spliterator<U> spl = m.apply(data.parallelStream()).spliterator(); spl.tryAdvance(b); ) { }
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate sequentially
+    PAR_STREAM_SPLITERATOR_FOREACH(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            m.apply(data.parallelStream()).spliterator().forEachRemaining(b);
+        }
+    },
+
+    // Wrap as parallel stream + toArray
+    PAR_STREAM_TO_ARRAY(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            for (Object t : m.apply(data.parallelStream()).toArray())
+                b.accept((U) t);
+        }
+    },
+
+    // Wrap as parallel stream, get the spliterator, wrap as a stream + toArray
+    PAR_STREAM_SPLITERATOR_STREAM_TO_ARRAY(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            Stream<U> s = m.apply(data.parallelStream());
+            Spliterator<U> sp = s.spliterator();
+            Stream<U> ss = StreamSupport.parallelStream(() -> sp,
+                                                        StreamOpFlag.toCharacteristics(OpTestCase.getStreamFlags(s))
+                                                        | (sp.getExactSizeIfKnown() < 0 ? 0 : Spliterator.SIZED));
+            for (Object t : ss.toArray())
+                b.accept((U) t);
+        }
+    },
+
+    // Wrap as parallel stream + toArray and clear SIZED flag
+    PAR_STREAM_TO_ARRAY_CLEAR_SIZED(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            S_IN pipe1 = (S_IN) OpTestCase.chain(data.parallelStream(),
+                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
+            Stream<U> pipe2 = m.apply(pipe1);
+
+            for (Object t : pipe2.toArray())
+                b.accept((U) t);
+        }
+    },
+
+    // Wrap as parallel + collect
+    PAR_STREAM_COLLECT(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            for (U u : m.apply(data.parallelStream()).collect(Collectors.toList()))
+                b.accept(u);
+        }
+    },
+
+    // Wrap sequential as parallel, + collect
+    STREAM_TO_PAR_STREAM_COLLECT(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            for (U u : m.apply(data.stream().parallel()).collect(Collectors.toList()))
+                b.accept(u);
+        }
+    },
+
+    // Wrap parallel as sequential,, + collect
+    PAR_STREAM_TO_STREAM_COLLECT(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void _run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            for (U u : m.apply(data.parallelStream().sequential()).collect(Collectors.toList()))
+                b.accept(u);
+        }
+    },
+    ;
+
+    private boolean isParallel;
+
+    StreamTestScenario(boolean isParallel) {
+        this.isParallel = isParallel;
+    }
+
+    public StreamShape getShape() {
+        return StreamShape.REFERENCE;
+    }
+
+    public boolean isParallel() {
+        return isParallel;
+    }
+
+    public <T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
+    void run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, S_OUT> m) {
+        _run(data, b, (Function<S_IN, Stream<U>>) m);
+    }
+
+    abstract <T, U, S_IN extends BaseStream<T, S_IN>>
+    void _run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, Stream<U>> m);
+
+}
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/TestData.java b/jdk/test/java/util/stream/bootlib/java/util/stream/TestData.java
new file mode 100644
index 0000000..e8b65d2
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/TestData.java
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.PrimitiveIterator;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.DoubleConsumer;
+import java.util.function.Function;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+import java.util.function.Supplier;
+import java.util.function.ToIntFunction;
+
+/** Describes a test data set for use in stream tests */
+public interface TestData<T, S extends BaseStream<T, S>>
+        extends Iterable<T> {
+
+    default int size() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    default Iterator<T> iterator() {
+        return Spliterators.iteratorFromSpliterator(spliterator());
+    }
+
+    Spliterator<T> spliterator();
+
+    default boolean isOrdered() {
+        return spliterator().hasCharacteristics(Spliterator.ORDERED);
+    }
+
+    StreamShape getShape();
+
+    default <A extends Collection<? super T>> A into(A target) {
+        spliterator().forEachRemaining(target::add);
+        return target;
+    }
+
+    S stream();
+
+    S parallelStream();
+
+    public interface OfRef<T> extends TestData<T, Stream<T>> { }
+
+    public interface OfInt extends TestData<Integer, IntStream> { }
+
+    public interface OfLong extends TestData<Long, LongStream> { }
+
+    public interface OfDouble extends TestData<Double, DoubleStream> { }
+
+    // @@@ Temporary garbage class to avoid triggering bugs with lambdas in static methods in interfaces
+    public static class Factory {
+        public static <T> OfRef<T> ofArray(String name, T[] array) {
+            return new AbstractTestData.RefTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(),
+                                                      Arrays::spliterator, a -> a.length);
+        }
+
+        public static <T> OfRef<T> ofCollection(String name, Collection<T> collection) {
+            return new AbstractTestData.RefTestData<>(name, collection, Collection::stream, Collection::parallelStream,
+                                                      Collection::spliterator, Collection::size);
+        }
+
+        public static <T> OfRef<T> ofSpinedBuffer(String name, SpinedBuffer<T> buffer) {
+            return new AbstractTestData.RefTestData<>(name, buffer,
+                                                      b -> StreamSupport.stream(b.spliterator()),
+                                                      b -> StreamSupport.parallelStream(b.spliterator()),
+                                                      SpinedBuffer::spliterator,
+                                                      b -> (int) b.count());
+        }
+
+        public static <T> OfRef<T> ofSupplier(String name, Supplier<Stream<T>> supplier) {
+            return new AbstractTestData.RefTestData<>(name, supplier,
+                                                      Supplier::get,
+                                                      s -> s.get().parallel(),
+                                                      s -> s.get().spliterator(),
+                                                      s -> (int) s.get().spliterator().getExactSizeIfKnown());
+        }
+
+        public static <T> OfRef<T> ofRefNode(String name, Node<T> node) {
+            return new AbstractTestData.RefTestData<>(name, node,
+                                                      n -> StreamSupport.stream(n::spliterator, Spliterator.SIZED | Spliterator.ORDERED),
+                                                      n -> StreamSupport.parallelStream(n::spliterator, Spliterator.SIZED | Spliterator.ORDERED),
+                                                      Node::spliterator,
+                                                      n -> (int) n.count());
+        }
+
+        // int factories
+        public static <T> OfInt ofArray(String name, int[] array) {
+            return new AbstractTestData.IntTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(),
+                                                      Arrays::spliterator, a -> a.length);
+        }
+
+        public static OfInt ofSpinedBuffer(String name, SpinedBuffer.OfInt buffer) {
+            return new AbstractTestData.IntTestData<>(name, buffer,
+                                                      b -> StreamSupport.intStream(b.spliterator()),
+                                                      b -> StreamSupport.intParallelStream(b.spliterator()),
+                                                      SpinedBuffer.OfInt::spliterator,
+                                                      b -> (int) b.count());
+        }
+
+        public static OfInt ofIntSupplier(String name, Supplier<IntStream> supplier) {
+            return new AbstractTestData.IntTestData<>(name, supplier,
+                                                      Supplier::get,
+                                                      s -> s.get().parallel(),
+                                                      s -> s.get().spliterator(),
+                                                      s -> (int) s.get().spliterator().getExactSizeIfKnown());
+        }
+
+        public static OfInt ofNode(String name, Node.OfInt node) {
+            int characteristics = Spliterator.SIZED | Spliterator.ORDERED;
+            return new AbstractTestData.IntTestData<>(name, node,
+                                                      n -> StreamSupport.intStream(n::spliterator, characteristics),
+                                                      n -> StreamSupport.intParallelStream(n::spliterator, characteristics),
+                                                      Node.OfInt::spliterator,
+                                                      n -> (int) n.count());
+        }
+
+        // long factories
+        public static <T> OfLong ofArray(String name, long[] array) {
+            return new AbstractTestData.LongTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(),
+                                                       Arrays::spliterator, a -> a.length);
+        }
+
+        public static OfLong ofSpinedBuffer(String name, SpinedBuffer.OfLong buffer) {
+            return new AbstractTestData.LongTestData<>(name, buffer,
+                                                      b -> StreamSupport.longStream(b.spliterator()),
+                                                      b -> StreamSupport.longParallelStream(b.spliterator()),
+                                                      SpinedBuffer.OfLong::spliterator,
+                                                      b -> (int) b.count());
+        }
+
+        public static OfLong ofLongSupplier(String name, Supplier<LongStream> supplier) {
+            return new AbstractTestData.LongTestData<>(name, supplier,
+                                                      Supplier::get,
+                                                      s -> s.get().parallel(),
+                                                      s -> s.get().spliterator(),
+                                                      s -> (int) s.get().spliterator().getExactSizeIfKnown());
+        }
+
+        public static OfLong ofNode(String name, Node.OfLong node) {
+            int characteristics = Spliterator.SIZED | Spliterator.ORDERED;
+            return new AbstractTestData.LongTestData<>(name, node,
+                                                      n -> StreamSupport.longStream(n::spliterator, characteristics),
+                                                      n -> StreamSupport.longParallelStream(n::spliterator, characteristics),
+                                                      Node.OfLong::spliterator,
+                                                      n -> (int) n.count());
+        }
+
+        // double factories
+        public static <T> OfDouble ofArray(String name, double[] array) {
+            return new AbstractTestData.DoubleTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(),
+                                                         Arrays::spliterator, a -> a.length);
+        }
+
+        public static OfDouble ofSpinedBuffer(String name, SpinedBuffer.OfDouble buffer) {
+            return new AbstractTestData.DoubleTestData<>(name, buffer,
+                                                         b -> StreamSupport.doubleStream(b.spliterator()),
+                                                         b -> StreamSupport.doubleParallelStream(b.spliterator()),
+                                                         SpinedBuffer.OfDouble::spliterator,
+                                                         b -> (int) b.count());
+        }
+
+        public static OfDouble ofDoubleSupplier(String name, Supplier<DoubleStream> supplier) {
+            return new AbstractTestData.DoubleTestData<>(name, supplier,
+                                                         Supplier::get,
+                                                         s -> s.get().parallel(),
+                                                         s -> s.get().spliterator(),
+                                                         s -> (int) s.get().spliterator().getExactSizeIfKnown());
+        }
+
+        public static OfDouble ofNode(String name, Node.OfDouble node) {
+            int characteristics = Spliterator.SIZED | Spliterator.ORDERED;
+            return new AbstractTestData.DoubleTestData<>(name, node,
+                                                         n -> StreamSupport.doubleStream(n::spliterator, characteristics),
+                                                         n -> StreamSupport.doubleParallelStream(n::spliterator, characteristics),
+                                                         Node.OfDouble::spliterator,
+                                                         n -> (int) n.count());
+        }
+    }
+
+
+    abstract class AbstractTestData<T, S extends BaseStream<T, S>,
+            T_STATE,
+                                    T_SPLITR extends Spliterator<T>>
+            implements TestData<T, S> {
+        private final String name;
+        private final StreamShape shape;
+        protected final T_STATE state;
+        private final ToIntFunction<T_STATE> sizeFn;
+        private final Function<T_STATE, S> streamFn;
+        private final Function<T_STATE, S> parStreamFn;
+        private final Function<T_STATE, T_SPLITR> splitrFn;
+
+        AbstractTestData(String name,
+                         StreamShape shape,
+                         T_STATE state,
+                         Function<T_STATE, S> streamFn,
+                         Function<T_STATE, S> parStreamFn,
+                         Function<T_STATE, T_SPLITR> splitrFn,
+                         ToIntFunction<T_STATE> sizeFn) {
+            this.name = name;
+            this.shape = shape;
+            this.state = state;
+            this.streamFn = streamFn;
+            this.parStreamFn = parStreamFn;
+            this.splitrFn = splitrFn;
+            this.sizeFn = sizeFn;
+        }
+
+        @Override
+        public StreamShape getShape() {
+            return shape;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getSimpleName() + "[" + name + "]";
+        }
+
+        @Override
+        public int size() {
+            return sizeFn.applyAsInt(state);
+        }
+
+        @Override
+        public T_SPLITR spliterator() {
+            return splitrFn.apply(state);
+        }
+
+        @Override
+        public S stream() {
+            return streamFn.apply(state);
+        }
+
+        @Override
+        public S parallelStream() {
+            return parStreamFn.apply(state);
+        }
+
+        public static class RefTestData<T, I>
+                extends AbstractTestData<T, Stream<T>, I, Spliterator<T>>
+                implements TestData.OfRef<T> {
+
+            protected RefTestData(String name,
+                                  I state,
+                                  Function<I, Stream<T>> streamFn,
+                                  Function<I, Stream<T>> parStreamFn,
+                                  Function<I, Spliterator<T>> splitrFn,
+                                  ToIntFunction<I> sizeFn) {
+                super(name, StreamShape.REFERENCE, state, streamFn, parStreamFn, splitrFn, sizeFn);
+            }
+
+        }
+
+        static class IntTestData<I>
+                extends AbstractTestData<Integer, IntStream, I, Spliterator.OfInt>
+                implements TestData.OfInt {
+
+            protected IntTestData(String name,
+                                  I state,
+                                  Function<I, IntStream> streamFn,
+                                  Function<I, IntStream> parStreamFn,
+                                  Function<I, Spliterator.OfInt> splitrFn,
+                                  ToIntFunction<I> sizeFn) {
+                super(name, StreamShape.INT_VALUE, state, streamFn, parStreamFn, splitrFn, sizeFn);
+            }
+
+            @Override
+            public PrimitiveIterator.OfInt iterator() {
+                return Spliterators.iteratorFromSpliterator(spliterator());
+            }
+
+            @Override
+            public <A extends Collection<? super Integer>> A into(A target) {
+                spliterator().forEachRemaining((IntConsumer) target::add);
+                return target;
+            }
+        }
+
+        static class LongTestData<I>
+                extends AbstractTestData<Long, LongStream, I, Spliterator.OfLong>
+                implements TestData.OfLong {
+
+            protected LongTestData(String name,
+                                   I state,
+                                   Function<I, LongStream> streamFn,
+                                   Function<I, LongStream> parStreamFn,
+                                   Function<I, Spliterator.OfLong> splitrFn,
+                                   ToIntFunction<I> sizeFn) {
+                super(name, StreamShape.LONG_VALUE, state, streamFn, parStreamFn, splitrFn, sizeFn);
+            }
+
+            @Override
+            public PrimitiveIterator.OfLong iterator() {
+                return Spliterators.iteratorFromSpliterator(spliterator());
+            }
+
+            @Override
+            public <A extends Collection<? super Long>> A into(A target) {
+                spliterator().forEachRemaining((LongConsumer) target::add);
+                return target;
+            }
+        }
+
+        static class DoubleTestData<I>
+                extends AbstractTestData<Double, DoubleStream, I, Spliterator.OfDouble>
+                implements OfDouble {
+
+            protected DoubleTestData(String name,
+                                     I state,
+                                     Function<I, DoubleStream> streamFn,
+                                     Function<I, DoubleStream> parStreamFn,
+                                     Function<I, Spliterator.OfDouble> splitrFn,
+                                     ToIntFunction<I> sizeFn) {
+                super(name, StreamShape.DOUBLE_VALUE, state, streamFn, parStreamFn, splitrFn, sizeFn);
+            }
+
+            @Override
+            public PrimitiveIterator.OfDouble iterator() {
+                return Spliterators.iteratorFromSpliterator(spliterator());
+            }
+
+            @Override
+            public <A extends Collection<? super Double>> A into(A target) {
+                spliterator().forEachRemaining((DoubleConsumer) target::add);
+                return target;
+            }
+        }
+    }
+}
diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/TestFlagExpectedOp.java b/jdk/test/java/util/stream/bootlib/java/util/stream/TestFlagExpectedOp.java
new file mode 100644
index 0000000..c59a185
--- /dev/null
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/TestFlagExpectedOp.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import org.testng.Assert;
+
+import java.util.EnumSet;
+
+class TestFlagExpectedOp<T> extends FlagDeclaringOp<T> {
+
+    static class Builder<T> {
+        final int flags;
+        StreamShape shape = StreamShape.REFERENCE;
+
+        EnumSet<StreamOpFlag> known = EnumSet.noneOf(StreamOpFlag.class);
+        EnumSet<StreamOpFlag> preserve = EnumSet.noneOf(StreamOpFlag.class);
+        EnumSet<StreamOpFlag> notKnown = EnumSet.noneOf(StreamOpFlag.class);
+
+        Builder(int flags) {
+            this.flags = flags;
+        }
+
+        Builder<T> known(EnumSet<StreamOpFlag> known) {
+            this.known = known;
+            return this;
+        }
+
+        Builder<T> preserve(EnumSet<StreamOpFlag> preserve) {
+            this.preserve = preserve;
+            return this;
+        }
+
+        Builder<T> notKnown(EnumSet<StreamOpFlag> notKnown) {
+            this.notKnown = notKnown;
+            return this;
+        }
+
+        Builder<T> shape(StreamShape shape) {
+            this.shape = shape;
+            return this;
+        }
+
+        TestFlagExpectedOp<T> build() {
+            return new TestFlagExpectedOp<>(flags, known, preserve, notKnown, shape);
+        }
+    }
+
+    final EnumSet<StreamOpFlag> known;
+    final EnumSet<StreamOpFlag> preserve;
+    final EnumSet<StreamOpFlag> notKnown;
+    final StreamShape shape;
+
+    TestFlagExpectedOp(int flags,
+                       EnumSet<StreamOpFlag> known,
+                       EnumSet<StreamOpFlag> preserve,
+                       EnumSet<StreamOpFlag> notKnown) {
+        this(flags, known, preserve, notKnown, StreamShape.REFERENCE);
+    }
+
+    TestFlagExpectedOp(int flags,
+                       EnumSet<StreamOpFlag> known,
+                       EnumSet<StreamOpFlag> preserve,
+                       EnumSet<StreamOpFlag> notKnown,
+                       StreamShape shape) {
+        super(flags);
+        this.known = known;
+        this.preserve = preserve;
+        this.notKnown = notKnown;
+        this.shape = shape;
+    }
+
+    @Override
+    public StreamShape outputShape() {
+        return shape;
+    }
+
+    @Override
+    public StreamShape inputShape() {
+        return shape;
+    }
+
+    @Override
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public Sink<T> opWrapSink(int flags, boolean parallel, Sink upstream) {
+        assertFlags(flags);
+        return upstream;
+    }
+
+    private void assertFlags(int flags) {
+        for (StreamOpFlag f : known) {
+            Assert.assertTrue(f.isKnown(flags),
+                              String.format("Flag %s is not known, but should be known.", f.toString()));
+        }
+
+        for (StreamOpFlag f : preserve) {
+            Assert.assertTrue(f.isPreserved(flags),
+                              String.format("Flag %s is not preserved, but should be preserved.", f.toString()));
+        }
+
+        for (StreamOpFlag f : notKnown) {
+            Assert.assertFalse(f.isKnown(flags),
+                               String.format("Flag %s is known, but should be not known.", f.toString()));
+        }
+    }
+}
diff --git a/jdk/test/java/util/stream/boottest/TEST.properties b/jdk/test/java/util/stream/boottest/TEST.properties
new file mode 100644
index 0000000..d51ddf7
--- /dev/null
+++ b/jdk/test/java/util/stream/boottest/TEST.properties
@@ -0,0 +1,5 @@
+# This file identifies root(s) of the test-ng hierarchy.
+
+TestNG.dirs = .
+bootclasspath.dirs = .
+lib.dirs = /java/util/stream/bootlib
diff --git a/jdk/test/java/util/stream/boottest/java/util/stream/DoubleNodeTest.java b/jdk/test/java/util/stream/boottest/java/util/stream/DoubleNodeTest.java
new file mode 100644
index 0000000..7ad4801
--- /dev/null
+++ b/jdk/test/java/util/stream/boottest/java/util/stream/DoubleNodeTest.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.PrimitiveIterator;
+import java.util.Spliterators;
+import java.util.function.Function;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+@Test
+public class DoubleNodeTest extends OpTestCase {
+
+    @DataProvider(name = "nodes")
+    public Object[][] createSizes() {
+        List<Object[]> params = new ArrayList<>();
+
+        for (int size : Arrays.asList(0, 1, 4, 15, 16, 17, 127, 128, 129, 1000)) {
+            double[] array = new double[size];
+            for (int i = 0; i < array.length; i++) {
+                array[i] = i;
+            }
+
+            List<Node<Double>> nodes = new ArrayList<>();
+
+            nodes.add(Nodes.node(array));
+            nodes.add(degenerateTree(Spliterators.iteratorFromSpliterator(Arrays.spliterator(array))));
+            nodes.add(tree(toList(array), l -> Nodes.node(toDoubleArray(l))));
+            nodes.add(fill(array, Nodes.doubleBuilder(array.length)));
+            nodes.add(fill(array, Nodes.doubleBuilder()));
+
+            for (Node<Double> node : nodes) {
+                params.add(new Object[]{array, node});
+            }
+
+        }
+
+        return params.toArray(new Object[0][]);
+    }
+
+    private static void assertEqualsListDoubleArray(List<Double> list, double[] array) {
+        assertEquals(list.size(), array.length);
+        for (int i = 0; i < array.length; i++)
+            assertEquals(array[i], list.get(i));
+    }
+
+    private List<Double> toList(double[] a) {
+        List<Double> l = new ArrayList<>();
+        for (double i : a) {
+            l.add(i);
+        }
+
+        return l;
+    }
+
+    private double[] toDoubleArray(List<Double> l) {
+        double[] a = new double[l.size()];
+
+        int i = 0;
+        for (Double e : l) {
+            a[i++] = e;
+        }
+        return a;
+    }
+
+    private Node.OfDouble fill(double[] array, Node.Builder.OfDouble nb) {
+        nb.begin(array.length);
+        for (double i : array)
+            nb.accept(i);
+        nb.end();
+        return nb.build();
+    }
+
+    private Node.OfDouble degenerateTree(PrimitiveIterator.OfDouble it) {
+        if (!it.hasNext()) {
+            return Nodes.node(new double[0]);
+        }
+
+        double i = it.nextDouble();
+        if (it.hasNext()) {
+            return new Nodes.DoubleConcNode(Nodes.node(new double[] {i}), degenerateTree(it));
+        }
+        else {
+            return Nodes.node(new double[] {i});
+        }
+    }
+
+    private Node.OfDouble tree(List<Double> l, Function<List<Double>, Node.OfDouble> m) {
+        if (l.size() < 3) {
+            return m.apply(l);
+        }
+        else {
+            return new Nodes.DoubleConcNode(
+                    tree(l.subList(0, l.size() / 2), m),
+                    tree(l.subList(l.size() / 2, l.size()), m));
+        }
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testAsArray(double[] array, Node.OfDouble n) {
+        assertEquals(n.asDoubleArray(), array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testFlattenAsArray(double[] array, Node.OfDouble n) {
+        assertEquals(Nodes.flattenDouble(n).asDoubleArray(), array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testCopyTo(double[] array, Node.OfDouble n) {
+        double[] copy = new double[(int) n.count()];
+        n.copyInto(copy, 0);
+
+        assertEquals(copy, array);
+    }
+
+    @Test(dataProvider = "nodes", groups = { "serialization-hostile" })
+    public void testForEach(double[] array, Node.OfDouble n) {
+        List<Double> l = new ArrayList<>((int) n.count());
+        n.forEach((double e) -> {
+            l.add(e);
+        });
+
+        assertEqualsListDoubleArray(l, array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testStreams(double[] array, Node.OfDouble n) {
+        TestData.OfDouble data = TestData.Factory.ofNode("Node", n);
+
+        exerciseOps(data, s -> s);
+
+        exerciseTerminalOps(data, s -> s.toArray());
+    }
+
+    @Test(dataProvider = "nodes", groups={ "serialization-hostile" })
+    // throws SOE on serialization of DoubleConcNode[size=1000]
+    public void testSpliterator(double[] array, Node.OfDouble n) {
+        SpliteratorTestHelper.testDoubleSpliterator(n::spliterator);
+    }
+}
diff --git a/jdk/test/java/util/stream/boottest/java/util/stream/FlagOpTest.java b/jdk/test/java/util/stream/boottest/java/util/stream/FlagOpTest.java
new file mode 100644
index 0000000..602d51f
--- /dev/null
+++ b/jdk/test/java/util/stream/boottest/java/util/stream/FlagOpTest.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.function.Supplier;
+
+import static java.util.stream.LambdaTestHelpers.countTo;
+
+@Test
+public class FlagOpTest extends OpTestCase {
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testFlagsPassThrough(String name, TestData<Integer, Stream<Integer>> data) {
+
+        @SuppressWarnings({"unchecked", "rawtypes"})
+        TestFlagPassThroughOp<Integer>[] ops = new TestFlagPassThroughOp[3];
+        ops[0] = new TestFlagPassThroughOp<>();
+        ops[1] = new TestFlagPassThroughOp<>();
+        ops[2] = new TestFlagPassThroughOp<>();
+
+        ops[0].set(null, ops[1]);
+        ops[1].set(ops[0], ops[2]);
+        ops[2].set(ops[1], null);
+
+        withData(data).ops(ops).exercise();
+    }
+
+    static class TestFlagPassThroughOp<T> extends FlagDeclaringOp<T> {
+        TestFlagPassThroughOp<T> upstream;
+        TestFlagPassThroughOp<T> downstream;
+
+        TestFlagPassThroughOp() {
+            super(0);
+        }
+
+        void set(TestFlagPassThroughOp<T> upstream, TestFlagPassThroughOp<T> downstream)  {
+            this.upstream = upstream;
+            this.downstream = downstream;
+        }
+
+        int wrapFlags;
+
+        @Override
+        @SuppressWarnings({"unchecked", "rawtypes"})
+        public Sink<T> opWrapSink(int flags, boolean parallel, Sink sink) {
+            this.wrapFlags = flags;
+
+            if (downstream != null) {
+                assertTrue(flags == downstream.wrapFlags);
+            }
+
+            return sink;
+        }
+    }
+
+    public void testFlagsClearAllSet() {
+        int clearAllFlags = 0;
+        for (StreamOpFlag f : EnumSet.allOf(StreamOpFlag.class)) {
+            if (f.isStreamFlag()) {
+                clearAllFlags |= f.clear();
+            }
+        }
+
+        EnumSet<StreamOpFlag> known = EnumSet.noneOf(StreamOpFlag.class);
+        EnumSet<StreamOpFlag> notKnown = StreamOpFlagTestHelper.allStreamFlags();
+
+        List<FlagDeclaringOp<Integer>> ops = new ArrayList<>();
+        ops.add(new FlagDeclaringOp<>(clearAllFlags));
+        for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
+            if (f.canSet(StreamOpFlag.Type.OP)) {
+                ops.add(new TestFlagExpectedOp<>(f.set(),
+                                             known.clone(),
+                                             EnumSet.noneOf(StreamOpFlag.class),
+                                             notKnown.clone()));
+                known.add(f);
+                notKnown.remove(f);
+            }
+        }
+        ops.add(new TestFlagExpectedOp<>(0,
+                                         known.clone(),
+                                         EnumSet.noneOf(StreamOpFlag.class),
+                                         notKnown.clone()));
+
+        TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
+        @SuppressWarnings("rawtypes")
+        FlagDeclaringOp[] opsArray = ops.toArray(new FlagDeclaringOp[ops.size()]);
+
+        withData(data).ops(opsArray).
+                without(StreamTestScenario.PAR_STREAM_TO_ARRAY_CLEAR_SIZED).
+                exercise();
+    }
+
+    public void testFlagsSetAllClear() {
+        EnumSet<StreamOpFlag> known = StreamOpFlagTestHelper.allStreamFlags();
+        int setAllFlags = 0;
+        for (StreamOpFlag f : EnumSet.allOf(StreamOpFlag.class)) {
+            if (f.isStreamFlag()) {
+                if (f.canSet(StreamOpFlag.Type.OP)) {
+                    setAllFlags |= f.set();
+                } else {
+                    known.remove(f);
+                }
+            }
+        }
+
+        EnumSet<StreamOpFlag> notKnown = EnumSet.noneOf(StreamOpFlag.class);
+
+        List<FlagDeclaringOp<Integer>> ops = new ArrayList<>();
+        ops.add(new FlagDeclaringOp<>(setAllFlags));
+        for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
+            ops.add(new TestFlagExpectedOp<>(f.clear(),
+                                             known.clone(),
+                                             EnumSet.noneOf(StreamOpFlag.class),
+                                             notKnown.clone()));
+            known.remove(f);
+            notKnown.add(f);
+        }
+        ops.add(new TestFlagExpectedOp<>(0,
+                                         known.clone(),
+                                         EnumSet.noneOf(StreamOpFlag.class),
+                                         notKnown.clone()));
+
+        TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
+        @SuppressWarnings("rawtypes")
+        FlagDeclaringOp[] opsArray = ops.toArray(new FlagDeclaringOp[ops.size()]);
+
+
+        withData(data).ops(opsArray).
+                without(StreamTestScenario.PAR_STREAM_TO_ARRAY_CLEAR_SIZED).
+                exercise();
+    }
+
+    public void testFlagsParallelCollect() {
+        testFlagsSetSequence(CollectorOps::collector);
+    }
+
+    private void testFlagsSetSequence(Supplier<StatefulTestOp<Integer>> cf) {
+        EnumSet<StreamOpFlag> known = EnumSet.of(StreamOpFlag.ORDERED, StreamOpFlag.SIZED);
+        EnumSet<StreamOpFlag> preserve = EnumSet.of(StreamOpFlag.DISTINCT, StreamOpFlag.SORTED);
+
+        List<IntermediateTestOp<Integer, Integer>> ops = new ArrayList<>();
+        for (StreamOpFlag f : EnumSet.of(StreamOpFlag.DISTINCT, StreamOpFlag.SORTED)) {
+            ops.add(cf.get());
+            ops.add(new TestFlagExpectedOp<>(f.set(),
+                                             known.clone(),
+                                             preserve.clone(),
+                                             EnumSet.noneOf(StreamOpFlag.class)));
+            known.add(f);
+            preserve.remove(f);
+        }
+        ops.add(cf.get());
+        ops.add(new TestFlagExpectedOp<>(0,
+                                         known.clone(),
+                                         preserve.clone(),
+                                         EnumSet.noneOf(StreamOpFlag.class)));
+
+        TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
+        @SuppressWarnings("rawtypes")
+        IntermediateTestOp[] opsArray = ops.toArray(new IntermediateTestOp[ops.size()]);
+
+        withData(data).ops(opsArray).
+                without(StreamTestScenario.PAR_STREAM_TO_ARRAY_CLEAR_SIZED).
+                exercise();
+    }
+
+
+    public void testFlagsClearParallelCollect() {
+        testFlagsClearSequence(CollectorOps::collector);
+    }
+
+    protected void testFlagsClearSequence(Supplier<StatefulTestOp<Integer>> cf) {
+        EnumSet<StreamOpFlag> known = EnumSet.of(StreamOpFlag.ORDERED, StreamOpFlag.SIZED);
+        EnumSet<StreamOpFlag> preserve = EnumSet.of(StreamOpFlag.DISTINCT, StreamOpFlag.SORTED);
+        EnumSet<StreamOpFlag> notKnown = EnumSet.noneOf(StreamOpFlag.class);
+
+        List<IntermediateTestOp<Integer, Integer>> ops = new ArrayList<>();
+        for (StreamOpFlag f : EnumSet.of(StreamOpFlag.ORDERED, StreamOpFlag.DISTINCT, StreamOpFlag.SORTED)) {
+            ops.add(cf.get());
+            ops.add(new TestFlagExpectedOp<>(f.clear(),
+                                             known.clone(),
+                                             preserve.clone(),
+                                             notKnown.clone()));
+            known.remove(f);
+            preserve.remove(f);
+            notKnown.add(f);
+        }
+        ops.add(cf.get());
+        ops.add(new TestFlagExpectedOp<>(0,
+                                         known.clone(),
+                                         preserve.clone(),
+                                         notKnown.clone()));
+
+        TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
+        @SuppressWarnings("rawtypes")
+        IntermediateTestOp[] opsArray = ops.toArray(new IntermediateTestOp[ops.size()]);
+
+        withData(data).ops(opsArray).
+                without(StreamTestScenario.PAR_STREAM_TO_ARRAY_CLEAR_SIZED).
+                exercise();
+    }
+
+    public void testFlagsSizedOrderedParallelCollect() {
+        EnumSet<StreamOpFlag> parKnown = EnumSet.of(StreamOpFlag.SIZED);
+        EnumSet<StreamOpFlag> serKnown = parKnown.clone();
+
+        List<IntermediateTestOp<Integer, Integer>> ops = new ArrayList<>();
+        for (StreamOpFlag f : parKnown) {
+            ops.add(CollectorOps.collector());
+            ops.add(new ParSerTestFlagExpectedOp<>(f.clear(),
+                                             parKnown,
+                                             serKnown));
+            serKnown.remove(f);
+        }
+        ops.add(CollectorOps.collector());
+        ops.add(new ParSerTestFlagExpectedOp<>(0,
+                                         parKnown,
+                                         EnumSet.noneOf(StreamOpFlag.class)));
+
+        TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
+        @SuppressWarnings("rawtypes")
+        IntermediateTestOp[] opsArray = ops.toArray(new IntermediateTestOp[ops.size()]);
+
+        withData(data).ops(opsArray).exercise();
+    }
+
+    static class ParSerTestFlagExpectedOp<T> extends FlagDeclaringOp<T> {
+        final EnumSet<StreamOpFlag> parKnown;
+        final EnumSet<StreamOpFlag> serKnown;
+
+        ParSerTestFlagExpectedOp(int flags, EnumSet<StreamOpFlag> known, EnumSet<StreamOpFlag> serKnown) {
+            super(flags);
+            this.parKnown = known;
+            this.serKnown = serKnown;
+        }
+
+        @Override
+        @SuppressWarnings({"unchecked", "rawtypes"})
+        public Sink<T> opWrapSink(int flags, boolean parallel, Sink upstream) {
+            assertFlags(flags, parallel);
+            return upstream;
+        }
+
+        protected void assertFlags(int flags, boolean parallel) {
+            if (parallel) {
+                for (StreamOpFlag f : parKnown) {
+                    Assert.assertTrue(f.isKnown(flags), String.format("Flag %s is not known, but should be known.", f.toString()));
+                }
+
+            } else {
+                for (StreamOpFlag f : serKnown) {
+                    Assert.assertTrue(f.isKnown(flags), String.format("Flag %s is not known, but should be known.", f.toString()));
+                }
+
+            }
+        }
+    }
+}
diff --git a/jdk/test/java/util/stream/boottest/java/util/stream/IntNodeTest.java b/jdk/test/java/util/stream/boottest/java/util/stream/IntNodeTest.java
new file mode 100644
index 0000000..0d345ad
--- /dev/null
+++ b/jdk/test/java/util/stream/boottest/java/util/stream/IntNodeTest.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.PrimitiveIterator;
+import java.util.Spliterators;
+import java.util.function.Function;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+@Test
+public class IntNodeTest extends OpTestCase {
+
+    @DataProvider(name = "nodes")
+    public Object[][] createSizes() {
+        List<Object[]> params = new ArrayList<>();
+
+        for (int size : Arrays.asList(0, 1, 4, 15, 16, 17, 127, 128, 129, 1000)) {
+            int[] array = new int[size];
+            for (int i = 0; i < array.length; i++) {
+                array[i] = i;
+            }
+
+            List<Node<Integer>> nodes = new ArrayList<>();
+
+            nodes.add(Nodes.node(array));
+            nodes.add(degenerateTree(Spliterators.iteratorFromSpliterator(Arrays.spliterator(array))));
+            nodes.add(tree(toList(array), l -> Nodes.node(toIntArray(l))));
+            nodes.add(fill(array, Nodes.intBuilder(array.length)));
+            nodes.add(fill(array, Nodes.intBuilder()));
+
+            for (Node<Integer> node : nodes) {
+                params.add(new Object[]{array, node});
+            }
+
+        }
+
+        return params.toArray(new Object[0][]);
+    }
+
+    private static void assertEqualsListIntArray(List<Integer> list, int[] array) {
+        assertEquals(list.size(), array.length);
+        for (int i = 0; i < array.length; i++)
+            assertEquals(array[i], (int) list.get(i));
+    }
+
+    private List<Integer> toList(int[] a) {
+        List<Integer> l = new ArrayList<>();
+        for (int i : a) {
+            l.add(i);
+        }
+
+        return l;
+    }
+
+    private int[] toIntArray(List<Integer> l) {
+        int[] a = new int[l.size()];
+
+        int i = 0;
+        for (Integer e : l) {
+            a[i++] = e;
+        }
+        return a;
+    }
+
+    private Node.OfInt fill(int[] array, Node.Builder.OfInt nb) {
+        nb.begin(array.length);
+        for (int i : array)
+            nb.accept(i);
+        nb.end();
+        return nb.build();
+    }
+
+    private Node.OfInt degenerateTree(PrimitiveIterator.OfInt it) {
+        if (!it.hasNext()) {
+            return Nodes.node(new int[0]);
+        }
+
+        int i = it.nextInt();
+        if (it.hasNext()) {
+            return new Nodes.IntConcNode(Nodes.node(new int[] {i}), degenerateTree(it));
+        }
+        else {
+            return Nodes.node(new int[] {i});
+        }
+    }
+
+    private Node.OfInt tree(List<Integer> l, Function<List<Integer>, Node.OfInt> m) {
+        if (l.size() < 3) {
+            return m.apply(l);
+        }
+        else {
+            return new Nodes.IntConcNode(
+                    tree(l.subList(0, l.size() / 2), m),
+                    tree(l.subList(l.size() / 2, l.size()), m));
+        }
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testAsArray(int[] array, Node.OfInt n) {
+        assertEquals(n.asIntArray(), array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testFlattenAsArray(int[] array, Node.OfInt n) {
+        assertEquals(Nodes.flattenInt(n).asIntArray(), array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testCopyTo(int[] array, Node.OfInt n) {
+        int[] copy = new int[(int) n.count()];
+        n.copyInto(copy, 0);
+
+        assertEquals(copy, array);
+    }
+
+    @Test(dataProvider = "nodes", groups = { "serialization-hostile" })
+    public void testForEach(int[] array, Node.OfInt n) {
+        List<Integer> l = new ArrayList<>((int) n.count());
+        n.forEach((int e) -> {
+            l.add(e);
+        });
+
+        assertEqualsListIntArray(l, array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testStreams(int[] array, Node.OfInt n) {
+        TestData.OfInt data = TestData.Factory.ofNode("Node", n);
+
+        exerciseOps(data, s -> s);
+        exerciseTerminalOps(data, s -> s.toArray());
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testSpliterator(int[] array, Node.OfInt n) {
+        SpliteratorTestHelper.testIntSpliterator(n::spliterator);
+    }
+}
diff --git a/jdk/test/java/util/stream/boottest/java/util/stream/LongNodeTest.java b/jdk/test/java/util/stream/boottest/java/util/stream/LongNodeTest.java
new file mode 100644
index 0000000..0b101a0
--- /dev/null
+++ b/jdk/test/java/util/stream/boottest/java/util/stream/LongNodeTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.PrimitiveIterator;
+import java.util.Spliterators;
+import java.util.function.Function;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+@Test
+public class LongNodeTest extends OpTestCase {
+
+    @DataProvider(name = "nodes")
+    public Object[][] createSizes() {
+        List<Object[]> params = new ArrayList<>();
+
+        for (int size : Arrays.asList(0, 1, 4, 15, 16, 17, 127, 128, 129, 1000)) {
+            long[] array = new long[size];
+            for (int i = 0; i < array.length; i++) {
+                array[i] = i;
+            }
+
+            List<Node<Long>> nodes = new ArrayList<>();
+
+            nodes.add(Nodes.node(array));
+            nodes.add(degenerateTree(Spliterators.iteratorFromSpliterator(Arrays.spliterator(array))));
+            nodes.add(tree(toList(array), l -> Nodes.node(toLongArray(l))));
+            nodes.add(fill(array, Nodes.longBuilder(array.length)));
+            nodes.add(fill(array, Nodes.longBuilder()));
+
+            for (Node<Long> node : nodes) {
+                params.add(new Object[]{array, node});
+            }
+
+        }
+
+        return params.toArray(new Object[0][]);
+    }
+
+    private static void assertEqualsListLongArray(List<Long> list, long[] array) {
+        assertEquals(list.size(), array.length);
+        for (int i = 0; i < array.length; i++)
+            assertEquals(array[i], (long) list.get(i));
+    }
+
+    private List<Long> toList(long[] a) {
+        List<Long> l = new ArrayList<>();
+        for (long i : a) {
+            l.add(i);
+        }
+
+        return l;
+    }
+
+    private long[] toLongArray(List<Long> l) {
+        long[] a = new long[l.size()];
+
+        int i = 0;
+        for (Long e : l) {
+            a[i++] = e;
+        }
+        return a;
+    }
+
+    private Node.OfLong fill(long[] array, Node.Builder.OfLong nb) {
+        nb.begin(array.length);
+        for (long i : array)
+            nb.accept(i);
+        nb.end();
+        return nb.build();
+    }
+
+    private Node.OfLong degenerateTree(PrimitiveIterator.OfLong it) {
+        if (!it.hasNext()) {
+            return Nodes.node(new long[0]);
+        }
+
+        long i = it.nextLong();
+        if (it.hasNext()) {
+            return new Nodes.LongConcNode(Nodes.node(new long[] {i}), degenerateTree(it));
+        }
+        else {
+            return Nodes.node(new long[] {i});
+        }
+    }
+
+    private Node.OfLong tree(List<Long> l, Function<List<Long>, Node.OfLong> m) {
+        if (l.size() < 3) {
+            return m.apply(l);
+        }
+        else {
+            return new Nodes.LongConcNode(
+                    tree(l.subList(0, l.size() / 2), m),
+                    tree(l.subList(l.size() / 2, l.size()), m));
+        }
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testAsArray(long[] array, Node.OfLong n) {
+        assertEquals(n.asLongArray(), array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testFlattenAsArray(long[] array, Node.OfLong n) {
+        assertEquals(Nodes.flattenLong(n).asLongArray(), array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testCopyTo(long[] array, Node.OfLong n) {
+        long[] copy = new long[(int) n.count()];
+        n.copyInto(copy, 0);
+
+        assertEquals(copy, array);
+    }
+
+    @Test(dataProvider = "nodes", groups = { "serialization-hostile" })
+    public void testForEach(long[] array, Node.OfLong n) {
+        List<Long> l = new ArrayList<>((int) n.count());
+        n.forEach((long e) -> {
+            l.add(e);
+        });
+
+        assertEqualsListLongArray(l, array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testStreams(long[] array, Node.OfLong n) {
+        TestData.OfLong data = TestData.Factory.ofNode("Node", n);
+
+        exerciseOps(data, s -> s);
+
+        exerciseTerminalOps(data, s -> s.toArray());
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testSpliterator(long[] array, Node.OfLong n) {
+        SpliteratorTestHelper.testLongSpliterator(n::spliterator);
+    }
+}
diff --git a/jdk/test/java/util/stream/boottest/java/util/stream/NodeBuilderTest.java b/jdk/test/java/util/stream/boottest/java/util/stream/NodeBuilderTest.java
new file mode 100644
index 0000000..11fe86f
--- /dev/null
+++ b/jdk/test/java/util/stream/boottest/java/util/stream/NodeBuilderTest.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.DoubleConsumer;
+import java.util.function.Function;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static java.util.stream.LambdaTestHelpers.assertContents;
+import static java.util.stream.LambdaTestHelpers.countTo;
+import static org.testng.Assert.assertEquals;
+
+@Test
+public class NodeBuilderTest {
+
+    List<Integer> sizes = Arrays.asList(0, 1, 4, 16, 256,
+                                        1023, 1024, 1025,
+                                        2047, 2048, 2049,
+                                        1024 * 32 - 1, 1024 * 32, 1024 * 32 + 1);
+
+    @DataProvider(name = "Node.Builder")
+    public Object[][] createNodeBuilders() {
+        List<List<Integer>> ls = new ArrayList<>();
+        for (int size : sizes) {
+            ls.add(countTo(size));
+        }
+
+        List<Function<Integer, Node.Builder<Integer>>> ms = Arrays.asList(
+                s -> Nodes.builder(),
+                s -> Nodes.builder(s, LambdaTestHelpers.integerArrayGenerator)
+        );
+
+        Object[][] params = new Object[ls.size() * ms.size()][];
+        int i = 0;
+        for (List<Integer> l : ls) {
+            for (Function<Integer, Node.Builder<Integer>> m : ms) {
+                params[i++] = new Object[]{l, m};
+            }
+        }
+
+        return params;
+    }
+
+    @Test(dataProvider = "Node.Builder", groups = { "serialization-hostile" })
+    public void testIteration(List<Integer> l, Function<Integer, Node.Builder<Integer>> m) {
+        Node.Builder<Integer> nb = m.apply(l.size());
+        nb.begin(l.size());
+        for (Integer i : l) {
+            nb.accept(i);
+        }
+        nb.end();
+
+        Node<Integer> n = nb.build();
+        assertEquals(n.count(), l.size());
+
+        {
+            List<Integer> _l = new ArrayList<>();
+            n.forEach(_l::add);
+
+            assertContents(_l, l);
+        }
+    }
+
+    // Node.Builder.OfInt
+
+    @DataProvider(name = "Node.Builder<Integer>")
+    public Object[][] createIntNodeBuilders() {
+        List<List<Integer>> ls = new ArrayList<>();
+        for (int size : sizes) {
+            ls.add(countTo(size));
+        }
+
+        List<Function<Integer, Node.Builder<Integer>>> ms = Arrays.asList(
+                s -> Nodes.intBuilder(),
+                s -> Nodes.intBuilder(s)
+        );
+
+        Object[][] params = new Object[ls.size() * ms.size()][];
+        int i = 0;
+        for (List<Integer> l : ls) {
+            for (Function<Integer, Node.Builder<Integer>> m : ms) {
+                params[i++] = new Object[]{l, m};
+            }
+        }
+
+        return params;
+    }
+
+    @Test(dataProvider = "Node.Builder<Integer>", groups = { "serialization-hostile" })
+    public void testIntIteration(List<Integer> l, Function<Integer, Node.Builder.OfInt> m) {
+        Node.Builder.OfInt nb = m.apply(l.size());
+        nb.begin(l.size());
+        for (Integer i : l) {
+            nb.accept((int) i);
+        }
+        nb.end();
+
+        Node.OfInt n = nb.build();
+        assertEquals(n.count(), l.size());
+
+        {
+            List<Integer> _l = new ArrayList<>();
+            n.forEach((IntConsumer) _l::add);
+
+            assertContents(_l, l);
+        }
+
+    }
+
+    // Node.Builder.OfLong
+
+    @DataProvider(name = "Node.Builder<Long>")
+    public Object[][] createLongNodeBuilders() {
+        List<List<Long>> ls = new ArrayList<>();
+        for (int size : sizes) {
+            List<Long> l = new ArrayList<>();
+            for (long i = 0; i < size; i++) {
+                l.add(i);
+            }
+            ls.add(l);
+        }
+
+        List<Function<Integer, Node.Builder<Long>>> ms = Arrays.asList(
+                s -> Nodes.longBuilder(),
+                s -> Nodes.longBuilder(s)
+        );
+
+        Object[][] params = new Object[ls.size() * ms.size()][];
+        int i = 0;
+        for (List<Long> l : ls) {
+            for (Function<Integer, Node.Builder<Long>> m : ms) {
+                params[i++] = new Object[]{l, m};
+            }
+        }
+
+        return params;
+    }
+
+    @Test(dataProvider = "Node.Builder<Long>")
+    public void testLongIteration(List<Long> l, Function<Integer, Node.Builder.OfLong> m) {
+        Node.Builder.OfLong nb = m.apply(l.size());
+        nb.begin(l.size());
+        for (Long i : l) {
+            nb.accept((long) i);
+        }
+        nb.end();
+
+        Node.OfLong n = nb.build();
+        assertEquals(n.count(), l.size());
+
+        {
+            List<Long> _l = new ArrayList<>();
+            n.forEach((LongConsumer) _l::add);
+
+            assertContents(_l, l);
+        }
+
+    }
+
+    // Node.Builder.OfDouble
+
+    @DataProvider(name = "Node.Builder<Double>")
+    public Object[][] createDoubleNodeBuilders() {
+        List<List<Double>> ls = new ArrayList<>();
+        for (int size : sizes) {
+            List<Double> l = new ArrayList<>();
+            for (long i = 0; i < size; i++) {
+                l.add((double) i);
+            }
+            ls.add(l);
+        }
+
+        List<Function<Integer, Node.Builder<Double>>> ms = Arrays.asList(
+                s -> Nodes.doubleBuilder(),
+                s -> Nodes.doubleBuilder(s)
+        );
+
+        Object[][] params = new Object[ls.size() * ms.size()][];
+        int i = 0;
+        for (List<Double> l : ls) {
+            for (Function<Integer, Node.Builder<Double>> m : ms) {
+                params[i++] = new Object[]{l, m};
+            }
+        }
+
+        return params;
+    }
+
+    @Test(dataProvider = "Node.Builder<Double>")
+    public void testDoubleIteration(List<Double> l, Function<Integer, Node.Builder.OfDouble> m) {
+        Node.Builder.OfDouble nb = m.apply(l.size());
+        nb.begin(l.size());
+        for (Double i : l) {
+            nb.accept((double) i);
+        }
+        nb.end();
+
+        Node.OfDouble n = nb.build();
+        assertEquals(n.count(), l.size());
+
+        {
+            List<Double> _l = new ArrayList<>();
+            n.forEach((DoubleConsumer) _l::add);
+
+            assertContents(_l, l);
+        }
+
+    }
+}
diff --git a/jdk/test/java/util/stream/boottest/java/util/stream/NodeTest.java b/jdk/test/java/util/stream/boottest/java/util/stream/NodeTest.java
new file mode 100644
index 0000000..8f5bff5
--- /dev/null
+++ b/jdk/test/java/util/stream/boottest/java/util/stream/NodeTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Function;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+@Test
+public class NodeTest extends OpTestCase {
+
+    @DataProvider(name = "nodes")
+    public Object[][] createSizes() {
+        List<Object[]> params = new ArrayList<>();
+
+        for (int size : Arrays.asList(0, 1, 4, 15, 16, 17, 127, 128, 129, 1000)) {
+            Integer[] array = new Integer[size];
+            for (int i = 0; i < array.length; i++) {
+                array[i] = i;
+            }
+
+            List<Node<Integer>> nodes = new ArrayList<>();
+            nodes.add(Nodes.node(array));
+            nodes.add(Nodes.node(Arrays.asList(array)));
+            nodes.add(degenerateTree(Arrays.asList(array).iterator()));
+            nodes.add(tree(Arrays.asList(array), l -> Nodes.node(l.toArray(new Integer[l.size()]))));
+            nodes.add(tree(Arrays.asList(array), l -> Nodes.node(l)));
+            nodes.add(fill(array, Nodes.builder(array.length, LambdaTestHelpers.integerArrayGenerator)));
+            nodes.add(fill(array, Nodes.builder()));
+
+            for (int i = 0; i < nodes.size(); i++) {
+                params.add(new Object[]{array, nodes.get(i)});
+            }
+
+        }
+
+        return params.toArray(new Object[0][]);
+    }
+
+    Node<Integer> fill(Integer[] array, Node.Builder<Integer> nb) {
+        nb.begin(array.length);
+        for (Integer i : array) {
+            nb.accept(i);
+        }
+        nb.end();
+        return nb.build();
+    }
+
+    Node<Integer> degenerateTree(Iterator<Integer> it) {
+        if (!it.hasNext()) {
+            return Nodes.node(Collections.emptyList());
+        }
+
+        Integer i = it.next();
+        if (it.hasNext()) {
+            return new Nodes.ConcNode<Integer>(Nodes.node(new Integer[] {i}), degenerateTree(it));
+        }
+        else {
+            return Nodes.node(new Integer[]{i});
+        }
+    }
+
+    Node<Integer> tree(List<Integer> l, Function<List<Integer>, Node<Integer>> m) {
+        if (l.size() < 3) {
+            return m.apply(l);
+        }
+        else {
+            return new Nodes.ConcNode<>(
+                    tree(l.subList(0, l.size() / 2), m),
+                    tree(l.subList(l.size() / 2, l.size()), m ));
+        }
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testAsArray(Integer[] array, Node<Integer> n) {
+        assertEquals(n.asArray(LambdaTestHelpers.integerArrayGenerator), array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testFlattenAsArray(Integer[] array, Node<Integer> n) {
+        assertEquals(Nodes.flatten(n, LambdaTestHelpers.integerArrayGenerator)
+                          .asArray(LambdaTestHelpers.integerArrayGenerator), array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testCopyTo(Integer[] array, Node<Integer> n) {
+        Integer[] copy = new Integer[(int) n.count()];
+        n.copyInto(copy, 0);
+
+        assertEquals(copy, array);
+    }
+
+    @Test(dataProvider = "nodes", groups = { "serialization-hostile" })
+    public void testForEach(Integer[] array, Node<Integer> n) {
+        List<Integer> l = new ArrayList<>((int) n.count());
+        n.forEach(e -> l.add(e));
+
+        assertEquals(l.toArray(), array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testStreams(Integer[] array, Node<Integer> n) {
+        TestData<Integer, Stream<Integer>> data = TestData.Factory.ofRefNode("Node", n);
+
+        exerciseOps(data, s -> s);
+
+        exerciseTerminalOps(data, s -> s.toArray());
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testSpliterator(Integer[] array, Node<Integer> n) {
+        SpliteratorTestHelper.testSpliterator(n::spliterator);
+    }
+}
diff --git a/jdk/test/java/util/stream/boottest/java/util/stream/SpinedBufferTest.java b/jdk/test/java/util/stream/boottest/java/util/stream/SpinedBufferTest.java
new file mode 100644
index 0000000..3fee90b
--- /dev/null
+++ b/jdk/test/java/util/stream/boottest/java/util/stream/SpinedBufferTest.java
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.*;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+
+@Test
+public class SpinedBufferTest {
+
+    // Create sizes around the boundary of spines
+    static List<Integer> sizes;
+    static {
+        try {
+            sizes = IntStream.range(0, 15)
+                             .map(i -> 1 << i)
+                             .flatMap(i -> Arrays.stream(new int[] { i-2, i-1, i, i+1, i+2 }))
+                             .filter(i -> i >= 0)
+                             .boxed()
+                             .distinct()
+                             .collect(Collectors.toList());
+        }
+        catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static final int TEST_SIZE = 5000;
+
+    // SpinedBuffer
+
+    @DataProvider(name = "SpinedBuffer")
+    public Object[][] createSpinedBuffer() {
+        List<Object[]> params = new ArrayList<>();
+
+        for (int size : sizes) {
+            int[] array = IntStream.range(0, size).toArray();
+
+            SpinedBuffer<Integer> sb = new SpinedBuffer<>();
+            Arrays.stream(array).boxed().forEach(sb);
+            params.add(new Object[]{array, sb});
+
+            sb = new SpinedBuffer<>(size / 2);
+            Arrays.stream(array).boxed().forEach(sb);
+            params.add(new Object[]{array, sb});
+
+            sb = new SpinedBuffer<>(size);
+            Arrays.stream(array).boxed().forEach(sb);
+            params.add(new Object[]{array, sb});
+
+            sb = new SpinedBuffer<>(size * 2);
+            Arrays.stream(array).boxed().forEach(sb);
+            params.add(new Object[]{array, sb});
+        }
+
+        return params.toArray(new Object[0][]);
+    }
+
+    @Test(dataProvider = "SpinedBuffer")
+    public void testSpliterator(int[] array, SpinedBuffer<Integer> sb) {
+        assertEquals(sb.count(), array.length);
+        assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
+
+        SpliteratorTestHelper.testSpliterator(sb::spliterator);
+    }
+
+    @Test(dataProvider = "SpinedBuffer", groups = { "serialization-hostile" })
+    public void testLastSplit(int[] array, SpinedBuffer<Integer> sb) {
+        Spliterator<Integer> spliterator = sb.spliterator();
+        Spliterator<Integer> split = spliterator.trySplit();
+        long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
+        long lastSplitSize = spliterator.getExactSizeIfKnown();
+        splitSizes += lastSplitSize;
+
+        assertEquals(splitSizes, array.length);
+
+        List<Integer> contentOfLastSplit = new ArrayList<>();
+        spliterator.forEachRemaining(contentOfLastSplit::add);
+
+        assertEquals(contentOfLastSplit.size(), lastSplitSize);
+
+        List<Integer> end = Arrays.stream(array)
+                .boxed()
+                .substream(array.length - lastSplitSize)
+                .collect(Collectors.toList());
+        assertEquals(contentOfLastSplit, end);
+    }
+
+    @Test(groups = { "serialization-hostile" })
+    public void testSpinedBuffer() {
+        List<Integer> list1 = new ArrayList<>();
+        List<Integer> list2 = new ArrayList<>();
+        SpinedBuffer<Integer> sb = new SpinedBuffer<>();
+        for (int i = 0; i < TEST_SIZE; i++) {
+            list1.add(i);
+            sb.accept(i);
+        }
+        Iterator<Integer> it = sb.iterator();
+        for (int i = 0; i < TEST_SIZE; i++)
+            list2.add(it.next());
+        assertFalse(it.hasNext());
+        assertEquals(list1, list2);
+
+        for (int i = 0; i < TEST_SIZE; i++)
+            assertEquals(sb.get(i), (Integer) i, Integer.toString(i));
+
+        list2.clear();
+        sb.forEach(list2::add);
+        assertEquals(list1, list2);
+        Integer[] array = sb.asArray(LambdaTestHelpers.integerArrayGenerator);
+        list2.clear();
+        for (Integer i : array)
+            list2.add(i);
+        assertEquals(list1, list2);
+    }
+
+    // IntSpinedBuffer
+
+    @DataProvider(name = "IntSpinedBuffer")
+    public Object[][] createIntSpinedBuffer() {
+        List<Object[]> params = new ArrayList<>();
+
+        for (int size : sizes) {
+            int[] array = IntStream.range(0, size).toArray();
+            SpinedBuffer.OfInt sb = new SpinedBuffer.OfInt();
+            Arrays.stream(array).forEach(sb);
+
+            params.add(new Object[]{array, sb});
+        }
+
+        return params.toArray(new Object[0][]);
+    }
+
+    @Test(dataProvider = "IntSpinedBuffer")
+    public void testIntSpliterator(int[] array, SpinedBuffer.OfInt sb) {
+        assertEquals(sb.count(), array.length);
+        assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
+
+        SpliteratorTestHelper.testIntSpliterator(sb::spliterator);
+    }
+
+    @Test(dataProvider = "IntSpinedBuffer", groups = { "serialization-hostile" })
+    public void testIntLastSplit(int[] array, SpinedBuffer.OfInt sb) {
+        Spliterator.OfInt spliterator = sb.spliterator();
+        Spliterator.OfInt split = spliterator.trySplit();
+        long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
+        long lastSplitSize = spliterator.getExactSizeIfKnown();
+        splitSizes += lastSplitSize;
+
+        assertEquals(splitSizes, array.length);
+
+        List<Integer> contentOfLastSplit = new ArrayList<>();
+        spliterator.forEachRemaining((IntConsumer) contentOfLastSplit::add);
+
+        assertEquals(contentOfLastSplit.size(), lastSplitSize);
+
+        List<Integer> end = Arrays.stream(array)
+                .boxed()
+                .substream(array.length - lastSplitSize)
+                .collect(Collectors.toList());
+        assertEquals(contentOfLastSplit, end);
+    }
+
+    @Test(groups = { "serialization-hostile" })
+    public void testIntSpinedBuffer() {
+        List<Integer> list1 = new ArrayList<>();
+        List<Integer> list2 = new ArrayList<>();
+        SpinedBuffer.OfInt sb = new SpinedBuffer.OfInt();
+        for (int i = 0; i < TEST_SIZE; i++) {
+            list1.add(i);
+            sb.accept(i);
+        }
+        PrimitiveIterator.OfInt it = sb.iterator();
+        for (int i = 0; i < TEST_SIZE; i++)
+            list2.add(it.nextInt());
+        assertFalse(it.hasNext());
+        assertEquals(list1, list2);
+
+        for (int i = 0; i < TEST_SIZE; i++)
+            assertEquals(sb.get(i), i, Integer.toString(i));
+
+        list2.clear();
+        sb.forEach((int i) -> list2.add(i));
+        assertEquals(list1, list2);
+        int[] array = sb.asIntArray();
+        list2.clear();
+        for (int i : array)
+            list2.add(i);
+        assertEquals(list1, list2);
+    }
+
+    // LongSpinedBuffer
+
+    @DataProvider(name = "LongSpinedBuffer")
+    public Object[][] createLongSpinedBuffer() {
+        List<Object[]> params = new ArrayList<>();
+
+        for (int size : sizes) {
+            long[] array = LongStream.range(0, size).toArray();
+            SpinedBuffer.OfLong sb = new SpinedBuffer.OfLong();
+            Arrays.stream(array).forEach(sb);
+
+            params.add(new Object[]{array, sb});
+        }
+
+        return params.toArray(new Object[0][]);
+    }
+
+    @Test(dataProvider = "LongSpinedBuffer")
+    public void testLongSpliterator(long[] array, SpinedBuffer.OfLong sb) {
+        assertEquals(sb.count(), array.length);
+        assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
+
+        SpliteratorTestHelper.testLongSpliterator(sb::spliterator);
+    }
+
+    @Test(dataProvider = "LongSpinedBuffer", groups = { "serialization-hostile" })
+    public void testLongLastSplit(long[] array, SpinedBuffer.OfLong sb) {
+        Spliterator.OfLong spliterator = sb.spliterator();
+        Spliterator.OfLong split = spliterator.trySplit();
+        long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
+        long lastSplitSize = spliterator.getExactSizeIfKnown();
+        splitSizes += lastSplitSize;
+
+        assertEquals(splitSizes, array.length);
+
+        List<Long> contentOfLastSplit = new ArrayList<>();
+        spliterator.forEachRemaining((LongConsumer) contentOfLastSplit::add);
+
+        assertEquals(contentOfLastSplit.size(), lastSplitSize);
+
+        List<Long> end = Arrays.stream(array)
+                .boxed()
+                .substream(array.length - lastSplitSize)
+                .collect(Collectors.toList());
+        assertEquals(contentOfLastSplit, end);
+    }
+
+    @Test(groups = { "serialization-hostile" })
+    public void testLongSpinedBuffer() {
+        List<Long> list1 = new ArrayList<>();
+        List<Long> list2 = new ArrayList<>();
+        SpinedBuffer.OfLong sb = new SpinedBuffer.OfLong();
+        for (long i = 0; i < TEST_SIZE; i++) {
+            list1.add(i);
+            sb.accept(i);
+        }
+        PrimitiveIterator.OfLong it = sb.iterator();
+        for (int i = 0; i < TEST_SIZE; i++)
+            list2.add(it.nextLong());
+        assertFalse(it.hasNext());
+        assertEquals(list1, list2);
+
+        for (int i = 0; i < TEST_SIZE; i++)
+            assertEquals(sb.get(i), i, Long.toString(i));
+
+        list2.clear();
+        sb.forEach((long i) -> list2.add(i));
+        assertEquals(list1, list2);
+        long[] array = sb.asLongArray();
+        list2.clear();
+        for (long i : array)
+            list2.add(i);
+        assertEquals(list1, list2);
+    }
+
+    // DoubleSpinedBuffer
+
+    @DataProvider(name = "DoubleSpinedBuffer")
+    public Object[][] createDoubleSpinedBuffer() {
+        List<Object[]> params = new ArrayList<>();
+
+        for (int size : sizes) {
+            // @@@ replace with double range when implemented
+            double[] array = LongStream.range(0, size).doubles().toArray();
+            SpinedBuffer.OfDouble sb = new SpinedBuffer.OfDouble();
+            Arrays.stream(array).forEach(sb);
+
+            params.add(new Object[]{array, sb});
+        }
+
+        return params.toArray(new Object[0][]);
+    }
+
+    @Test(dataProvider = "DoubleSpinedBuffer")
+    public void testDoubleSpliterator(double[] array, SpinedBuffer.OfDouble sb) {
+        assertEquals(sb.count(), array.length);
+        assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
+
+        SpliteratorTestHelper.testDoubleSpliterator(sb::spliterator);
+    }
+
+    @Test(dataProvider = "DoubleSpinedBuffer", groups = { "serialization-hostile" })
+    public void testLongLastSplit(double[] array, SpinedBuffer.OfDouble sb) {
+        Spliterator.OfDouble spliterator = sb.spliterator();
+        Spliterator.OfDouble split = spliterator.trySplit();
+        long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
+        long lastSplitSize = spliterator.getExactSizeIfKnown();
+        splitSizes += lastSplitSize;
+
+        assertEquals(splitSizes, array.length);
+
+        List<Double> contentOfLastSplit = new ArrayList<>();
+        spliterator.forEachRemaining((DoubleConsumer) contentOfLastSplit::add);
+
+        assertEquals(contentOfLastSplit.size(), lastSplitSize);
+
+        List<Double> end = Arrays.stream(array)
+                .boxed()
+                .substream(array.length - lastSplitSize)
+                .collect(Collectors.toList());
+        assertEquals(contentOfLastSplit, end);
+    }
+
+    @Test(groups = { "serialization-hostile" })
+    public void testDoubleSpinedBuffer() {
+        List<Double> list1 = new ArrayList<>();
+        List<Double> list2 = new ArrayList<>();
+        SpinedBuffer.OfDouble sb = new SpinedBuffer.OfDouble();
+        for (long i = 0; i < TEST_SIZE; i++) {
+            list1.add((double) i);
+            sb.accept((double) i);
+        }
+        PrimitiveIterator.OfDouble it = sb.iterator();
+        for (int i = 0; i < TEST_SIZE; i++)
+            list2.add(it.nextDouble());
+        assertFalse(it.hasNext());
+        assertEquals(list1, list2);
+
+        for (int i = 0; i < TEST_SIZE; i++)
+            assertEquals(sb.get(i), (double) i, Double.toString(i));
+
+        list2.clear();
+        sb.forEach((double i) -> list2.add(i));
+        assertEquals(list1, list2);
+        double[] array = sb.asDoubleArray();
+        list2.clear();
+        for (double i : array)
+            list2.add(i);
+        assertEquals(list1, list2);
+    }
+}
diff --git a/jdk/test/java/util/stream/boottest/java/util/stream/StreamFlagsTest.java b/jdk/test/java/util/stream/boottest/java/util/stream/StreamFlagsTest.java
new file mode 100644
index 0000000..a5fa364
--- /dev/null
+++ b/jdk/test/java/util/stream/boottest/java/util/stream/StreamFlagsTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.*;
+import java.util.stream.Stream;
+import java.util.stream.StreamOpFlag;
+import java.util.stream.Streams;
+
+import static java.util.stream.StreamOpFlag.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * StreamFlagsTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class StreamFlagsTest {
+    Stream<String> arrayList = new ArrayList<String>().stream();
+    Stream<String> linkedList = new LinkedList<String>().stream();
+    Stream<String> hashSet = new HashSet<String>().stream();
+    Stream<String> treeSet = new TreeSet<String>().stream();
+    Stream<String> linkedHashSet = new LinkedHashSet<String>().stream();
+    Stream<String> repeat = Stream.generate(() -> "");
+
+    Stream<?>[] streams = { arrayList, linkedList, hashSet, treeSet, linkedHashSet, repeat };
+
+    private void assertFlags(int value, EnumSet<StreamOpFlag> setFlags, EnumSet<StreamOpFlag> clearFlags) {
+        for (StreamOpFlag flag : setFlags)
+            assertTrue(flag.isKnown(value));
+        for (StreamOpFlag flag : clearFlags)
+            assertTrue(!flag.isKnown(value));
+    }
+
+    public void testBaseStreams() {
+        Stream<String> arrayList = new ArrayList<String>().stream();
+        Stream<String> linkedList = new LinkedList<String>().stream();
+        Stream<String> hashSet = new HashSet<String>().stream();
+        Stream<String> treeSet = new TreeSet<String>().stream();
+        Stream<String> linkedHashSet = new LinkedHashSet<String>().stream();
+        Stream<String> repeat = Stream.generate(() -> "");
+
+        assertFlags(OpTestCase.getStreamFlags(arrayList),
+                    EnumSet.of(ORDERED, SIZED),
+                    EnumSet.of(DISTINCT, SORTED, SHORT_CIRCUIT));
+        assertFlags(OpTestCase.getStreamFlags(linkedList),
+                    EnumSet.of(ORDERED, SIZED),
+                    EnumSet.of(DISTINCT, SORTED, SHORT_CIRCUIT));
+        assertFlags(OpTestCase.getStreamFlags(hashSet),
+                    EnumSet.of(SIZED, DISTINCT),
+                    EnumSet.of(ORDERED, SORTED, SHORT_CIRCUIT));
+        assertFlags(OpTestCase.getStreamFlags(treeSet),
+                    EnumSet.of(ORDERED, SIZED, DISTINCT, SORTED),
+                    EnumSet.of(SHORT_CIRCUIT));
+        assertFlags(OpTestCase.getStreamFlags(linkedHashSet),
+                    EnumSet.of(ORDERED, DISTINCT, SIZED),
+                    EnumSet.of(SORTED, SHORT_CIRCUIT));
+        assertFlags(OpTestCase.getStreamFlags(repeat),
+                    EnumSet.of(ORDERED),
+                    EnumSet.of(SIZED, DISTINCT, SORTED, SHORT_CIRCUIT));
+    }
+
+    public void testFilter() {
+        for (Stream<?> s : streams) {
+            int baseFlags = OpTestCase.getStreamFlags(s);
+            int filteredFlags = OpTestCase.getStreamFlags(s.filter((Object e) -> true));
+            int expectedFlags = baseFlags & ~SIZED.set();
+
+            assertEquals(filteredFlags, expectedFlags);
+        }
+    }
+}
diff --git a/jdk/test/java/util/stream/boottest/java/util/stream/StreamOpFlagsTest.java b/jdk/test/java/util/stream/boottest/java/util/stream/StreamOpFlagsTest.java
new file mode 100644
index 0000000..aa47aa2
--- /dev/null
+++ b/jdk/test/java/util/stream/boottest/java/util/stream/StreamOpFlagsTest.java
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.StreamOpFlag.*;
+import static org.testng.Assert.*;
+import static org.testng.Assert.assertEquals;
+
+@Test
+public class StreamOpFlagsTest {
+
+    public void testNullCombine() {
+        int sourceFlags = StreamOpFlag.IS_SIZED;
+
+        assertEquals(sourceFlags, toStreamFlags(combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE)));
+    }
+
+    public void testInitialOpFlagsFromSourceFlags() {
+        List<StreamOpFlag> flags = new ArrayList<>(StreamOpFlagTestHelper.allStreamFlags());
+        for (int i = 0; i < (1 << flags.size()); i++)  {
+            int sourceFlags = 0;
+            for (int f = 0; f < flags.size(); f++) {
+                if ((i & (1 << f)) != 0)  {
+                    sourceFlags |= flags.get(f).set();
+                }
+            }
+
+            int opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
+            assertEquals(opsFlags, (~(sourceFlags << 1)) & StreamOpFlag.INITIAL_OPS_VALUE);
+        }
+    }
+
+    public void testSameCombine() {
+        for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
+            int sourceFlags = f.set();
+            int opsFlags;
+
+            opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
+            opsFlags = combineOpFlags(f.set(), opsFlags);
+            assertEquals(sourceFlags, toStreamFlags(opsFlags));
+        }
+    }
+
+    public void testOpClear() {
+        for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
+            // Clear when source not set
+            int sourceFlags = 0;
+            int opsFlags;
+
+            opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
+            opsFlags = combineOpFlags(f.clear(), opsFlags);
+            assertEquals(sourceFlags, toStreamFlags(opsFlags));
+
+            // Clear when source set
+            sourceFlags = f.set();
+
+            opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
+            opsFlags = combineOpFlags(f.clear(), opsFlags);
+            assertEquals(0, toStreamFlags(opsFlags));
+        }
+    }
+
+    public void testOpInject() {
+        for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
+            // Set when source not set
+            int sourceFlags = 0;
+            int opsFlags;
+
+            opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
+            opsFlags = combineOpFlags(f.set(), opsFlags);
+            assertEquals(f.set(), toStreamFlags(opsFlags));
+
+            // Set when source set
+            sourceFlags = f.set();
+
+            opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
+            opsFlags = combineOpFlags(f.set(), opsFlags);
+            assertEquals(sourceFlags, toStreamFlags(opsFlags));
+        }
+    }
+
+    public void testPairSet() {
+        List<Integer> sourceFlagsList
+                = StreamOpFlagTestHelper.allStreamFlags().stream().map(StreamOpFlag::set).collect(toList());
+        sourceFlagsList.add(0, 0);
+
+        for (int sourceFlags : sourceFlagsList) {
+            for (StreamOpFlag f1 : StreamOpFlagTestHelper.allStreamFlags()) {
+                for (StreamOpFlag f2 : StreamOpFlagTestHelper.allStreamFlags()) {
+                    int opsFlags;
+
+                    opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
+                    opsFlags = combineOpFlags(f1.set(), opsFlags);
+                    opsFlags = combineOpFlags(f2.set(), opsFlags);
+                    assertEquals(sourceFlags | f1.set() | f2.set(), toStreamFlags(opsFlags));
+                }
+            }
+        }
+    }
+
+    public void testPairSetAndClear() {
+        List<Integer> sourceFlagsList
+                = StreamOpFlagTestHelper.allStreamFlags().stream().map(StreamOpFlag::set).collect(toList());
+        sourceFlagsList.add(0, 0);
+
+        for (int sourceFlags : sourceFlagsList) {
+            for (StreamOpFlag f1 : StreamOpFlagTestHelper.allStreamFlags())  {
+                for (StreamOpFlag f2 : StreamOpFlagTestHelper.allStreamFlags()) {
+                    int opsFlags;
+
+                    opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
+                    opsFlags = combineOpFlags(f1.set(), opsFlags);
+                    opsFlags = combineOpFlags(f2.clear(), opsFlags);
+                    if (f1 == f2)
+                        assertEquals((f2.set() == sourceFlags) ? 0 : sourceFlags, toStreamFlags(opsFlags));
+                    else
+                        assertEquals((f2.set() == sourceFlags) ? f1.set() : sourceFlags | f1.set(), toStreamFlags(opsFlags));
+                }
+            }
+        }
+    }
+
+    public void testShortCircuit() {
+        int opsFlags = combineOpFlags(0, StreamOpFlag.INITIAL_OPS_VALUE);
+        assertFalse(StreamOpFlag.SHORT_CIRCUIT.isKnown(opsFlags));
+
+        opsFlags = combineOpFlags(StreamOpFlag.IS_SHORT_CIRCUIT, opsFlags);
+        assertTrue(StreamOpFlag.SHORT_CIRCUIT.isKnown(opsFlags));
+
+        opsFlags = combineOpFlags(0, opsFlags);
+        assertTrue(StreamOpFlag.SHORT_CIRCUIT.isKnown(opsFlags));
+    }
+
+    public void testApplySourceFlags() {
+        int sourceFlags = StreamOpFlag.IS_SIZED | StreamOpFlag.IS_DISTINCT;
+
+        List<Integer> ops = Arrays.asList(StreamOpFlag.NOT_SIZED, StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SORTED);
+
+        int opsFlags = StreamOpFlag.combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
+        for (int opFlags : ops) {
+            opsFlags = combineOpFlags(opFlags, opsFlags);
+        }
+        assertFalse(StreamOpFlag.SIZED.isKnown(opsFlags));
+        assertTrue(StreamOpFlag.SIZED.isCleared(opsFlags));
+        assertFalse(StreamOpFlag.SIZED.isPreserved(opsFlags));
+        assertTrue(StreamOpFlag.DISTINCT.isKnown(opsFlags));
+        assertFalse(StreamOpFlag.DISTINCT.isCleared(opsFlags));
+        assertFalse(StreamOpFlag.DISTINCT.isPreserved(opsFlags));
+        assertTrue(StreamOpFlag.SORTED.isKnown(opsFlags));
+        assertFalse(StreamOpFlag.SORTED.isCleared(opsFlags));
+        assertFalse(StreamOpFlag.SORTED.isPreserved(opsFlags));
+        assertTrue(StreamOpFlag.ORDERED.isKnown(opsFlags));
+        assertFalse(StreamOpFlag.ORDERED.isCleared(opsFlags));
+        assertFalse(StreamOpFlag.ORDERED.isPreserved(opsFlags));
+
+        int streamFlags = toStreamFlags(opsFlags);
+        assertFalse(StreamOpFlag.SIZED.isKnown(streamFlags));
+        assertTrue(StreamOpFlag.DISTINCT.isKnown(streamFlags));
+        assertTrue(StreamOpFlag.SORTED.isKnown(streamFlags));
+        assertTrue(StreamOpFlag.ORDERED.isKnown(streamFlags));
+    }
+
+    public void testSpliteratorMask() {
+        assertSpliteratorMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
+        assertSpliteratorMask(StreamOpFlag.DISTINCT.clear(), 0);
+
+        assertSpliteratorMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
+        assertSpliteratorMask(StreamOpFlag.SORTED.clear(), 0);
+
+        assertSpliteratorMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
+        assertSpliteratorMask(StreamOpFlag.ORDERED.clear(), 0);
+
+        assertSpliteratorMask(StreamOpFlag.SIZED.set(), StreamOpFlag.IS_SIZED);
+        assertSpliteratorMask(StreamOpFlag.SIZED.clear(), 0);
+
+        assertSpliteratorMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
+        assertSpliteratorMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
+    }
+
+    private void assertSpliteratorMask(int actual, int expected) {
+        assertEquals(actual & StreamOpFlag.SPLITERATOR_CHARACTERISTICS_MASK, expected);
+    }
+
+    public void testStreamMask() {
+        assertStreamMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
+        assertStreamMask(StreamOpFlag.DISTINCT.clear(), 0);
+
+        assertStreamMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
+        assertStreamMask(StreamOpFlag.SORTED.clear(), 0);
+
+        assertStreamMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
+        assertStreamMask(StreamOpFlag.ORDERED.clear(), 0);
+
+        assertStreamMask(StreamOpFlag.SIZED.set(), StreamOpFlag.IS_SIZED);
+        assertStreamMask(StreamOpFlag.SIZED.clear(), 0);
+
+        assertStreamMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
+        assertStreamMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
+    }
+
+    private void assertStreamMask(int actual, int expected) {
+        assertEquals(actual & StreamOpFlag.STREAM_MASK, expected);
+    }
+
+    public void testOpMask() {
+        assertOpMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
+        assertOpMask(StreamOpFlag.DISTINCT.clear(), StreamOpFlag.NOT_DISTINCT);
+
+        assertOpMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
+        assertOpMask(StreamOpFlag.SORTED.clear(), StreamOpFlag.NOT_SORTED);
+
+        assertOpMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
+        assertOpMask(StreamOpFlag.ORDERED.clear(), StreamOpFlag.NOT_ORDERED);
+
+        assertOpMask(StreamOpFlag.SIZED.set(), 0);
+        assertOpMask(StreamOpFlag.SIZED.clear(), StreamOpFlag.NOT_SIZED);
+
+        assertOpMask(StreamOpFlag.SHORT_CIRCUIT.set(), StreamOpFlag.IS_SHORT_CIRCUIT);
+        assertOpMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
+    }
+
+    private void assertOpMask(int actual, int expected) {
+        assertEquals(actual & StreamOpFlag.OP_MASK, expected);
+    }
+
+    public void testTerminalOpMask() {
+        assertTerminalOpMask(StreamOpFlag.DISTINCT.set(), 0);
+        assertTerminalOpMask(StreamOpFlag.DISTINCT.clear(), 0);
+
+        assertTerminalOpMask(StreamOpFlag.SORTED.set(), 0);
+        assertTerminalOpMask(StreamOpFlag.SORTED.clear(), 0);
+
+        assertTerminalOpMask(StreamOpFlag.ORDERED.set(), 0);
+        assertTerminalOpMask(StreamOpFlag.ORDERED.clear(), StreamOpFlag.NOT_ORDERED);
+
+        assertTerminalOpMask(StreamOpFlag.SIZED.set(), 0);
+        assertTerminalOpMask(StreamOpFlag.SIZED.clear(), 0);
+
+        assertTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.set(), StreamOpFlag.IS_SHORT_CIRCUIT);
+        assertTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
+    }
+
+    private void assertTerminalOpMask(int actual, int expected) {
+        assertEquals(actual & StreamOpFlag.TERMINAL_OP_MASK, expected);
+    }
+
+    public void testUpstreamTerminalOpMask() {
+        assertUpstreamTerminalOpMask(StreamOpFlag.DISTINCT.set(), 0);
+        assertUpstreamTerminalOpMask(StreamOpFlag.DISTINCT.clear(), 0);
+
+        assertUpstreamTerminalOpMask(StreamOpFlag.SORTED.set(), 0);
+        assertUpstreamTerminalOpMask(StreamOpFlag.SORTED.clear(), 0);
+
+        assertUpstreamTerminalOpMask(StreamOpFlag.ORDERED.set(), 0);
+        assertUpstreamTerminalOpMask(StreamOpFlag.ORDERED.clear(), StreamOpFlag.NOT_ORDERED);
+
+        assertUpstreamTerminalOpMask(StreamOpFlag.SIZED.set(), 0);
+        assertUpstreamTerminalOpMask(StreamOpFlag.SIZED.clear(), 0);
+
+        assertUpstreamTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
+        assertUpstreamTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
+    }
+
+    private void assertUpstreamTerminalOpMask(int actual, int expected) {
+        assertEquals(actual & StreamOpFlag.UPSTREAM_TERMINAL_OP_MASK, expected);
+    }
+
+    public void testSpliteratorCharacteristics() {
+        assertEquals(Spliterator.DISTINCT, StreamOpFlag.IS_DISTINCT);
+        assertEquals(Spliterator.SORTED, StreamOpFlag.IS_SORTED);
+        assertEquals(Spliterator.ORDERED, StreamOpFlag.IS_ORDERED);
+        assertEquals(Spliterator.SIZED, StreamOpFlag.IS_SIZED);
+
+        List<Integer> others = Arrays.asList(Spliterator.NONNULL, Spliterator.IMMUTABLE,
+                                             Spliterator.CONCURRENT, Spliterator.SUBSIZED);
+        for (int c : others) {
+            assertNotEquals(c, StreamOpFlag.IS_SHORT_CIRCUIT);
+        }
+    }
+
+    public void testSpliteratorCharacteristicsMask() {
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.DISTINCT.clear(), 0);
+
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.SORTED.clear(), 0);
+
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.ORDERED.clear(), 0);
+
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.SIZED.set(), StreamOpFlag.IS_SIZED);
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.SIZED.clear(), 0);
+
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
+    }
+
+    private void assertSpliteratorCharacteristicsMask(int actual, int expected) {
+        assertEquals(StreamOpFlag.fromCharacteristics(actual), expected);
+    }
+
+    public void testSpliteratorSorted() {
+        class SortedEmptySpliterator implements Spliterator<Object> {
+            final Comparator<Object> c;
+
+            SortedEmptySpliterator(Comparator<Object> c) {
+                this.c = c;
+            }
+
+            @Override
+            public Spliterator<Object> trySplit() {
+                return null;
+            }
+
+            @Override
+            public boolean tryAdvance(Consumer<? super Object> action) {
+                return false;
+            }
+
+            @Override
+            public long estimateSize() {
+                return Long.MAX_VALUE;
+            }
+
+            @Override
+            public int characteristics() {
+                return Spliterator.SORTED;
+            }
+
+            @Override
+            public Comparator<? super Object> getComparator() {
+                return c;
+            }
+        };
+
+        {
+            int flags = StreamOpFlag.fromCharacteristics(new SortedEmptySpliterator(null));
+            assertEquals(flags, StreamOpFlag.IS_SORTED);
+        }
+
+        {
+            int flags = StreamOpFlag.fromCharacteristics(new SortedEmptySpliterator((a, b) -> 0));
+            assertEquals(flags, 0);
+        }
+    }
+}
diff --git a/jdk/test/java/util/stream/boottest/java/util/stream/StreamReuseTest.java b/jdk/test/java/util/stream/boottest/java/util/stream/StreamReuseTest.java
new file mode 100644
index 0000000..0ac9d68
--- /dev/null
+++ b/jdk/test/java/util/stream/boottest/java/util/stream/StreamReuseTest.java
@@ -0,0 +1,441 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.function.Function;
+
+import static org.testng.Assert.fail;
+
+/**
+ * StreamReuseTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class StreamReuseTest {
+
+    private <T, U, E, S extends BaseStream<E, S>, D extends TestData<E, S>> void assertSecondFails(
+            D data,
+            Function<S, T> first,
+            Function<S, U> second,
+            Class<? extends Throwable> exception,
+            String text) {
+        S stream = data.stream();
+        T fr = first.apply(stream);
+        try {
+            U sr = second.apply(stream);
+            fail(text + " (seq)");
+        }
+        catch (Throwable e) {
+            if (exception.isAssignableFrom(e.getClass())) {
+                // Expected
+            }
+            else if (e instanceof Error)
+                throw (Error) e;
+            else if (e instanceof RuntimeException)
+                throw (RuntimeException) e;
+            else
+                throw new AssertionError("Unexpected exception " + e.getClass(), e);
+        }
+
+        stream = data.parallelStream();
+        fr = first.apply(stream);
+        try {
+            U sr = second.apply(stream);
+            fail(text + " (par)");
+        }
+        catch (Throwable e) {
+            if (exception.isAssignableFrom(e.getClass())) {
+                // Expected
+            }
+            else if (e instanceof Error)
+                throw (Error) e;
+            else if (e instanceof RuntimeException)
+                throw (RuntimeException) e;
+            else
+                throw new AssertionError("Unexpected exception " + e.getClass(), e);
+        }
+    }
+
+    // Stream
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testTwoStreams(String name, TestData<Integer, Stream<Integer>> data) {
+        assertSecondFails(data,
+                          (Stream<Integer> s) -> s.map(i -> i), (Stream<Integer> s) -> s.map(i -> i),
+                          IllegalStateException.class,
+                          "Stream map / map succeeded erroneously");
+        assertSecondFails(data,
+                          Stream::distinct, (Stream<Integer> s) -> s.map(i -> i),
+                          IllegalStateException.class,
+                          "Stream distinct / map succeeded erroneously");
+        assertSecondFails(data,
+                          (Stream<Integer> s) -> s.map(i -> i), Stream::distinct,
+                          IllegalStateException.class,
+                          "Stream map / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          Stream::distinct, Stream::distinct,
+                          IllegalStateException.class,
+                          "Stream distinct / distinct succeeded erroneously");
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testTwoTerminals(String name, TestData<Integer, Stream<Integer>> data) {
+        assertSecondFails(data,
+                          Stream::findFirst, Stream::findFirst,
+                          IllegalStateException.class,
+                          "Stream findFirst / findFirst succeeded erroneously");
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testTerminalStream(String name, TestData<Integer, Stream<Integer>> data) {
+        assertSecondFails(data,
+                          Stream::findFirst, (Stream<Integer> s) -> s.map(i -> i),
+                          IllegalStateException.class,
+                          "Stream findFirst / map succeeded erroneously");
+        assertSecondFails(data,
+                          (Stream<Integer> s) -> s.map(i -> i), Stream::findFirst,
+                          IllegalStateException.class,
+                          "Stream map / findFirst succeeded erroneously");
+        assertSecondFails(data,
+                          Stream::findFirst, Stream::distinct,
+                          IllegalStateException.class,
+                          "Stream findFirst / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          Stream::distinct, Stream::findFirst,
+                          IllegalStateException.class,
+                          "Stream distinct / findFirst succeeded erroneously");
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testTwoIterators(String name, TestData<Integer, Stream<Integer>> data) {
+        assertSecondFails(data,
+                          Stream::iterator, Stream::iterator,
+                          IllegalStateException.class,
+                          "Stream iterator / iterator succeeded erroneously");
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testTerminalIterator(String name, TestData<Integer, Stream<Integer>> data) {
+        assertSecondFails(data,
+                          Stream::iterator, Stream::findFirst,
+                          IllegalStateException.class,
+                          "Stream iterator / findFirst succeeded erroneously");
+        assertSecondFails(data,
+                          Stream::findFirst, Stream::iterator,
+                          IllegalStateException.class,
+                          "Stream findFirst / iterator succeeded erroneously");
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testStreamIterator(String name, TestData<Integer, Stream<Integer>> data) {
+        assertSecondFails(data,
+                          Stream::iterator, (Stream<Integer> s) -> s.map(i -> i),
+                          IllegalStateException.class,
+                          "Stream iterator / map succeeded erroneously");
+        assertSecondFails(data,
+                          (Stream<Integer> s) -> s.map(i -> i), Stream::iterator,
+                          IllegalStateException.class,
+                          "Stream map / iterator succeeded erroneously");
+        assertSecondFails(data,
+                          Stream::iterator, Stream::distinct,
+                          IllegalStateException.class,
+                          "Stream iterator / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          Stream::distinct, Stream::iterator,
+                          IllegalStateException.class,
+                          "Stream distinct / iterator succeeded erroneously");
+    }
+
+    // IntStream
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testTwoStreams(String name, TestData.OfInt data) {
+        assertSecondFails(data,
+                          (IntStream s) -> s.mapToObj(i -> i), (IntStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "IntStream map / map succeeded erroneously");
+        assertSecondFails(data,
+                          IntStream::distinct, (IntStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "IntStream distinct / map succeeded erroneously");
+        assertSecondFails(data,
+                          (IntStream s) -> s.mapToObj(i -> i), IntStream::distinct,
+                          IllegalStateException.class,
+                          "IntStream map / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          IntStream::distinct, IntStream::distinct,
+                          IllegalStateException.class,
+                          "IntStream distinct / distinct succeeded erroneously");
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testTwoTerminals(String name, TestData.OfInt data) {
+        assertSecondFails(data,
+                          IntStream::sum, IntStream::sum,
+                          IllegalStateException.class,
+                          "IntStream sum / sum succeeded erroneously");
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testTerminalStream(String name, TestData.OfInt data) {
+        assertSecondFails(data,
+                          IntStream::sum, (IntStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "IntStream sum / map succeeded erroneously");
+        assertSecondFails(data,
+                          (IntStream s) -> s.mapToObj(i -> i), IntStream::sum,
+                          IllegalStateException.class,
+                          "IntStream map / sum succeeded erroneously");
+        assertSecondFails(data,
+                          IntStream::sum, IntStream::distinct,
+                          IllegalStateException.class,
+                          "IntStream sum / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          IntStream::distinct, IntStream::sum,
+                          IllegalStateException.class,
+                          "IntStream distinct / sum succeeded erroneously");
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testTwoIterators(String name, TestData.OfInt data) {
+        assertSecondFails(data,
+                          IntStream::iterator, IntStream::iterator,
+                          IllegalStateException.class,
+                          "IntStream iterator / iterator succeeded erroneously");
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testTerminalIterator(String name, TestData.OfInt data) {
+        assertSecondFails(data,
+                          IntStream::iterator, IntStream::sum,
+                          IllegalStateException.class,
+                          "IntStream iterator / sum succeeded erroneously");
+        assertSecondFails(data,
+                          IntStream::sum, IntStream::iterator,
+                          IllegalStateException.class,
+                          "Stream sum / iterator succeeded erroneously");
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testStreamIterator(String name, TestData.OfInt data) {
+        assertSecondFails(data,
+                          IntStream::iterator, (IntStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "IntStream iterator / map succeeded erroneously");
+        assertSecondFails(data,
+                          (IntStream s) -> s.mapToObj(i -> i), IntStream::iterator,
+                          IllegalStateException.class,
+                          "IntStream map / iterator succeeded erroneously");
+        assertSecondFails(data,
+                          IntStream::iterator, IntStream::distinct,
+                          IllegalStateException.class,
+                          "IntStream iterator / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          IntStream::distinct, IntStream::iterator,
+                          IllegalStateException.class,
+                          "IntStream distinct / iterator succeeded erroneously");
+    }
+
+    // LongStream
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testTwoStreams(String name, TestData.OfLong data) {
+        assertSecondFails(data,
+                          (LongStream s) -> s.mapToObj(i -> i), (LongStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "LongStream map / map succeeded erroneously");
+        assertSecondFails(data,
+                          LongStream::distinct, (LongStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "LongStream distinct / map succeeded erroneously");
+        assertSecondFails(data,
+                          (LongStream s) -> s.mapToObj(i -> i), LongStream::distinct,
+                          IllegalStateException.class,
+                          "LongStream map / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          LongStream::distinct, LongStream::distinct,
+                          IllegalStateException.class,
+                          "LongStream distinct / distinct succeeded erroneously");
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testTwoTerminals(String name, TestData.OfLong data) {
+        assertSecondFails(data,
+                          LongStream::sum, LongStream::sum,
+                          IllegalStateException.class,
+                          "LongStream sum / sum succeeded erroneously");
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testTerminalStream(String name, TestData.OfLong data) {
+        assertSecondFails(data,
+                          LongStream::sum, (LongStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "LongStream sum / map succeeded erroneously");
+        assertSecondFails(data,
+                          (LongStream s) -> s.mapToObj(i -> i), LongStream::sum,
+                          IllegalStateException.class,
+                          "LongStream map / sum succeeded erroneously");
+        assertSecondFails(data,
+                          LongStream::sum, LongStream::distinct,
+                          IllegalStateException.class,
+                          "LongStream sum / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          LongStream::distinct, LongStream::sum,
+                          IllegalStateException.class,
+                          "LongStream distinct / sum succeeded erroneously");
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testTwoIterators(String name, TestData.OfLong data) {
+        assertSecondFails(data,
+                          LongStream::iterator, LongStream::iterator,
+                          IllegalStateException.class,
+                          "LongStream iterator / iterator succeeded erroneously");
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testTerminalIterator(String name, TestData.OfLong data) {
+        assertSecondFails(data,
+                          LongStream::iterator, LongStream::sum,
+                          IllegalStateException.class,
+                          "LongStream iterator / sum succeeded erroneously");
+        assertSecondFails(data,
+                          LongStream::sum, LongStream::iterator,
+                          IllegalStateException.class,
+                          "Stream sum / iterator succeeded erroneously");
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testStreamIterator(String name, TestData.OfLong data) {
+        assertSecondFails(data,
+                          LongStream::iterator, (LongStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "LongStream iterator / map succeeded erroneously");
+        assertSecondFails(data,
+                          (LongStream s) -> s.mapToObj(i -> i), LongStream::iterator,
+                          IllegalStateException.class,
+                          "LongStream map / iterator succeeded erroneously");
+        assertSecondFails(data,
+                          LongStream::iterator, LongStream::distinct,
+                          IllegalStateException.class,
+                          "LongStream iterator / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          LongStream::distinct, LongStream::iterator,
+                          IllegalStateException.class,
+                          "LongStream distinct / iterator succeeded erroneously");
+    }
+
+    // DoubleStream
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testTwoStreams(String name, TestData.OfDouble data) {
+        assertSecondFails(data,
+                          (DoubleStream s) -> s.mapToObj(i -> i), (DoubleStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "DoubleStream map / map succeeded erroneously");
+        assertSecondFails(data,
+                          DoubleStream::distinct, (DoubleStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "DoubleStream distinct / map succeeded erroneously");
+        assertSecondFails(data,
+                          (DoubleStream s) -> s.mapToObj(i -> i), DoubleStream::distinct,
+                          IllegalStateException.class,
+                          "DoubleStream map / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          DoubleStream::distinct, DoubleStream::distinct,
+                          IllegalStateException.class,
+                          "DoubleStream distinct / distinct succeeded erroneously");
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testTwoTerminals(String name, TestData.OfDouble data) {
+        assertSecondFails(data,
+                          DoubleStream::sum, DoubleStream::sum,
+                          IllegalStateException.class,
+                          "DoubleStream sum / sum succeeded erroneously");
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testTerminalStream(String name, TestData.OfDouble data) {
+        assertSecondFails(data,
+                          DoubleStream::sum, (DoubleStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "DoubleStream sum / map succeeded erroneously");
+        assertSecondFails(data,
+                          (DoubleStream s) -> s.mapToObj(i -> i), DoubleStream::sum,
+                          IllegalStateException.class,
+                          "DoubleStream map / sum succeeded erroneously");
+        assertSecondFails(data,
+                          DoubleStream::sum, DoubleStream::distinct,
+                          IllegalStateException.class,
+                          "DoubleStream sum / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          DoubleStream::distinct, DoubleStream::sum,
+                          IllegalStateException.class,
+                          "DoubleStream distinct / sum succeeded erroneously");
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testTwoIterators(String name, TestData.OfDouble data) {
+        assertSecondFails(data,
+                          DoubleStream::iterator, DoubleStream::iterator,
+                          IllegalStateException.class,
+                          "DoubleStream iterator / iterator succeeded erroneously");
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testTerminalIterator(String name, TestData.OfDouble data) {
+        assertSecondFails(data,
+                          DoubleStream::iterator, DoubleStream::sum,
+                          IllegalStateException.class,
+                          "DoubleStream iterator / sum succeeded erroneously");
+        assertSecondFails(data,
+                          DoubleStream::sum, DoubleStream::iterator,
+                          IllegalStateException.class,
+                          "Stream sum / iterator succeeded erroneously");
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testStreamIterator(String name, TestData.OfDouble data) {
+        assertSecondFails(data,
+                          DoubleStream::iterator, (DoubleStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "DoubleStream iterator / map succeeded erroneously");
+        assertSecondFails(data,
+                          (DoubleStream s) -> s.mapToObj(i -> i), DoubleStream::iterator,
+                          IllegalStateException.class,
+                          "DoubleStream map / iterator succeeded erroneously");
+        assertSecondFails(data,
+                          DoubleStream::iterator, DoubleStream::distinct,
+                          IllegalStateException.class,
+                          "DoubleStream iterator / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          DoubleStream::distinct, DoubleStream::iterator,
+                          IllegalStateException.class,
+                          "DoubleStream distinct / iterator succeeded erroneously");
+    }
+}
diff --git a/jdk/test/java/util/stream/boottest/java/util/stream/UnorderedTest.java b/jdk/test/java/util/stream/boottest/java/util/stream/UnorderedTest.java
new file mode 100644
index 0000000..48b4e75
--- /dev/null
+++ b/jdk/test/java/util/stream/boottest/java/util/stream/UnorderedTest.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+
+@Test
+public class UnorderedTest extends OpTestCase {
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testTerminalOps(String name, TestData<Integer, Stream<Integer>> data) {
+        testTerminal(data, s -> { s.forEach(x -> { }); return 0; });
+
+        testTerminal(data, s -> s.findAny(), (a, b) -> assertEquals(a.isPresent(), b.isPresent()));
+
+        testTerminal(data, s -> s.anyMatch(e -> true));
+    }
+
+
+    private <T, R> void testTerminal(TestData<T, Stream<T>> data, Function<Stream<T>, R> terminalF) {
+        testTerminal(data, terminalF, LambdaTestHelpers::assertContentsEqual);
+    }
+
+    static class WrappingUnaryOperator<S> implements UnaryOperator<S> {
+
+        final boolean isLimit;
+        final UnaryOperator<S> uo;
+
+        WrappingUnaryOperator(UnaryOperator<S> uo) {
+            this(uo, false);
+        }
+
+        WrappingUnaryOperator(UnaryOperator<S> uo, boolean isLimit) {
+            this.uo = uo;
+            this.isLimit = isLimit;
+        }
+
+        @Override
+        public S apply(S s) {
+            return uo.apply(s);
+        }
+    }
+
+    static <S> WrappingUnaryOperator<S> wrap(UnaryOperator<S> uo) {
+        return new WrappingUnaryOperator<>(uo);
+    }
+
+    static <S> WrappingUnaryOperator<S> wrap(UnaryOperator<S> uo, boolean isLimit) {
+        return new WrappingUnaryOperator<>(uo, isLimit);
+    }
+
+    @SuppressWarnings("rawtypes")
+    private List permutationOfFunctions =
+            LambdaTestHelpers.perm(Arrays.<WrappingUnaryOperator<Stream<Object>>>asList(
+                    wrap(s -> s.sorted()),
+                    wrap(s -> s.distinct()),
+                    wrap(s -> s.limit(5), true)
+            ));
+
+    @SuppressWarnings("unchecked")
+    private <T, R> void testTerminal(TestData<T, Stream<T>> data,
+                                     Function<Stream<T>, R> terminalF,
+                                     BiConsumer<R, R> equalityAsserter) {
+        testTerminal(data, terminalF, equalityAsserter, permutationOfFunctions, StreamShape.REFERENCE);
+    }
+
+    //
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntTerminalOps(String name, TestData.OfInt data) {
+        testIntTerminal(data, s -> { s.forEach(x -> { }); return 0; });
+        testIntTerminal(data, s -> s.findAny(), (a, b) -> assertEquals(a.isPresent(), b.isPresent()));
+        testIntTerminal(data, s -> s.anyMatch(e -> true));
+    }
+
+
+    private <T, R> void testIntTerminal(TestData.OfInt data, Function<IntStream, R> terminalF) {
+        testIntTerminal(data, terminalF, LambdaTestHelpers::assertContentsEqual);
+    }
+
+    private List<List<WrappingUnaryOperator<IntStream>>> intPermutationOfFunctions =
+            LambdaTestHelpers.perm(Arrays.asList(
+                    wrap(s -> s.sorted()),
+                    wrap(s -> s.distinct()),
+                    wrap(s -> s.limit(5), true)
+            ));
+
+    private <R> void testIntTerminal(TestData.OfInt data,
+                                     Function<IntStream, R> terminalF,
+                                     BiConsumer<R, R> equalityAsserter) {
+        testTerminal(data, terminalF, equalityAsserter, intPermutationOfFunctions, StreamShape.INT_VALUE);
+    }
+
+    //
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongTerminalOps(String name, TestData.OfLong data) {
+        testLongTerminal(data, s -> { s.forEach(x -> { }); return 0; });
+        testLongTerminal(data, s -> s.findAny(), (a, b) -> assertEquals(a.isPresent(), b.isPresent()));
+        testLongTerminal(data, s -> s.anyMatch(e -> true));
+    }
+
+
+    private <T, R> void testLongTerminal(TestData.OfLong data, Function<LongStream, R> terminalF) {
+        testLongTerminal(data, terminalF, LambdaTestHelpers::assertContentsEqual);
+    }
+
+    private List<List<WrappingUnaryOperator<LongStream>>> longPermutationOfFunctions =
+            LambdaTestHelpers.perm(Arrays.asList(
+                    wrap(s -> s.sorted()),
+                    wrap(s -> s.distinct()),
+                    wrap(s -> s.limit(5), true)
+            ));
+
+    private <R> void testLongTerminal(TestData.OfLong data,
+                                      Function<LongStream, R> terminalF,
+                                      BiConsumer<R, R> equalityAsserter) {
+        testTerminal(data, terminalF, equalityAsserter, longPermutationOfFunctions, StreamShape.LONG_VALUE);
+    }
+
+    //
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleTerminalOps(String name, TestData.OfDouble data) {
+        testDoubleTerminal(data, s -> { s.forEach(x -> { }); return 0; });
+        testDoubleTerminal(data, s -> s.findAny(), (a, b) -> assertEquals(a.isPresent(), b.isPresent()));
+        testDoubleTerminal(data, s -> s.anyMatch(e -> true));
+    }
+
+
+    private <T, R> void testDoubleTerminal(TestData.OfDouble data, Function<DoubleStream, R> terminalF) {
+        testDoubleTerminal(data, terminalF, LambdaTestHelpers::assertContentsEqual);
+    }
+
+    private List<List<WrappingUnaryOperator<DoubleStream>>> doublePermutationOfFunctions =
+            LambdaTestHelpers.perm(Arrays.asList(
+                    wrap(s -> s.sorted()),
+                    wrap(s -> s.distinct()),
+                    wrap(s -> s.limit(5), true)
+            ));
+
+    private <R> void testDoubleTerminal(TestData.OfDouble data,
+                                        Function<DoubleStream, R> terminalF,
+                                        BiConsumer<R, R> equalityAsserter) {
+        testTerminal(data, terminalF, equalityAsserter, doublePermutationOfFunctions, StreamShape.DOUBLE_VALUE);
+    }
+
+    //
+
+    private <T, S extends BaseStream<T, S>, R> void testTerminal(TestData<T, S> data,
+                                                                 Function<S, R> terminalF,
+                                                                 BiConsumer<R, R> equalityAsserter,
+                                                                 List<List<WrappingUnaryOperator<S>>> pFunctions,
+                                                                 StreamShape shape) {
+        CheckClearOrderedOp<T> checkClearOrderedOp = new CheckClearOrderedOp<>(shape);
+        for (List<WrappingUnaryOperator<S>> f : pFunctions) {
+            @SuppressWarnings("unchecked")
+            UnaryOperator<S> fi = interpose(f, (S s) -> (S) chain(s, checkClearOrderedOp));
+            withData(data).
+                    terminal(fi, terminalF).
+                    without(TerminalTestScenario.ALL_PARALLEL_SEQUENTIAL).
+                    equalator(equalityAsserter).
+                    exercise();
+        }
+
+        CheckSetOrderedOp<T> checkSetOrderedOp = new CheckSetOrderedOp<>(shape);
+        for (List<WrappingUnaryOperator<S>> f : pFunctions) {
+            @SuppressWarnings("unchecked")
+            UnaryOperator<S> fi = interpose(f, (S s) -> (S) chain(s, checkSetOrderedOp));
+            withData(data).
+                    terminal(fi, s -> terminalF.apply(s.sequential())).
+                    without(TerminalTestScenario.ALL_PARALLEL_SEQUENTIAL).
+                    equalator(equalityAsserter).
+                    exercise();
+        }
+    }
+
+    static class CheckClearOrderedOp<T> implements StatelessTestOp<T, T> {
+        private final StreamShape shape;
+
+        CheckClearOrderedOp(StreamShape shape) {
+            this.shape = shape;
+        }
+
+        @Override
+        public StreamShape outputShape() {
+            return shape;
+        }
+
+        @Override
+        public StreamShape inputShape() {
+            return shape;
+        }
+
+        @Override
+        public Sink<T> opWrapSink(int flags, boolean parallel, Sink<T> sink) {
+            if (parallel) {
+                assertTrue(StreamOpFlag.ORDERED.isCleared(flags));
+            }
+
+            return sink;
+        }
+    }
+
+    static class CheckSetOrderedOp<T> extends CheckClearOrderedOp<T> {
+
+        CheckSetOrderedOp(StreamShape shape) {
+            super(shape);
+        }
+
+        @Override
+        public Sink<T> opWrapSink(int flags, boolean parallel, Sink<T> sink) {
+            assertTrue(StreamOpFlag.ORDERED.isKnown(flags) || StreamOpFlag.ORDERED.isPreserved(flags));
+
+            return sink;
+        }
+    }
+
+    private <T, S extends BaseStream<T, S>>
+    UnaryOperator<S> interpose(List<WrappingUnaryOperator<S>> fs, UnaryOperator<S> fi) {
+        int l = -1;
+        for (int i = 0; i < fs.size(); i++) {
+            if (fs.get(i).isLimit) {
+                l = i;
+            }
+        }
+
+        final int lastLimitIndex = l;
+        return s -> {
+            if (lastLimitIndex == -1)
+                s = fi.apply(s);
+            for (int i = 0; i < fs.size(); i++) {
+                s = fs.get(i).apply(s);
+                if (i >= lastLimitIndex) {
+                    s = fi.apply(s);
+                }
+            }
+            return s;
+        };
+    }
+}
diff --git a/jdk/test/java/util/stream/test/TEST.properties b/jdk/test/java/util/stream/test/TEST.properties
new file mode 100644
index 0000000..4128f6a
--- /dev/null
+++ b/jdk/test/java/util/stream/test/TEST.properties
@@ -0,0 +1,8 @@
+# This file identifies root(s) of the test-ng hierarchy.
+
+TestNG.dirs = .
+
+lib.dirs = /java/util/stream/bootlib
+
+# Tests that must run in othervm mode
+othervm.dirs= /java/util/stream
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/DeserializeMethodTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/DeserializeMethodTest.java
new file mode 100644
index 0000000..67dc982
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/DeserializeMethodTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.lang.invoke;
+
+import org.testng.annotations.Test;
+
+import java.io.Serializable;
+import java.lang.invoke.SerializedLambda;
+import java.lang.reflect.Method;
+
+import static org.testng.Assert.fail;
+
+/**
+ * Ensure that the $deserializeLambda$ method is present when it should be, and absent otherwise
+ */
+
+@Test(groups = { "serialization-hostile" })
+public class DeserializeMethodTest {
+    private void assertDeserializeMethod(Class<?> clazz, boolean expectedPresent) {
+        try {
+            Method m = clazz.getDeclaredMethod("$deserializeLambda$", SerializedLambda.class);
+            if (!expectedPresent)
+                fail("Unexpected $deserializeLambda$ in " + clazz);
+        }
+        catch (NoSuchMethodException e) {
+            if (expectedPresent)
+                fail("Expected to find $deserializeLambda$ in " + clazz);
+        }
+    }
+
+    static class Empty {}
+
+    public void testEmptyClass() {
+        assertDeserializeMethod(Empty.class, false);
+    }
+
+    static class Cap1 {
+        void foo() {
+            Runnable r = (Runnable & Serializable) () -> { };
+        }
+    }
+
+    public void testCapturingSerLambda() {
+        assertDeserializeMethod(Cap1.class, true);
+    }
+
+    static class Cap2 {
+        void foo() {
+            Runnable r = () -> { };
+        }
+    }
+
+    public void testCapturingNonSerLambda() {
+        assertDeserializeMethod(Cap2.class, false);
+    }
+
+    interface Marker { }
+    static class Cap3 {
+        void foo() {
+            Runnable r = (Runnable & Marker) () -> { };
+        }
+    }
+
+    public void testCapturingNonserIntersectionLambda() {
+        assertDeserializeMethod(Cap3.class, false);
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/MHProxiesTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/MHProxiesTest.java
new file mode 100644
index 0000000..9d9829d
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/MHProxiesTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.lang.invoke;
+
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandleProxies;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * MHProxiesTest -- regression test for MH library bug
+ */
+@Test
+public class MHProxiesTest {
+    public interface Sam { double m(int arg); }
+
+    public static Byte m(int arg) { return (byte) arg; }
+
+    public void testProxy() throws NoSuchMethodException, IllegalAccessException {
+        MethodHandle m = MethodHandles.lookup().findStatic(MHProxiesTest.class, "m",
+                                                           MethodType.methodType(Byte.class, int.class));
+        Sam s = MethodHandleProxies.asInterfaceInstance(Sam.class, m);
+        assertEquals(66d, s.m(66));
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/SerializedLambdaTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/SerializedLambdaTest.java
new file mode 100644
index 0000000..5423ac4
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/SerializedLambdaTest.java
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.lang.invoke;
+
+import org.testng.annotations.Test;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.BiPredicate;
+import java.util.function.Consumer;
+import java.util.function.LongConsumer;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+/**
+ * SerializedLambdaTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class SerializedLambdaTest {
+    @SuppressWarnings("unchecked")
+    private<T> void assertSerial(T p, Consumer<T> asserter) throws IOException, ClassNotFoundException {
+        asserter.accept(p);
+
+        byte[] bytes = serialize(p);
+        assertTrue(bytes.length > 0);
+
+        asserter.accept((T) deserialize(bytes));
+    }
+
+    private void assertNotSerial(Predicate<String> p, Consumer<Predicate<String>> asserter)
+            throws IOException, ClassNotFoundException {
+        asserter.accept(p);
+        try {
+            byte[] bytes = serialize(p);
+            fail("Expected serialization failure");
+        }
+        catch (NotSerializableException e) {
+            // success
+        }
+    }
+
+    private byte[] serialize(Object o) throws IOException {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(bos);
+        oos.writeObject(o);
+        oos.close();
+        return bos.toByteArray();
+    }
+
+    private Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
+        try(ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
+            return ois.readObject();
+        }
+    }
+
+    // Test instantiating against intersection type
+    public void testSimpleSerializedInstantiation() throws IOException, ClassNotFoundException {
+        @SuppressWarnings("unchecked")
+        Predicate<String> pred = (Predicate<String> & Serializable) s -> true;
+        assertSerial(pred,
+                     p -> {
+                         assertTrue(p instanceof Predicate);
+                         assertTrue(p instanceof Serializable);
+                         assertTrue(p.test(""));
+                     });
+    }
+
+    interface SerPredicate<T> extends Predicate<T>, Serializable { }
+
+    // Test instantiating against derived type
+    public void testSimpleSerializedInstantiation2() throws IOException, ClassNotFoundException {
+        SerPredicate<String> serPred = (SerPredicate<String>) s -> true;
+        assertSerial(serPred,
+                     p -> {
+                         assertTrue(p instanceof Predicate);
+                         assertTrue(p instanceof Serializable);
+                         assertTrue(p instanceof SerPredicate);
+                         assertTrue(p.test(""));
+                     });
+    }
+
+    // Negative test: non-serializable lambdas are in fact not serializable
+    public void testNonserializableInstantiation() throws IOException, ClassNotFoundException {
+        @SuppressWarnings("unchecked")
+        Predicate<String> pred = (Predicate<String>) s -> true;
+        assertNotSerial(pred,
+                        p -> {
+                            assertTrue(p instanceof Predicate);
+                            assertFalse(p instanceof Serializable);
+                            assertTrue(p.test(""));
+                        });
+    }
+
+    // Test lambda capturing int
+    public void testSerializeCapturingInt() throws IOException, ClassNotFoundException {
+        class Moo {
+            @SuppressWarnings("unchecked")
+            Predicate<String> foo(int x) {
+                return (Predicate<String> & Serializable) s -> s.length() >= x;
+            }
+        }
+        Predicate<String> pred = new Moo().foo(3);
+        assertSerial(pred, p -> {
+            assertTrue(p.test("yada"));
+            assertFalse(p.test("no"));
+        });
+    }
+
+    // Test lambda capturing String
+    public void testSerializeCapturingString() throws IOException, ClassNotFoundException {
+        class Moo {
+            @SuppressWarnings("unchecked")
+            Predicate<String> foo(String t) {
+                return (Predicate<String> & Serializable) s -> s.equals(t);
+            }
+        }
+        Predicate<String> pred = new Moo().foo("goo");
+        assertSerial(pred, p -> {
+            assertTrue(p.test("goo"));
+            assertFalse(p.test("foo"));
+        });
+    }
+
+    // Negative test: lambdas that capture a non-serializable var
+    public void testSerializeCapturingNonSerializable() throws IOException, ClassNotFoundException {
+        class Box {
+            String s;
+
+            Box(String s) { this.s = s; }
+        }
+        class Moo {
+            @SuppressWarnings("unchecked")
+            Predicate<String> foo(Box b) {
+                return (Predicate<String> & Serializable) s -> s.equals(b.s);
+            }
+        }
+        Predicate<String> pred = new Moo().foo(new Box("goo"));
+        assertNotSerial(pred, p -> {
+            assertTrue(p.test("goo"));
+            assertFalse(p.test("foo"));
+        });
+    }
+
+    static boolean startsWithA(String s) {
+        return s.startsWith("a");
+    }
+
+    // Test static method ref
+    public void testStaticMR() throws IOException, ClassNotFoundException {
+        @SuppressWarnings("unchecked")
+        Predicate<String> mh1 = (Predicate<String> & Serializable) SerializedLambdaTest::startsWithA;
+        @SuppressWarnings("unchecked")
+        Predicate<String> mh2 = (SerPredicate<String>) SerializedLambdaTest::startsWithA;
+        Consumer<Predicate<String>> b = p -> {
+            assertTrue(p instanceof Serializable);
+            assertTrue(p.test("arf"));
+            assertFalse(p.test("barf"));
+        };
+        assertSerial(mh1, b);
+        assertSerial(mh2, b);
+    }
+
+    // Test unbound method ref of nonserializable class -- should still succeed
+    public void testUnboundMR() throws IOException, ClassNotFoundException {
+        class Moo {
+            public boolean startsWithB(String s) {
+                return s.startsWith("b");
+            }
+        }
+        @SuppressWarnings("unchecked")
+        BiPredicate<Moo, String> mh1 = (BiPredicate<Moo, String> & Serializable) Moo::startsWithB;
+        Consumer<BiPredicate<Moo, String>> b = p -> {
+            assertTrue(p instanceof Serializable);
+            assertTrue(p.test(new Moo(), "barf"));
+            assertFalse(p.test(new Moo(), "arf"));
+        };
+        assertSerial(mh1, b);
+    }
+
+    // Negative test: test bound MR of nonserializable class
+    public void testBoundMRNotSerReceiver() throws IOException, ClassNotFoundException {
+        class Moo {
+            public boolean startsWithB(String s) {
+                return s.startsWith("b");
+            }
+        }
+        Moo moo = new Moo();
+        @SuppressWarnings("unchecked")
+        Predicate<String> mh1 = (Predicate<String> & Serializable) moo::startsWithB;
+        @SuppressWarnings("unchecked")
+        Predicate<String> mh2 = (SerPredicate<String>) moo::startsWithB;
+        Consumer<Predicate<String>> b = p -> {
+            assertTrue(p instanceof Serializable);
+            assertTrue(p.test("barf"));
+            assertFalse(p.test("arf"));
+        };
+        assertNotSerial(mh1, b);
+        assertNotSerial(mh2, b);
+    }
+
+    // Test bound MR of serializable class
+    @SuppressWarnings("serial")
+    static class ForBoundMRef implements Serializable {
+        public boolean startsWithB(String s) {
+            return s.startsWith("b");
+        }
+    }
+
+    public void testBoundMR() throws IOException, ClassNotFoundException {
+        ForBoundMRef moo = new ForBoundMRef();
+        @SuppressWarnings("unchecked")
+        Predicate<String> mh1 = (Predicate<String> & Serializable) moo::startsWithB;
+        @SuppressWarnings("unchecked")
+        Predicate<String> mh2 = (SerPredicate<String>) moo::startsWithB;
+        Consumer<Predicate<String>> b = p -> {
+            assertTrue(p instanceof Serializable);
+            assertTrue(p.test("barf"));
+            assertFalse(p.test("arf"));
+        };
+        assertSerial(mh1, b);
+        assertSerial(mh2, b);
+    }
+
+    static class ForCtorRef {
+        public boolean startsWithB(String s) {
+            return s.startsWith("b");
+        }
+    }
+    // Test ctor ref of nonserializable class
+    public void testCtorRef() throws IOException, ClassNotFoundException {
+        @SuppressWarnings("unchecked")
+        Supplier<ForCtorRef> ctor = (Supplier<ForCtorRef> & Serializable) ForCtorRef::new;
+        Consumer<Supplier<ForCtorRef>> b = s -> {
+            assertTrue(s instanceof Serializable);
+            ForCtorRef m = s.get();
+            assertTrue(m.startsWithB("barf"));
+            assertFalse(m.startsWithB("arf"));
+        };
+        assertSerial(ctor, b);
+    }
+
+    //Test throwing away return type
+    public void testDiscardReturnBound() throws IOException, ClassNotFoundException {
+        List<String> list = new ArrayList<>();
+        Consumer<String> c = (Consumer<String> & Serializable) list::add;
+        assertSerial(c, cc -> { assertTrue(cc instanceof Consumer); });
+
+        AtomicLong a = new AtomicLong();
+        LongConsumer lc = (LongConsumer & Serializable) a::addAndGet;
+        assertSerial(lc, plc -> { plc.accept(3); });
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/FillableStringTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/FillableStringTest.java
new file mode 100644
index 0000000..5c8a65a
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/FillableStringTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.java.util;
+
+import java.util.Arrays;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+@Test(groups = "lib")
+public class FillableStringTest {
+    public Stream<String> generate() {
+        return Arrays.asList("one", "two", "three", "four", "five", "six").stream()
+                .filter(s->s.length() > 3)
+                .map(String::toUpperCase);
+    }
+
+    public void testStringBuilder() {
+        String s = generate().collect(Collectors.toStringBuilder()).toString();
+        assertEquals(s, "THREEFOURFIVE");
+    }
+
+    public void testStringBuffer() {
+        String s = generate().collect(Collectors.toStringBuilder()).toString();
+        assertEquals(s, "THREEFOURFIVE");
+    }
+
+    public void testStringJoiner() {
+        String s = generate().collect(Collectors.toStringJoiner("-")).toString();
+        assertEquals(s, "THREE-FOUR-FIVE");
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/MapTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/MapTest.java
new file mode 100644
index 0000000..53c7ab1
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/MapTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.java.util;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.LambdaTestHelpers;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Unit tests for extension methods on Map
+ */
+public class MapTest {
+
+    private static final Map<Integer, String> EXPECTED = new HashMap<>();
+
+    private Map<Integer, String> map;
+
+    @BeforeClass
+    public void setUpClass() {
+        EXPECTED.put(0, "zero");
+        EXPECTED.put(1, "one");
+        EXPECTED.put(2, "two");
+        EXPECTED.put(3, "three");
+        EXPECTED.put(4, "four");
+        EXPECTED.put(5, "five");
+        EXPECTED.put(6, "six");
+        EXPECTED.put(7, "seven");
+        EXPECTED.put(8, "eight");
+        EXPECTED.put(9, "nine");
+    }
+
+    @AfterClass
+    public void tearDownClass() {
+        EXPECTED.clear();
+    }
+
+    @BeforeMethod
+    public void setUp() {
+        map = new HashMap<>(EXPECTED);
+    }
+
+    @AfterMethod
+    public void tearDown() {
+        map.clear();
+        map = null;
+    }
+
+    @Test(groups = { "serialization-hostile" })
+    public void testForEach() {
+        final Set<String> values = new HashSet<>(EXPECTED.size());
+        map.forEach((k, v) -> {values.add(v);});
+        LambdaTestHelpers.assertContentsUnordered(values, EXPECTED.values());
+    }
+
+    @Test
+    public void testReplaceAll() {
+        map.replaceAll((k, v) -> {return v.toUpperCase();});
+        for (final Map.Entry<Integer, String> entry : map.entrySet()) {
+            assertEquals(entry.getValue(), EXPECTED.get(entry.getKey()).toUpperCase());
+        }
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/NullArgsTestCase.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/NullArgsTestCase.java
new file mode 100644
index 0000000..eaad768
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/NullArgsTestCase.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util;
+
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.function.Consumer;
+
+import static org.testng.Assert.fail;
+
+/**
+ * NullArgsTestCase -- Given a Consumer&ltObject[]&gt, and an Object[] array of args, call the block with the args,
+ * assert success, and then call the consumer N times, each time setting one of the args to null, and assert that
+ * all these throw NPE.
+ *
+ * Typically this would be combined with a DataProvider that serves up combinations of things to be tested, as in
+ * IteratorsNullTest.
+ */
+public abstract class NullArgsTestCase {
+    public final String name;
+    public final Consumer<Object[]> sink;
+    public final Object[] args;
+
+    protected NullArgsTestCase(String name, Consumer<Object[]> sink, Object[] args) {
+        this.name = name;
+        this.sink = sink;
+        this.args = args;
+    }
+
+    @Test
+    public void goodNonNull() {
+        sink.accept(args);
+    }
+
+    @Test
+    public void throwWithNull() {
+        for (int i=0; i<args.length; i++) {
+            Object[] temp = Arrays.copyOf(args, args.length);
+            temp[i] = null;
+            try {
+                sink.accept(temp);
+                fail(String.format("Expected NullPointerException for argument %d of test case %s", i, name));
+            }
+            catch (NullPointerException e) {
+                // Success
+            }
+        }
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectionAndMapModifyStreamTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectionAndMapModifyStreamTest.java
new file mode 100644
index 0000000..9a74214
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectionAndMapModifyStreamTest.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.LinkedTransferQueue;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.function.Supplier;
+import java.util.stream.LambdaTestHelpers;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.*;
+import java.util.stream.Stream;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * Tests laziness of stream operations -- mutations to the source after the stream() but prior to terminal operations
+ * are reflected in the stream contents.
+ */
+@Test
+public class CollectionAndMapModifyStreamTest {
+
+    @DataProvider(name = "collections")
+    public Object[][] createCollections() {
+        List<Integer> content = LambdaTestHelpers.countTo(10);
+
+        List<Collection<Integer>> collections = new ArrayList<>();
+        collections.add(new ArrayList<>(content));
+        collections.add(new LinkedList<>(content));
+        collections.add(new Vector<>(content));
+
+        collections.add(new HashSet<>(content));
+        collections.add(new LinkedHashSet<>(content));
+        collections.add(new TreeSet<>(content));
+
+        Stack<Integer> stack = new Stack<>();
+        stack.addAll(content);
+        collections.add(stack);
+        collections.add(new PriorityQueue<>(content));
+        collections.add(new ArrayDeque<>(content));
+
+        // Concurrent collections
+
+        collections.add(new ConcurrentSkipListSet<>(content));
+
+        ArrayBlockingQueue<Integer> arrayBlockingQueue = new ArrayBlockingQueue<>(content.size());
+        for (Integer i : content)
+            arrayBlockingQueue.add(i);
+        collections.add(arrayBlockingQueue);
+        collections.add(new PriorityBlockingQueue<>(content));
+        collections.add(new LinkedBlockingQueue<>(content));
+        collections.add(new LinkedTransferQueue<>(content));
+        collections.add(new ConcurrentLinkedQueue<>(content));
+        collections.add(new LinkedBlockingDeque<>(content));
+        collections.add(new ConcurrentLinkedDeque<>(content));
+
+        Object[][] params = new Object[collections.size()][];
+        for (int i = 0; i < collections.size(); i++) {
+            params[i] = new Object[]{collections.get(i).getClass().getName(), collections.get(i)};
+        }
+
+        return params;
+    }
+
+    @Test(dataProvider = "collections")
+    public void testCollectionSizeRemove(String name, Collection<Integer> c) {
+        assertTrue(c.remove(1));
+        Stream<Integer> s = c.stream();
+        assertTrue(c.remove(2));
+        Object[] result = s.toArray();
+        assertEquals(result.length, c.size());
+    }
+
+    @DataProvider(name = "maps")
+    public Object[][] createMaps() {
+        Map<Integer, Integer> content = new HashMap<>();
+        for (int i = 0; i < 10; i++) {
+            content.put(i, i);
+        }
+
+        Map<String, Supplier<Map<Integer, Integer>>> maps = new HashMap<>();
+
+        maps.put(HashMap.class.getName(), () -> new HashMap<>(content));
+        maps.put(HashMap.class.getName(), () -> new LinkedHashMap<>(content));
+        maps.put(IdentityHashMap.class.getName(), () -> new IdentityHashMap<>(content));
+        maps.put(WeakHashMap.class.getName(), () -> new WeakHashMap<>(content));
+
+        maps.put(TreeMap.class.getName(), () -> new TreeMap<>(content));
+        maps.put(TreeMap.class.getName() + ".descendingMap()", () -> new TreeMap<>(content).descendingMap());
+
+        // The following are not lazy
+//        maps.put(TreeMap.class.getName() + ".descendingMap().descendingMap()", () -> new TreeMap<>(content).descendingMap().descendingMap());
+//        maps.put(TreeMap.class.getName() + ".headMap()", () -> new TreeMap<>(content).headMap(content.size() - 1));
+//        maps.put(TreeMap.class.getName() + ".descendingMap().headMap()", () -> new TreeMap<>(content).descendingMap().tailMap(content.size() - 1, false));
+
+        // Concurrent collections
+
+        maps.put(ConcurrentHashMap.class.getName(), () -> new ConcurrentHashMap<>(content));
+        maps.put(ConcurrentSkipListMap.class.getName(), () -> new ConcurrentSkipListMap<>(content));
+
+        Object[][] params = new Object[maps.size()][];
+        int i = 0;
+        for (Map.Entry<String, Supplier<Map<Integer, Integer>>> e : maps.entrySet()) {
+            params[i++] = new Object[]{e.getKey(), e.getValue()};
+
+        }
+
+        return params;
+    }
+
+    @Test(dataProvider = "maps", groups = { "serialization-hostile" })
+    public void testMapKeysSizeRemove(String name, Supplier<Map<Integer, Integer>> c) {
+        testCollectionSizeRemove(name + " key set", c.get().keySet());
+    }
+
+    @Test(dataProvider = "maps", groups = { "serialization-hostile" })
+    public void testMapValuesSizeRemove(String name, Supplier<Map<Integer, Integer>> c) {
+        testCollectionSizeRemove(name + " value set", c.get().values());
+    }
+
+    @Test(dataProvider = "maps")
+    public void testMapEntriesSizeRemove(String name, Supplier<Map<Integer, Integer>> c) {
+        testEntrySetSizeRemove(name + " entry set", c.get().entrySet());
+    }
+
+    private void testEntrySetSizeRemove(String name, Set<Map.Entry<Integer, Integer>> c) {
+        Map.Entry<Integer, Integer> first = c.iterator().next();
+        assertTrue(c.remove(first));
+        Stream<Map.Entry<Integer, Integer>> s = c.stream();
+        Map.Entry<Integer, Integer> second = c.iterator().next();
+        assertTrue(c.remove(second));
+        Object[] result = s.toArray();
+        assertEquals(result.length, c.size());
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/DistinctOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/DistinctOpTest.java
new file mode 100644
index 0000000..cb492f8
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/DistinctOpTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.stream.*;
+
+import static java.util.stream.LambdaTestHelpers.*;
+
+/**
+ * DistinctOpTest
+ */
+@Test
+public class DistinctOpTest extends OpTestCase {
+
+    public void testUniqOp() {
+        assertCountSum(repeat(0, 10).stream().distinct(), 1, 0);
+        assertCountSum(repeat(1, 10).stream().distinct(), 1, 1);
+        assertCountSum(countTo(0).stream().distinct(), 0, 0);
+        assertCountSum(countTo(10).stream().distinct(), 10, 55);
+        assertCountSum(countTo(10).stream().distinct(), 10, 55);
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testOp(String name, TestData.OfRef<Integer> data) {
+        Collection<Integer> result = exerciseOpsInt(data, Stream::distinct, IntStream::distinct, LongStream::distinct, DoubleStream::distinct);
+
+        assertUnique(result);
+        assertTrue((data.size() > 0) ? result.size() > 0 : result.size() == 0);
+        assertTrue(result.size() <= data.size());
+    }
+
+    @Test(dataProvider = "withNull:StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testOpWithNull(String name, TestData.OfRef<Integer> data) {
+        Collection<Integer> node = exerciseOps(data, Stream::distinct);
+        assertUnique(node);
+
+        node = withData(data).
+                stream(s -> s.unordered().distinct()).
+                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
+                exercise();
+        assertUnique(node);
+
+        node = exerciseOps(data, s -> s.distinct().distinct());
+        assertUnique(node);
+    }
+
+    @Test(dataProvider = "withNull:StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testOpWithNullSorted(String name, TestData.OfRef<Integer> data) {
+        List<Integer> l = new ArrayList<>();
+        data.into(l).sort(cNullInteger);
+        // Need to inject SORTED into the sorted list source since
+        // sorted() with a comparator ironically clears SORTED
+        Collection<Integer> node = exerciseOps(new SortedTestData<>(l), Stream::distinct);
+        assertUnique(node);
+        assertSorted(node, cNullInteger);
+    }
+
+    @SuppressWarnings("serial")
+    static class SortedTestData<T> extends TestData.AbstractTestData.RefTestData<T, List<T>> {
+        SortedTestData(List<T> coll) {
+            super("SortedTestData", coll,
+                  c -> StreamSupport.stream(Spliterators.spliterator(c.toArray(), Spliterator.ORDERED | Spliterator.SORTED)),
+                  c -> StreamSupport.parallelStream(Spliterators.spliterator(c.toArray(), Spliterator.ORDERED | Spliterator.SORTED)),
+                  c -> Spliterators.spliterator(c.toArray(), Spliterator.ORDERED | Spliterator.SORTED),
+                  List::size);
+        }
+    }
+
+    public static final Comparator<Integer> cNullInteger = (a, b) -> {
+        if (a == null && b == null) {
+            return 0;
+        }
+        else if (a == null) {
+            return -1;
+        }
+        else if (b == null) {
+            return 1;
+        }
+        else {
+            return Integer.compare(a, b);
+        }
+    };
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testDistinctDistinct(String name, TestData.OfRef<Integer> data) {
+        Collection<Integer> result = withData(data)
+                .stream(s -> s.distinct().distinct(), new CollectorOps.TestParallelSizedOp<>())
+                .exercise();
+        assertUnique(result);
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testDistinctSorted(String name, TestData.OfRef<Integer> data) {
+        Collection<Integer> result = withData(data)
+                .stream(s -> s.distinct().sorted(),
+                        new CollectorOps.TestParallelSizedOp<>())
+                .exercise();
+        assertUnique(result);
+        assertSorted(result);
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testSortedDistinct(String name, TestData.OfRef<Integer> data) {
+        Collection<Integer> result = withData(data)
+                .stream(s -> s.sorted().distinct(),
+                        new CollectorOps.TestParallelSizedOp<>())
+                .exercise();
+        assertUnique(result);
+        assertSorted(result);
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/DoublePrimitiveOpsTests.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/DoublePrimitiveOpsTests.java
new file mode 100644
index 0000000..4a66d1a
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/DoublePrimitiveOpsTests.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Random;
+import java.util.stream.DoubleStream;
+import java.util.stream.LongStream;
+
+import static org.testng.Assert.assertEquals;
+
+@Test
+public class DoublePrimitiveOpsTests {
+
+    // @@@ tests for double are fragile if relying on equality when accumulating and multiplying values
+
+    public void testUnBox() {
+        double sum = Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0).stream().mapToDouble(i -> i).reduce(0.0, Double::sum);
+        assertEquals(sum, 1.0 + 2.0 + 3.0 + 4.0 + 5.0);
+    }
+
+    public void testToArray() {
+        {
+            double[] array =  LongStream.range(1, 10).doubles().map(i -> i * 2).toArray();
+            assertEquals(array, new double[]{2, 4, 6, 8, 10, 12, 14, 16, 18});
+        }
+
+        {
+            double[] array =  LongStream.range(1, 10).parallel().doubles().map(i -> i * 2).toArray();
+            assertEquals(array, new double[]{2, 4, 6, 8, 10, 12, 14, 16, 18});
+        }
+    }
+
+    public void testSort() {
+        Random r = new Random();
+
+        double[] content = DoubleStream.generate(() -> r.nextDouble()).limit(10).toArray();
+        double[] sortedContent = content.clone();
+        Arrays.sort(sortedContent);
+
+        {
+            double[] array =  Arrays.stream(content).sorted().toArray();
+            assertEquals(array, sortedContent);
+        }
+
+        {
+            double[] array =  Arrays.stream(content).parallel().sorted().toArray();
+            assertEquals(array, sortedContent);
+        }
+    }
+
+    public void testSortSort() {
+        Random r = new Random();
+
+        double[] content = DoubleStream.generate(() -> r.nextDouble()).limit(10).toArray();
+        double[] sortedContent = content.clone();
+        Arrays.sort(sortedContent);
+
+        {
+            double[] array =  Arrays.stream(content).sorted().sorted().toArray();
+            assertEquals(array, sortedContent);
+        }
+
+        {
+            double[] array =  Arrays.stream(content).parallel().sorted().sorted().toArray();
+            assertEquals(array, sortedContent);
+        }
+    }
+
+    public void testLimit() {
+        double[] expected = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+
+        {
+            double[] actual = DoubleStream.iterate(1.0, i -> i + 1.0).limit(9).toArray();
+            Assert.assertTrue(Arrays.equals(expected, actual));
+        }
+
+        {
+            double[] actual = LongStream.range(1, 100).parallel().doubles().limit(9).toArray();
+            Assert.assertTrue(Arrays.equals(expected, actual));
+        }
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ExplodeOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ExplodeOpTest.java
new file mode 100644
index 0000000..dcb88fb
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ExplodeOpTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.function.Function;
+import java.util.stream.*;
+
+import static java.util.stream.LambdaTestHelpers.*;
+
+/**
+ * ExplodeOpTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class ExplodeOpTest extends OpTestCase {
+
+    static final Function<Integer, Stream<Integer>> integerRangeMapper
+            = e -> IntStream.range(0, e).boxed();
+
+    public void testFlatMap() {
+        String[] stringsArray = {"hello", "there", "", "yada"};
+        Stream<String> strings = Arrays.asList(stringsArray).stream();
+        assertConcat(strings.flatMap(flattenChars).iterator(), "hellothereyada");
+
+        assertCountSum(countTo(10).stream().flatMap(mfId), 10, 55);
+        assertCountSum(countTo(10).stream().flatMap(mfNull), 0, 0);
+        assertCountSum(countTo(3).stream().flatMap(mfLt), 6, 4);
+
+        exerciseOps(TestData.Factory.ofArray("stringsArray", stringsArray), s -> s.flatMap(flattenChars));
+        exerciseOps(TestData.Factory.ofArray("LONG_STRING", new String[] {LONG_STRING}), s -> s.flatMap(flattenChars));
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfRef<Integer> data) {
+        Collection<Integer> result = exerciseOps(data, s -> s.flatMap(mfId));
+        assertEquals(data.size(), result.size());
+
+        result = exerciseOps(data, s -> s.flatMap(mfNull));
+        assertEquals(0, result.size());
+
+        exerciseOps(data, s -> s.flatMap(mfLt));
+        exerciseOps(data, s -> s.flatMap(integerRangeMapper));
+        exerciseOps(data, s -> s.flatMap((Integer e) -> IntStream.range(0, e).boxed().limit(10)));
+    }
+
+    //
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntOps(String name, TestData.OfInt data) {
+        Collection<Integer> result = exerciseOps(data, s -> s.flatMap(i -> Collections.singleton(i).stream().mapToInt(j -> j)));
+        assertEquals(data.size(), result.size());
+        assertContents(data, result);
+
+        result = exerciseOps(data, s -> s.flatMap(i -> IntStream.empty()));
+        assertEquals(0, result.size());
+
+        exerciseOps(data, s -> s.flatMap(e -> IntStream.range(0, e)));
+        exerciseOps(data, s -> s.flatMap(e -> IntStream.range(0, e).limit(10)));
+    }
+
+    //
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongOps(String name, TestData.OfLong data) {
+        Collection<Long> result = exerciseOps(data, s -> s.flatMap(i -> Collections.singleton(i).stream().mapToLong(j -> j)));
+        assertEquals(data.size(), result.size());
+        assertContents(data, result);
+
+        result = exerciseOps(data, s -> LongStream.empty());
+        assertEquals(0, result.size());
+
+        exerciseOps(data, s -> s.flatMap(e -> LongStream.range(0, e)));
+        exerciseOps(data, s -> s.flatMap(e -> LongStream.range(0, e).limit(10)));
+    }
+
+    //
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleOps(String name, TestData.OfDouble data) {
+        Collection<Double> result = exerciseOps(data, s -> s.flatMap(i -> Collections.singleton(i).stream().mapToDouble(j -> j)));
+        assertEquals(data.size(), result.size());
+        assertContents(data, result);
+
+        result = exerciseOps(data, s -> DoubleStream.empty());
+        assertEquals(0, result.size());
+
+        exerciseOps(data, s -> s.flatMap(e -> DoubleStream.range(0, e)));
+        exerciseOps(data, s -> s.flatMap(e -> DoubleStream.range(0, e).limit(10)));
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FilterOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FilterOpTest.java
new file mode 100644
index 0000000..12ff052
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FilterOpTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.Collection;
+import java.util.stream.*;
+
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+
+import static java.util.stream.LambdaTestHelpers.*;
+
+/**
+ * FilterOpTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class FilterOpTest extends OpTestCase {
+    public void testFilter() {
+        assertCountSum(countTo(0).stream().filter(pTrue), 0, 0);
+        assertCountSum(countTo(10).stream().filter(pFalse), 0, 0);
+        assertCountSum(countTo(10).stream().filter(pEven), 5, 30);
+        assertCountSum(countTo(10).stream().filter(pOdd), 5, 25);
+        assertCountSum(countTo(10).stream().filter(pTrue), 10, 55);
+        assertCountSum(countTo(10).stream().filter(pEven).filter(pOdd), 0, 0);
+
+        exerciseOps(countTo(1000), s -> s.filter(pTrue), countTo(1000));
+        exerciseOps(countTo(1000), s -> s.filter(pFalse), countTo(0));
+        exerciseOps(countTo(1000), s -> s.filter(e -> e > 100), range(101, 1000));
+        exerciseOps(countTo(1000), s -> s.filter(e -> e < 100), countTo(99));
+        exerciseOps(countTo(1000), s -> s.filter(e -> e == 100), Arrays.asList(100));
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfRef<Integer> data) {
+        Collection<Integer> result = exerciseOps(data, s -> s.filter(pTrue));
+        assertEquals(result.size(), data.size());
+
+        result = exerciseOps(data, s -> s.filter(pFalse));
+        assertEquals(result.size(), 0);
+
+        exerciseOps(data, s -> s.filter(pEven));
+        exerciseOps(data, s -> s.filter(pOdd));
+
+        result = exerciseOps(data, s -> s.filter(pOdd.and(pEven)));
+        assertEquals(result.size(), 0);
+
+        result = exerciseOps(data, s -> s.filter(pOdd.or(pEven)));
+        assertEquals(result.size(), data.size());
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfInt data) {
+        Collection<Integer> result = exerciseOps(data, s -> s.filter(i -> true));
+        assertEquals(result.size(), data.size());
+
+        result = exerciseOps(data, s -> s.filter(i -> false));
+        assertEquals(result.size(), 0);
+
+        exerciseOps(data, s -> s.filter(i -> 0 == i % 2));
+        exerciseOps(data, s -> s.filter(i -> 1 == i % 2));
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfLong data) {
+        Collection<Long> result = exerciseOps(data, s -> s.filter(i -> true));
+        assertEquals(result.size(), data.size());
+
+        result = exerciseOps(data, s -> s.filter(i -> false));
+        assertEquals(result.size(), 0);
+
+        exerciseOps(data, s -> s.filter(i -> 0 == i % 2));
+        exerciseOps(data, s -> s.filter(i -> 1 == i % 2));
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfDouble data) {
+        Collection<Double> result = exerciseOps(data, s -> s.filter(i -> true));
+        assertEquals(result.size(), data.size());
+
+        result = exerciseOps(data, s -> s.filter(i -> false));
+        assertEquals(result.size(), 0);
+
+        exerciseOps(data, s -> s.filter(i -> 0 == ((long) i) % 2));
+        exerciseOps(data, s -> s.filter(i -> 1 == ((long) i) % 2));
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FindAnyOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FindAnyOpTest.java
new file mode 100644
index 0000000..64a9240
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FindAnyOpTest.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.*;
+import java.util.function.BiConsumer;
+import java.util.stream.*;
+
+import org.testng.annotations.Test;
+
+import java.util.function.Function;
+
+import static java.util.stream.LambdaTestHelpers.*;
+
+
+/**
+ * FindAnyOpTest
+ */
+@Test
+public class FindAnyOpTest extends OpTestCase {
+
+    public void testFindAny() {
+        assertFalse(Collections.emptySet().stream().findAny().isPresent(), "no result");
+        assertFalse(countTo(10).stream().filter(x -> x > 10).findAny().isPresent(), "no result");
+        assertTrue(countTo(10).stream().filter(pEven).findAny().isPresent(), "with result");
+    }
+
+    public void testFindAnyParallel() {
+        assertFalse(Collections.emptySet().parallelStream().findAny().isPresent(), "no result");
+        assertFalse(countTo(1000).parallelStream().filter(x -> x > 1000).findAny().isPresent(), "no result");
+        assertTrue(countTo(1000).parallelStream().filter(pEven).findAny().isPresent(), "with result");
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testStream(String name, TestData.OfRef<Integer> data) {
+        exerciseStream(data, s -> s);
+        exerciseStream(data, s -> s.filter(pTrue));
+        exerciseStream(data, s -> s.filter(pFalse));
+        exerciseStream(data, s -> s.filter(pEven));
+    }
+
+    void exerciseStream(TestData.OfRef<Integer> data, Function<Stream<Integer>, Stream<Integer>> fs) {
+        Optional<Integer> or = withData(data).terminal(fs, s -> s.findAny()).equalator(VALID_ANSWER).exercise();
+        if (or.isPresent()) {
+            Integer r = or.get();
+            Iterator<Integer> it = fs.apply(data.stream()).iterator();
+            boolean contained = false;
+            while (!contained && it.hasNext()) {
+                contained = Objects.equals(r, it.next());
+            }
+            assertTrue(contained);
+        }
+        else {
+            assertFalse(fs.apply(data.stream()).iterator().hasNext());
+        }
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntStream(String name, TestData.OfInt data) {
+        exerciseIntStream(data, s -> s);
+        exerciseIntStream(data, s -> s.filter(ipTrue));
+        exerciseIntStream(data, s -> s.filter(ipFalse));
+        exerciseIntStream(data, s -> s.filter(ipEven));
+    }
+
+    void exerciseIntStream(TestData.OfInt data, Function<IntStream, IntStream> fs) {
+        OptionalInt or = withData(data).terminal(fs, s -> s.findAny()).equalator(INT_VALID_ANSWER).exercise();
+        if (or.isPresent()) {
+            int r = or.getAsInt();
+            PrimitiveIterator.OfInt it = fs.apply(data.stream()).iterator();
+            boolean contained = false;
+            while (!contained && it.hasNext()) {
+                contained = r == it.nextInt();
+            }
+            assertTrue(contained);
+        }
+        else {
+            assertFalse(fs.apply(data.stream()).iterator().hasNext());
+        }
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongStream(String name, TestData.OfLong data) {
+        exerciseLongStream(data, s -> s);
+        exerciseLongStream(data, s -> s.filter(lpTrue));
+        exerciseLongStream(data, s -> s.filter(lpFalse));
+        exerciseLongStream(data, s -> s.filter(lpEven));
+    }
+
+    void exerciseLongStream(TestData.OfLong data, Function<LongStream, LongStream> fs) {
+        OptionalLong or = withData(data).terminal(fs, s -> s.findAny()).equalator(LONG_VALID_ANSWER).exercise();
+        if (or.isPresent()) {
+            long r = or.getAsLong();
+            PrimitiveIterator.OfLong it = fs.apply(data.stream()).iterator();
+            boolean contained = false;
+            while (!contained && it.hasNext()) {
+                contained = r == it.nextLong();
+            }
+            assertTrue(contained);
+        }
+        else {
+            assertFalse(fs.apply(data.stream()).iterator().hasNext());
+        }
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleStream(String name, TestData.OfDouble data) {
+        exerciseDoubleStream(data, s -> s);
+        exerciseDoubleStream(data, s -> s.filter(dpTrue));
+        exerciseDoubleStream(data, s -> s.filter(dpEven));
+        exerciseDoubleStream(data, s -> s.filter(dpFalse));
+    }
+
+    void exerciseDoubleStream(TestData.OfDouble data, Function<DoubleStream, DoubleStream> fs) {
+        OptionalDouble or = withData(data).terminal(fs, s -> s.findAny()).equalator(DOUBLE_VALID_ANSWER).exercise();
+        if (or.isPresent()) {
+            double r = or.getAsDouble();
+            PrimitiveIterator.OfDouble it = fs.apply(data.stream()).iterator();
+            boolean contained = false;
+            while (!contained && it.hasNext()) {
+                contained = r == it.nextDouble();
+            }
+            assertTrue(contained);
+        }
+        else {
+            assertFalse(fs.apply(data.stream()).iterator().hasNext());
+        }
+    }
+
+    static final BiConsumer<Optional<Integer>, Optional<Integer>> VALID_ANSWER = (a, b) -> assertEquals(a.isPresent(), b.isPresent());
+
+    static final BiConsumer<OptionalInt, OptionalInt> INT_VALID_ANSWER = (a, b) -> assertEquals(a.isPresent(), b.isPresent());
+
+    static final BiConsumer<OptionalLong, OptionalLong> LONG_VALID_ANSWER = (a, b) -> assertEquals(a.isPresent(), b.isPresent());
+
+    static final BiConsumer<OptionalDouble, OptionalDouble> DOUBLE_VALID_ANSWER = (a, b) -> assertEquals(a.isPresent(), b.isPresent());
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FindFirstOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FindFirstOpTest.java
new file mode 100644
index 0000000..02e3d07
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FindFirstOpTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.*;
+import java.util.stream.*;
+
+import org.testng.annotations.Test;
+
+import java.util.function.Function;
+
+import static java.util.stream.LambdaTestHelpers.*;
+
+
+/**
+ * FindFirstOpTest
+ */
+@Test
+public class FindFirstOpTest extends OpTestCase {
+
+    public void testFindFirst() {
+        assertFalse(Collections.emptySet().stream().findFirst().isPresent(), "no result");
+        assertFalse(countTo(10).stream().filter(x -> x > 10).findFirst().isPresent(), "no result");
+
+        exerciseOps(countTo(1000), s -> Arrays.asList(new Integer[]{s.filter(pEven).findFirst().get()}).stream(), Arrays.asList(2));
+        exerciseOps(countTo(1000), s -> Arrays.asList(new Integer[]{s.findFirst().get()}).stream(), Arrays.asList(1));
+        exerciseOps(countTo(1000), s -> Arrays.asList(new Integer[]{s.filter(e -> e == 499).findFirst().get()}).stream(), Arrays.asList(499));
+        exerciseOps(countTo(1000), s -> Arrays.asList(new Integer[]{s.filter(e -> e == 999).findFirst().get()}).stream(), Arrays.asList(999));
+        exerciseOps(countTo(0), s -> Arrays.asList(new Integer[]{s.findFirst().orElse(-1)}).stream(), Arrays.asList(-1));
+        exerciseOps(countTo(1000), s -> Arrays.asList(new Integer[]{s.filter(e -> e == 1499).findFirst().orElse(-1)}).stream(), Arrays.asList(-1));
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testStream(String name, TestData.OfRef<Integer> data) {
+        exerciseStream(data, s -> s);
+        exerciseStream(data, s -> s.filter(pTrue));
+        exerciseStream(data, s -> s.filter(pFalse));
+        exerciseStream(data, s -> s.filter(pEven));
+    }
+
+    void exerciseStream(TestData.OfRef<Integer> data, Function<Stream<Integer>, Stream<Integer>> fs) {
+        Optional<Integer> r = exerciseTerminalOps(data, fs, s -> s.findFirst());
+        if (r.isPresent()) {
+            Iterator<Integer> i = fs.apply(data.stream()).iterator();
+            assertTrue(i.hasNext());
+            assertEquals(i.next(), r.get());
+        }
+        else {
+            assertFalse(fs.apply(data.stream()).iterator().hasNext());
+        }
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntStream(String name, TestData.OfInt data) {
+        exerciseIntStream(data, s -> s);
+        exerciseIntStream(data, s -> s.filter(ipTrue));
+        exerciseIntStream(data, s -> s.filter(ipFalse));
+        exerciseIntStream(data, s -> s.filter(ipEven));
+    }
+
+    void exerciseIntStream(TestData.OfInt data, Function<IntStream, IntStream> fs) {
+        OptionalInt r = exerciseTerminalOps(data, fs, s -> s.findFirst());
+        if (r.isPresent()) {
+            PrimitiveIterator.OfInt i = fs.apply(data.stream()).iterator();
+            assertTrue(i.hasNext());
+            assertEquals(i.nextInt(), r.getAsInt());
+        }
+        else {
+            assertFalse(fs.apply(data.stream()).iterator().hasNext());
+        }
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongStream(String name, TestData.OfLong data) {
+        exerciseLongStream(data, s -> s);
+        exerciseLongStream(data, s -> s.filter(lpTrue));
+        exerciseLongStream(data, s -> s.filter(lpFalse));
+        exerciseLongStream(data, s -> s.filter(lpEven));
+    }
+
+    void exerciseLongStream(TestData.OfLong data, Function<LongStream, LongStream> fs) {
+        OptionalLong r = exerciseTerminalOps(data, fs, s -> s.findFirst());
+        if (r.isPresent()) {
+            PrimitiveIterator.OfLong i = fs.apply(data.stream()).iterator();
+            assertTrue(i.hasNext());
+            assertEquals(i.nextLong(), r.getAsLong());
+        }
+        else {
+            assertFalse(fs.apply(data.stream()).iterator().hasNext());
+        }
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleStream(String name, TestData.OfDouble data) {
+        exerciseDoubleStream(data, s -> s);
+        exerciseDoubleStream(data, s -> s.filter(dpTrue));
+        exerciseDoubleStream(data, s -> s.filter(dpFalse));
+        exerciseDoubleStream(data, s -> s.filter(dpEven));
+    }
+
+    void exerciseDoubleStream(TestData.OfDouble data, Function<DoubleStream, DoubleStream> fs) {
+        OptionalDouble r = exerciseTerminalOps(data, fs, s -> s.findFirst());
+        if (r.isPresent()) {
+            PrimitiveIterator.OfDouble i = fs.apply(data.stream()).iterator();
+            assertTrue(i.hasNext());
+            assertEquals(i.nextDouble(), r.getAsDouble());
+        }
+        else {
+            assertFalse(fs.apply(data.stream()).iterator().hasNext());
+        }
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ForEachOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ForEachOpTest.java
new file mode 100644
index 0000000..4a078a4
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ForEachOpTest.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
+import java.util.stream.*;
+
+import static java.util.stream.LambdaTestHelpers.countTo;
+
+/**
+ * ForEachOpTest
+ */
+@Test
+public class ForEachOpTest extends OpTestCase {
+
+    @Test(groups = { "serialization-hostile" })
+    public void testForEach() {
+        exerciseTerminalOps(countTo(10),
+                            s -> {
+                                AtomicInteger count = new AtomicInteger(0);
+                                s.forEach(e -> count.incrementAndGet());
+                                return count.get();
+                            },
+                            10);
+
+        exerciseTerminalOps(countTo(10),
+                            s -> {
+                                AtomicInteger sum = new AtomicInteger(0);
+                                s.forEach(sum::addAndGet);
+                                return sum.get();
+                            },
+                            55);
+    }
+
+    @Test
+    public void testForEachOrdered() {
+        List<Integer> input = countTo(10000);
+        TestData.OfRef<Integer> data = TestData.Factory.ofCollection("[1, 10000]", input);
+
+        Function<Stream<Integer>, List<Integer>> terminalFunc = s -> {
+            List<Integer> l = new ArrayList<>();
+            s.forEachOrdered(l::add);
+            return l;
+        };
+
+        // Test head
+        withData(data).
+                terminal(terminalFunc).
+                expectedResult(input).
+                exercise();
+
+        // Test multiple stages
+        withData(data).
+                terminal(s -> s.map(LambdaTestHelpers.identity()), terminalFunc).
+                expectedResult(input).
+                exercise();
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testForEach(String name, TestData.OfRef<Integer> data) {
+        Function<Stream<Integer>, List<Integer>> terminalFunc = s -> {
+            List<Integer> l = Collections.synchronizedList(new ArrayList<>());
+            s.forEach(l::add);
+            return l;
+        };
+
+        // Test head
+        withData(data).
+                terminal(terminalFunc).
+                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
+                exercise();
+
+        // Test multiple stages
+        withData(data).
+                terminal(s -> s.map(LambdaTestHelpers.identity()), terminalFunc).
+                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
+                exercise();
+    }
+
+    //
+
+    @Test
+    public void testIntForEachOrdered() {
+        List<Integer> input = countTo(10000);
+        TestData.OfInt data = TestData.Factory.ofIntSupplier("[1, 10000]",
+                                                             () -> IntStream.range(1, 10001));
+
+        Function<IntStream, List<Integer>> terminalFunc = s -> {
+            List<Integer> l = new ArrayList<>();
+            s.forEachOrdered(l::add);
+            return l;
+        };
+
+        // Test head
+        withData(data).
+                terminal(terminalFunc).
+                expectedResult(input).
+                exercise();
+
+        // Test multiple stages
+        withData(data).
+                terminal(s -> s.map(i -> i), terminalFunc).
+                expectedResult(input).
+                exercise();
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntForEach(String name, TestData.OfInt data) {
+        Function<IntStream, List<Integer>> terminalFunc = s -> {
+            List<Integer> l = Collections.synchronizedList(new ArrayList<Integer>());
+            s.forEach(l::add);
+            return l;
+        };
+
+        // Test head
+        withData(data).
+                terminal(terminalFunc).
+                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
+                exercise();
+
+        // Test multiple stages
+        withData(data).
+                terminal(s -> s.map(i -> i), terminalFunc).
+                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
+                exercise();
+    }
+
+    //
+
+    @Test
+    public void testLongForEachOrdered() {
+        List<Integer> input = countTo(10000);
+        TestData.OfLong data = TestData.Factory.ofLongSupplier("[1, 10000]",
+                                                               () -> LongStream.range(1, 10001));
+
+        Function<LongStream, List<Integer>> terminalFunc = s -> {
+            List<Integer> l = new ArrayList<>();
+            s.forEachOrdered(e -> l.add((int) e));
+            return l;
+        };
+
+        // Test head
+        withData(data).
+                terminal(terminalFunc).
+                expectedResult(input).
+                exercise();
+
+        // Test multiple stages
+        withData(data).
+                terminal(s -> s.map(i -> i), terminalFunc).
+                expectedResult(input).
+                exercise();
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongOps(String name, TestData.OfLong data) {
+        Function<LongStream, List<Long>> terminalFunc = s -> {
+            List<Long> l = Collections.synchronizedList(new ArrayList<Long>());
+            s.forEach(l::add);
+            return l;
+        };
+
+        // Test head
+        withData(data).
+                terminal(terminalFunc).
+                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
+                exercise();
+
+        // Test multiple stages
+        withData(data).
+                terminal(s -> s.map(i -> i), terminalFunc).
+                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
+                exercise();
+    }
+
+    //
+
+    @Test
+    public void testDoubleForEachOrdered() {
+        List<Integer> input = countTo(10000);
+        TestData.OfDouble data = TestData.Factory.ofDoubleSupplier("[1, 10000]",
+                                                                   () -> DoubleStream.range(1, 10001));
+
+        Function<DoubleStream, List<Integer>> terminalFunc = s -> {
+            List<Integer> l = new ArrayList<>();
+            s.forEachOrdered(e -> l.add((int) e));
+            return l;
+        };
+
+        // Test head
+        withData(data).
+                terminal(terminalFunc).
+                expectedResult(input).
+                exercise();
+
+        // Test multiple stages
+        withData(data).
+                terminal(s -> s.map(i -> i), terminalFunc).
+                expectedResult(input).
+                exercise();
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleOps(String name, TestData.OfDouble data) {
+        Function<DoubleStream, List<Double>> terminalFunc = s -> {
+            List<Double> l = Collections.synchronizedList(new ArrayList<Double>());
+            s.forEach(l::add);
+            return l;
+        };
+
+        // Test head
+        withData(data).
+                terminal(terminalFunc).
+                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
+                exercise();
+
+        // Test multiple stages
+        withData(data).
+                terminal(s -> s.map(i -> i), terminalFunc).
+                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
+                exercise();
+    }
+
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/GroupByOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/GroupByOpTest.java
new file mode 100644
index 0000000..7c6d695
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/GroupByOpTest.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+import java.util.stream.LambdaTestHelpers;
+import java.util.stream.OpTestCase;
+import java.util.stream.Stream;
+import java.util.stream.StreamOpFlagTestHelper;
+import java.util.stream.StreamTestDataProvider;
+import java.util.stream.TestData;
+
+import org.testng.annotations.Test;
+
+import static java.util.stream.LambdaTestHelpers.countTo;
+import static java.util.stream.LambdaTestHelpers.mDoubler;
+import static java.util.stream.LambdaTestHelpers.mId;
+import static java.util.stream.LambdaTestHelpers.mZero;
+import static java.util.stream.LambdaTestHelpers.pEven;
+import static java.util.stream.LambdaTestHelpers.pFalse;
+import static java.util.stream.LambdaTestHelpers.pOdd;
+import static java.util.stream.LambdaTestHelpers.pTrue;
+
+/**
+ * GroupByOpTest
+ *
+ */
+@Test
+public class GroupByOpTest extends OpTestCase {
+
+    public void testBypassCollect() {
+        Collector<Integer, Map<Boolean, List<Integer>>> collector
+                = Collectors.groupingBy(LambdaTestHelpers.forPredicate(pEven, true, false));
+
+        Map<Boolean, List<Integer>> m = collector.resultSupplier().get();
+        int[] ints = countTo(10).stream().mapToInt(e -> (int) e).toArray();
+        for (int i : ints)
+            m = collector.accumulator().apply(m, i);
+
+        assertEquals(2, m.keySet().size());
+        for(Collection<Integer> group : m.values()) {
+            int count = 0;
+            Stream<Integer> stream = group.stream();
+            Iterator<Integer> it = stream.iterator();
+            while (it.hasNext()) {
+                it.next();
+                ++count;
+            }
+            assertEquals(5, count);
+        }
+    }
+
+    public void testGroupBy() {
+        Map<Boolean,List<Integer>> result = countTo(10).stream().collect(Collectors.groupingBy(LambdaTestHelpers.forPredicate(pEven, true, false)));
+
+        assertEquals(2, result.keySet().size());
+        for(Collection<Integer> group : result.values()) {
+            int count = 0;
+            Stream<Integer> stream = group.stream();
+            Iterator<Integer> it = stream.iterator();
+            while (it.hasNext()) {
+                it.next();
+                ++count;
+            }
+            assertEquals(5, count);
+        }
+    }
+
+    static class MapperData<T, K> {
+        Function<T, K> m;
+        int expectedSize;
+
+        MapperData(Function<T, K> m, int expectedSize) {
+            this.m = m;
+            this.expectedSize = expectedSize;
+        }
+    }
+
+    List<MapperData<Integer, ?>> getMapperData(TestData.OfRef<Integer> data) {
+        int uniqueSize = data.into(new HashSet<>()).size();
+
+        return Arrays.asList(
+            new MapperData<>(mId, uniqueSize),
+            new MapperData<>(mZero, Math.min(1, data.size())),
+            new MapperData<>(mDoubler, uniqueSize),
+            new MapperData<>(LambdaTestHelpers.compose(mId, mDoubler), uniqueSize),
+            new MapperData<>(LambdaTestHelpers.compose(mDoubler, mDoubler), uniqueSize),
+
+            new MapperData<>(LambdaTestHelpers.forPredicate(pFalse, true, false), Math.min(1, uniqueSize)),
+            new MapperData<>(LambdaTestHelpers.forPredicate(pTrue, true, false), Math.min(1, uniqueSize)),
+            new MapperData<>(LambdaTestHelpers.forPredicate(pEven, true, false), Math.min(2, uniqueSize)),
+            new MapperData<>(LambdaTestHelpers.forPredicate(pOdd, true, false), Math.min(2, uniqueSize))
+        );
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfRef<Integer> data) {
+        // @@@ More things to test here:
+        //     - Every value in data is present in right bucket
+        //     - Total number of values equals size of data
+
+        for (MapperData<Integer, ?> md : getMapperData(data)) {
+            Collector<Integer, Map<Object, List<Integer>>> tab = Collectors.groupingBy(md.m);
+            Map<Object, List<Integer>> result =
+                    withData(data)
+                            .terminal(s -> s, s -> s.collect(tab))
+                            .parallelEqualityAsserter(s -> StreamOpFlagTestHelper.isStreamOrdered(s) ? GroupByOpTest::assertObjectEquals : GroupByOpTest::assertMultiMapEquals)
+                            .exercise();
+            assertEquals(result.keySet().size(), md.expectedSize);
+        }
+    }
+
+    static void assertObjectEquals(Object a, Object b) {
+        assertTrue(Objects.equals(a, b));
+    }
+
+    static <K, V> void assertMultiMapEquals(Map<K, ? extends Collection<V>> a, Map<K, ? extends Collection<V>> b) {
+        assertTrue(multiMapEquals(a, b));
+    }
+
+    static<K, V> boolean multiMapEquals(Map<K, ? extends Collection<V>> a, Map<K, ? extends Collection<V>> b) {
+        if (!Objects.equals(a.keySet(), b.keySet())) {
+            return false;
+        }
+
+        for (K k : a.keySet()) {
+            Set<V> as = new HashSet<>(a.get(k));
+            Set<V> bs = new HashSet<>(b.get(k));
+            if (!Objects.equals(as, bs)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/InfiniteStreamWithLimitOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/InfiniteStreamWithLimitOpTest.java
new file mode 100644
index 0000000..a43802c
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/InfiniteStreamWithLimitOpTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.stream.OpTestCase;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static java.util.stream.LambdaTestHelpers.assertContents;
+
+
+@Test
+public class InfiniteStreamWithLimitOpTest extends OpTestCase {
+
+    private static final List<String> tenAs = Arrays.asList("A", "A", "A", "A", "A", "A", "A", "A", "A", "A");
+
+    public void testRepeatLimit() {
+        assertContents(Stream.generate(() -> "A").limit(10).iterator(), tenAs.iterator());
+    }
+
+    public void testIterateLimit() {
+        assertContents(Stream.iterate("A", s -> s).limit(10).iterator(), tenAs.iterator());
+    }
+
+    public void testIterateFibLimit() {
+        Stream<Integer> fib = Stream.iterate(new int[] {0, 1}, pair -> new int[] {pair[1], pair[0] + pair[1]})
+                                    .map(pair -> pair[0]);
+
+        assertContents(
+                fib.limit(10).iterator(),
+                Arrays.asList(0, 1, 1, 2, 3, 5, 8, 13, 21, 34).iterator());
+    }
+
+    public void testInfiniteWithLimitToShortCircuitTerminal() {
+        Object[] array = Stream.generate(() -> 1).limit(4).toArray();
+        assertEquals(4, array.length);
+        array = Stream.generate(() -> 1).limit(4).filter(i -> true).toArray();
+        assertEquals(4, array.length);
+        List<Integer> result = Stream.generate(() -> 1).limit(4).collect(Collectors.toList());
+        assertEquals(result, Arrays.asList(1, 1, 1, 1));
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntPrimitiveOpsTests.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntPrimitiveOpsTests.java
new file mode 100644
index 0000000..1efc5fd
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntPrimitiveOpsTests.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.IntConsumer;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import static org.testng.Assert.assertEquals;
+
+@Test
+public class IntPrimitiveOpsTests {
+
+    public void testSum() {
+        long sum = IntStream.range(1, 10).filter(i -> i % 2 == 0).sum();
+        assertEquals(sum, 20);
+    }
+
+    public void testMap() {
+        long sum = IntStream.range(1, 10).filter(i -> i % 2 == 0).map(i -> i * 2).sum();
+        assertEquals(sum, 40);
+    }
+
+    public void testParSum() {
+        long sum = IntStream.range(1, 10).parallel().filter(i -> i % 2 == 0).sum();
+        assertEquals(sum, 20);
+    }
+
+    @Test(groups = { "serialization-hostile" })
+    public void testTee() {
+        int[] teeSum = new int[1];
+        long sum = IntStream.range(1, 10).filter(i -> i % 2 == 0).peek(i -> { teeSum[0] = teeSum[0] + i; }).sum();
+        assertEquals(teeSum[0], sum);
+    }
+
+    @Test(groups = { "serialization-hostile" })
+    public void testForEach() {
+        int[] sum = new int[1];
+        IntStream.range(1, 10).filter(i -> i % 2 == 0).forEach(i -> { sum[0] = sum[0] + i; });
+        assertEquals(sum[0], 20);
+    }
+
+    @Test(groups = { "serialization-hostile" })
+    public void testParForEach() {
+        AtomicInteger ai = new AtomicInteger(0);
+        IntStream.range(1, 10).parallel().filter(i -> i % 2 == 0).forEach(ai::addAndGet);
+        assertEquals(ai.get(), 20);
+    }
+
+    public void testBox() {
+        List<Integer> l = IntStream.range(1, 10).parallel().boxed().collect(Collectors.toList());
+        int sum = l.stream().reduce(0, (a, b) -> a + b);
+        assertEquals(sum, 45);
+    }
+
+    public void testUnBox() {
+        long sum = Arrays.asList(1, 2, 3, 4, 5).stream().mapToInt(i -> (int) i).sum();
+        assertEquals(sum, 15);
+    }
+
+    public void testToArray() {
+        {
+            int[] array =  IntStream.range(1, 10).map(i -> i * 2).toArray();
+            assertEquals(array, new int[]{2, 4, 6, 8, 10, 12, 14, 16, 18});
+        }
+
+        {
+            int[] array =  IntStream.range(1, 10).parallel().map(i -> i * 2).toArray();
+            assertEquals(array, new int[]{2, 4, 6, 8, 10, 12, 14, 16, 18});
+        }
+    }
+
+    public void testSort() {
+        Random r = new Random();
+
+        int[] content = IntStream.generate(() -> r.nextInt(100)).limit(10).toArray();
+        int[] sortedContent = content.clone();
+        Arrays.sort(sortedContent);
+
+        {
+            int[] array =  Arrays.stream(content).sorted().toArray();
+            assertEquals(array, sortedContent);
+        }
+
+        {
+            int[] array =  Arrays.stream(content).parallel().sorted().toArray();
+            assertEquals(array, sortedContent);
+        }
+    }
+
+    public void testSortSort() {
+        Random r = new Random();
+
+        int[] content = IntStream.generate(() -> r.nextInt(100)).limit(10).toArray();
+        int[] sortedContent = content.clone();
+        Arrays.sort(sortedContent);
+
+        {
+            int[] array =  Arrays.stream(content).sorted().sorted().toArray();
+            assertEquals(array, sortedContent);
+        }
+
+        {
+            int[] array =  Arrays.stream(content).parallel().sorted().sorted().toArray();
+            assertEquals(array, sortedContent);
+        }
+    }
+
+    public void testSequential() {
+
+        int[] expected = IntStream.range(1, 1000).toArray();
+
+        class AssertingConsumer implements IntConsumer {
+            private final int[] array;
+            int offset;
+
+            AssertingConsumer(int[] array) {
+                this.array = array;
+            }
+
+            @Override
+            public void accept(int value) {
+                assertEquals(array[offset++], value);
+            }
+
+            public int getCount() { return offset; }
+        }
+
+        {
+            AssertingConsumer consumer = new AssertingConsumer(expected);
+            IntStream.range(1, 1000).sequential().forEach(consumer);
+            assertEquals(expected.length, consumer.getCount());
+        }
+
+        {
+            AssertingConsumer consumer = new AssertingConsumer(expected);
+            IntStream.range(1, 1000).parallel().sequential().forEach(consumer);
+            assertEquals(expected.length, consumer.getCount());
+        }
+    }
+
+    public void testLimit() {
+        int[] expected = IntStream.range(1, 10).toArray();
+
+        {
+            int[] actual = IntStream.iterate(1, i -> i + 1).limit(9).toArray();
+            Assert.assertTrue(Arrays.equals(expected, actual));
+        }
+
+        {
+            int[] actual = IntStream.range(1, 100).parallel().limit(9).toArray();
+            Assert.assertTrue(Arrays.equals(expected, actual));
+        }
+    }
+
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntReduceTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntReduceTest.java
new file mode 100644
index 0000000..baf9007
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntReduceTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.stream.IntStream;
+import java.util.stream.IntStreamTestDataProvider;
+import java.util.stream.OpTestCase;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.OptionalInt;
+import java.util.stream.TestData;
+
+import static java.util.stream.LambdaTestHelpers.*;
+
+public class IntReduceTest extends OpTestCase {
+    public void testReduce() {
+        int[] a = IntStream.range(1, 11).toArray();
+
+        assertEquals(55, Arrays.stream(a).reduce(irPlus).getAsInt());
+        assertEquals(55, Arrays.stream(a).reduce(0, irPlus));
+        assertEquals(10, Arrays.stream(a).reduce(irMax).getAsInt());
+        assertEquals(1, Arrays.stream(a).reduce(irMin).getAsInt());
+
+        assertEquals(0, IntStream.empty().reduce(0, irPlus));
+        assertFalse(IntStream.empty().reduce(irPlus).isPresent());
+
+        assertEquals(110, Arrays.stream(a).map(irDoubler).reduce(irPlus).getAsInt());
+        assertEquals(20, Arrays.stream(a).map(irDoubler).reduce(irMax).getAsInt());
+        assertEquals(2, Arrays.stream(a).map(irDoubler).reduce(irMin).getAsInt());
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfInt data) {
+        assertEquals(0, (int) exerciseTerminalOps(data, s -> s.filter(ipFalse), s -> s.reduce(0, irPlus)));
+
+        OptionalInt seedless = exerciseTerminalOps(data, s -> s.reduce(irPlus));
+        int folded = exerciseTerminalOps(data, s -> s.reduce(0, irPlus));
+        assertEquals(folded, seedless.orElse(0));
+
+        seedless = exerciseTerminalOps(data, s -> s.reduce(irMin));
+        folded = exerciseTerminalOps(data, s -> s.reduce(Integer.MAX_VALUE, irMin));
+        assertEquals(folded, seedless.orElse(Integer.MAX_VALUE));
+
+        seedless = exerciseTerminalOps(data, s -> s.reduce(irMax));
+        folded = exerciseTerminalOps(data, s -> s.reduce(Integer.MIN_VALUE, irMax));
+        assertEquals(folded, seedless.orElse(Integer.MIN_VALUE));
+
+        seedless = exerciseTerminalOps(data, s -> s.map(irDoubler), s -> s.reduce(irPlus));
+        folded = exerciseTerminalOps(data, s -> s.map(irDoubler), s -> s.reduce(0, irPlus));
+        assertEquals(folded, seedless.orElse(0));
+
+        seedless = exerciseTerminalOps(data, s -> s.map(irDoubler), s -> s.reduce(irMin));
+        folded = exerciseTerminalOps(data, s -> s.map(irDoubler), s -> s.reduce(Integer.MAX_VALUE, irMin));
+        assertEquals(folded, seedless.orElse(Integer.MAX_VALUE));
+
+        seedless = exerciseTerminalOps(data, s -> s.map(irDoubler), s -> s.reduce(irMax));
+        folded = exerciseTerminalOps(data, s -> s.map(irDoubler), s -> s.reduce(Integer.MIN_VALUE, irMax));
+        assertEquals(folded, seedless.orElse(Integer.MIN_VALUE));
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntSliceOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntSliceOpTest.java
new file mode 100644
index 0000000..6521f8b
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntSliceOpTest.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.Collection;
+import java.util.stream.*;
+
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static java.util.stream.LambdaTestHelpers.assertCountSum;
+
+/**
+ * SliceOpTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class IntSliceOpTest extends OpTestCase {
+
+    private static final int[] EMPTY_INT_ARRAY = new int[0];
+
+    public void testSkip() {
+        assertCountSum(IntStream.range(0, 0).substream(0).boxed(), 0, 0);
+        assertCountSum(IntStream.range(0, 0).substream(4).boxed(), 0, 0);
+        assertCountSum(IntStream.range(1, 5).substream(4).boxed(), 0, 0);
+        assertCountSum(IntStream.range(1, 5).substream(2).boxed(), 2, 7);
+        assertCountSum(IntStream.range(1, 5).substream(0).boxed(), 4, 10);
+
+        assertCountSum(IntStream.range(0, 0).parallel().substream(0).boxed(), 0, 0);
+        assertCountSum(IntStream.range(0, 0).parallel().substream(4).boxed(), 0, 0);
+        assertCountSum(IntStream.range(1, 5).parallel().substream(4).boxed(), 0, 0);
+        assertCountSum(IntStream.range(1, 5).parallel().substream(2).boxed(), 2, 7);
+        assertCountSum(IntStream.range(1, 5).parallel().substream(0).boxed(), 4, 10);
+
+        exerciseOps(EMPTY_INT_ARRAY, s -> s.substream(0), EMPTY_INT_ARRAY);
+        exerciseOps(EMPTY_INT_ARRAY, s -> s.substream(10), EMPTY_INT_ARRAY);
+
+        exerciseOps(IntStream.range(1, 2).toArray(), s -> s.substream(0), IntStream.range(1, 2).toArray());
+        exerciseOps(IntStream.range(1, 2).toArray(), s -> s.substream(1), EMPTY_INT_ARRAY);
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(0), IntStream.range(1, 101).toArray());
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(10), IntStream.range(11, 101).toArray());
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(100), EMPTY_INT_ARRAY);
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(200), EMPTY_INT_ARRAY);
+    }
+
+    public void testLimit() {
+        assertCountSum(IntStream.range(0, 0).limit(4).boxed(), 0, 0);
+        assertCountSum(IntStream.range(1, 3).limit(4).boxed(), 2, 3);
+        assertCountSum(IntStream.range(1, 5).limit(4).boxed(), 4, 10);
+        assertCountSum(IntStream.range(1, 9).limit(4).boxed(), 4, 10);
+
+        assertCountSum(IntStream.range(0, 0).parallel().limit(4).boxed(), 0, 0);
+        assertCountSum(IntStream.range(1, 3).parallel().limit(4).boxed(), 2, 3);
+        assertCountSum(IntStream.range(1, 5).parallel().limit(4).boxed(), 4, 10);
+        assertCountSum(IntStream.range(1, 9).parallel().limit(4).boxed(), 4, 10);
+
+        exerciseOps(EMPTY_INT_ARRAY, s -> s.limit(0), EMPTY_INT_ARRAY);
+        exerciseOps(EMPTY_INT_ARRAY, s -> s.limit(10), EMPTY_INT_ARRAY);
+
+        exerciseOps(IntStream.range(1, 2).toArray(), s -> s.limit(0), EMPTY_INT_ARRAY);
+        exerciseOps(IntStream.range(1, 2).toArray(), s -> s.limit(1), IntStream.range(1, 2).toArray());
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.limit(0), EMPTY_INT_ARRAY);
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.limit(10), IntStream.range(1, 11).toArray());
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.limit(10).limit(10), IntStream.range(1, 11).toArray());
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.limit(100), IntStream.range(1, 101).toArray());
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.limit(100).limit(10), IntStream.range(1, 11).toArray());
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.limit(200), IntStream.range(1, 101).toArray());
+    }
+
+    public void testSkipLimit() {
+        exerciseOps(EMPTY_INT_ARRAY, s -> s.substream(0).limit(0), EMPTY_INT_ARRAY);
+        exerciseOps(EMPTY_INT_ARRAY, s -> s.substream(0).limit(10), EMPTY_INT_ARRAY);
+        exerciseOps(EMPTY_INT_ARRAY, s -> s.substream(10).limit(0), EMPTY_INT_ARRAY);
+        exerciseOps(EMPTY_INT_ARRAY, s -> s.substream(10).limit(10), EMPTY_INT_ARRAY);
+
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(0).limit(100), IntStream.range(1, 101).toArray());
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(0).limit(10), IntStream.range(1, 11).toArray());
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(0).limit(0), EMPTY_INT_ARRAY);
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(10).limit(100), IntStream.range(11, 101).toArray());
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(10).limit(10), IntStream.range(11, 21).toArray());
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(10).limit(0), EMPTY_INT_ARRAY);
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(100).limit(100), EMPTY_INT_ARRAY);
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(100).limit(10), EMPTY_INT_ARRAY);
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(100).limit(0), EMPTY_INT_ARRAY);
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(200).limit(100), EMPTY_INT_ARRAY);
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(200).limit(10), EMPTY_INT_ARRAY);
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(200).limit(0), EMPTY_INT_ARRAY);
+    }
+
+    public void testSlice() {
+        exerciseOps(EMPTY_INT_ARRAY, s -> s.substream(0, 0), EMPTY_INT_ARRAY);
+        exerciseOps(EMPTY_INT_ARRAY, s -> s.substream(10, 10), EMPTY_INT_ARRAY);
+
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(0, 100), IntStream.range(1, 101).toArray());
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(0, 10), IntStream.range(1, 11).toArray());
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(0, 0), EMPTY_INT_ARRAY);
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(10, 110), IntStream.range(11, 101).toArray());
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(10, 20), IntStream.range(11, 21).toArray());
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(10, 10), EMPTY_INT_ARRAY);
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(100, 200), EMPTY_INT_ARRAY);
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(100, 110), EMPTY_INT_ARRAY);
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(100, 100), EMPTY_INT_ARRAY);
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(200, 300), EMPTY_INT_ARRAY);
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(200, 210), EMPTY_INT_ARRAY);
+        exerciseOps(IntStream.range(1, 101).toArray(), s -> s.substream(200, 200), EMPTY_INT_ARRAY);
+    }
+
+    private int sliceSize(int dataSize, int skip, int limit) {
+        int size = Math.max(0, dataSize - skip);
+        if (limit >= 0)
+            size = Math.min(size, limit);
+        return size;
+    }
+
+    private int sliceSize(int dataSize, int skip) {
+        return Math.max(0, dataSize - skip);
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testSkipOps(String name, TestData.OfInt data) {
+        List<Integer> skips = sizes(data.size());
+
+        for (int s : skips) {
+            Collection<Integer> sr = exerciseOps(data, st -> st.substream(s));
+            assertEquals(sr.size(), sliceSize(data.size(), s));
+
+            sr = exerciseOps(data, st -> st.substream(s).substream(s / 2));
+            assertEquals(sr.size(), sliceSize(sliceSize(data.size(), s), s / 2));
+        }
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testSkipLimitOps(String name, TestData.OfInt data) {
+        List<Integer> skips = sizes(data.size());
+        List<Integer> limits = skips;
+
+        for (int s : skips) {
+            for (int limit : limits) {
+                Collection<Integer> sr = exerciseOps(data, st -> st.substream(s).limit(limit));
+                assertEquals(sr.size(), sliceSize(sliceSize(data.size(), s), 0, limit));
+
+                sr = exerciseOps(data, st -> st.substream(s, limit+s));
+                assertEquals(sr.size(), sliceSize(data.size(), s, limit));
+            }
+        }
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testLimitOps(String name, TestData.OfInt data) {
+        List<Integer> limits = sizes(data.size());
+
+        for (int limit : limits) {
+            Collection<Integer> sr = exerciseOps(data, st -> st.limit(limit));
+            assertEquals(sr.size(), sliceSize(data.size(), 0, limit));
+
+            sr = exerciseOps(data, st -> st.limit(limit).limit(limit / 2));
+            assertEquals(sr.size(), sliceSize(sliceSize(data.size(), 0, limit), 0, limit / 2));
+        }
+    }
+
+    public void testLimitSort() {
+        exerciseOps(IntStream.range(1, 101).map(i -> 101 - i).toArray(), s -> s.limit(10).sorted());
+    }
+
+    @Test(groups = { "serialization-hostile" })
+    public void testLimitShortCircuit() {
+        for (int l : Arrays.asList(0, 10)) {
+            AtomicInteger ai = new AtomicInteger();
+            IntStream.range(1, 101)
+                    .peek(i -> ai.getAndIncrement())
+                    .limit(l).toArray();
+            // For the case of a zero limit, one element will get pushed through the sink chain
+            assertEquals(ai.get(), l, "tee block was called too many times");
+        }
+    }
+
+    public void testSkipParallel() {
+        int[] l = IntStream.range(1, 1001).parallel().substream(200).limit(200).sequential().toArray();
+        assertEquals(l.length, 200);
+        assertEquals(l[l.length - 1], 400);
+    }
+
+    public void testLimitParallel() {
+        int[] l = IntStream.range(1, 1001).parallel().limit(500).sequential().toArray();
+        assertEquals(l.length, 500);
+        assertEquals(l[l.length - 1], 500);
+    }
+
+    private List<Integer> sizes(int size) {
+        if (size < 4) {
+            return Arrays.asList(0, 1, 2, 3, 4, 6);
+        }
+        else {
+            return Arrays.asList(0, 1, size / 2, size - 1, size, size + 1, 2 * size);
+        }
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntUniqOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntUniqOpTest.java
new file mode 100644
index 0000000..8205d4d
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntUniqOpTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.Collection;
+import java.util.stream.*;
+
+import org.testng.annotations.Test;
+
+import static java.util.stream.LambdaTestHelpers.assertCountSum;
+import static java.util.stream.LambdaTestHelpers.assertUnique;
+
+/**
+ * UniqOpTest
+ */
+@Test
+public class IntUniqOpTest extends OpTestCase {
+
+    public void testUniqOp() {
+        assertCountSum(IntStream.generate(() -> 0).limit(10).distinct().boxed(), 1, 0);
+        assertCountSum(IntStream.generate(() -> 1).limit(10).distinct().boxed(), 1, 1);
+        assertCountSum(IntStream.range(0, 0).distinct().boxed(), 0, 0);
+        assertCountSum(IntStream.range(1, 11).distinct().boxed(), 10, 55);
+        assertCountSum(IntStream.range(1, 11).distinct().boxed(), 10, 55);
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testOp(String name, TestData.OfInt data) {
+        Collection<Integer> result = exerciseOps(data, s -> s.distinct().boxed());
+
+        assertUnique(result);
+        if (data.size() > 0)
+            assertTrue(result.size() > 0);
+        else
+            assertTrue(result.size() == 0);
+        assertTrue(result.size() <= data.size());
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testOpSorted(String name, TestData.OfInt data) {
+        Collection<Integer> result = withData(data).
+                stream(s -> s.sorted().distinct().boxed()).
+                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
+                exercise();
+
+        assertUnique(result);
+        if (data.size() > 0)
+            assertTrue(result.size() > 0);
+        else
+            assertTrue(result.size() == 0);
+        assertTrue(result.size() <= data.size());
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/LongPrimitiveOpsTests.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/LongPrimitiveOpsTests.java
new file mode 100644
index 0000000..fc8fa2a
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/LongPrimitiveOpsTests.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.LongConsumer;
+import java.util.stream.Collectors;
+import java.util.stream.LongStream;
+
+import static org.testng.Assert.assertEquals;
+
+@Test
+public class LongPrimitiveOpsTests {
+
+    public void testSum() {
+        long sum = LongStream.range(1, 10).filter(i -> i % 2 == 0).sum();
+        assertEquals(sum, 20);
+    }
+
+    public void testMap() {
+        long sum = LongStream.range(1, 10).filter(i -> i % 2 == 0).map(i -> i * 2).sum();
+        assertEquals(sum, 40);
+    }
+
+    public void testParSum() {
+        long sum = LongStream.range(1, 10).parallel().filter(i -> i % 2 == 0).sum();
+        assertEquals(sum, 20);
+    }
+
+    @Test(groups = { "serialization-hostile" })
+    public void testTee() {
+        long[] teeSum = new long[1];
+        long sum = LongStream.range(1, 10).filter(i -> i % 2 == 0).peek(i -> { teeSum[0] = teeSum[0] + i; }).sum();
+        assertEquals(teeSum[0], sum);
+    }
+
+    @Test(groups = { "serialization-hostile" })
+    public void testForEach() {
+        long[] sum = new long[1];
+        LongStream.range(1, 10).filter(i -> i % 2 == 0).forEach(i -> { sum[0] = sum[0] + i; });
+        assertEquals(sum[0], 20);
+    }
+
+    @Test(groups = { "serialization-hostile" })
+    public void testParForEach() {
+        AtomicLong ai = new AtomicLong(0);
+        LongStream.range(1, 10).parallel().filter(i -> i % 2 == 0).forEach(ai::addAndGet);
+        assertEquals(ai.get(), 20);
+    }
+
+    public void testBox() {
+        List<Long> l = LongStream.range(1, 10).parallel().boxed().collect(Collectors.toList());
+        long sum = l.stream().reduce(0L, (a, b) -> a + b);
+        assertEquals(sum, 45);
+    }
+
+    public void testUnBox() {
+        long sum = Arrays.asList(1L, 2L, 3L, 4L, 5L).stream().mapToLong(i -> (long) i).sum();
+        assertEquals(sum, 15);
+    }
+
+    public void testToArray() {
+        {
+            long[] array =  LongStream.range(1, 10).map(i -> i * 2).toArray();
+            assertEquals(array, new long[]{2, 4, 6, 8, 10, 12, 14, 16, 18});
+        }
+
+        {
+            long[] array =  LongStream.range(1, 10).parallel().map(i -> i * 2).toArray();
+            assertEquals(array, new long[]{2, 4, 6, 8, 10, 12, 14, 16, 18});
+        }
+    }
+
+    public void testSort() {
+        Random r = new Random();
+
+        long[] content = LongStream.generate(() -> r.nextLong()).limit(10).toArray();
+        long[] sortedContent = content.clone();
+        Arrays.sort(sortedContent);
+
+        {
+            long[] array =  Arrays.stream(content).sorted().toArray();
+            assertEquals(array, sortedContent);
+        }
+
+        {
+            long[] array =  Arrays.stream(content).parallel().sorted().toArray();
+            assertEquals(array, sortedContent);
+        }
+    }
+
+    public void testSortSort() {
+        Random r = new Random();
+
+        long[] content = LongStream.generate(() -> r.nextLong()).limit(10).toArray();
+        long[] sortedContent = content.clone();
+        Arrays.sort(sortedContent);
+
+        {
+            long[] array =  Arrays.stream(content).sorted().sorted().toArray();
+            assertEquals(array, sortedContent);
+        }
+
+        {
+            long[] array =  Arrays.stream(content).parallel().sorted().sorted().toArray();
+            assertEquals(array, sortedContent);
+        }
+    }
+
+    public void testSequential() {
+
+        long[] expected = LongStream.range(1, 1000).toArray();
+
+        class AssertingConsumer implements LongConsumer {
+            private final long[] array;
+            int offset;
+
+            AssertingConsumer(long[] array) {
+                this.array = array;
+            }
+
+            @Override
+            public void accept(long value) {
+                assertEquals(array[offset++], value);
+            }
+
+            public int getCount() { return offset; }
+        }
+
+        {
+            AssertingConsumer consumer = new AssertingConsumer(expected);
+            LongStream.range(1, 1000).sequential().forEach(consumer);
+            assertEquals(expected.length, consumer.getCount());
+        }
+
+        {
+            AssertingConsumer consumer = new AssertingConsumer(expected);
+            LongStream.range(1, 1000).parallel().sequential().forEach(consumer);
+            assertEquals(expected.length, consumer.getCount());
+        }
+    }
+
+    public void testLimit() {
+        long[] expected = LongStream.range(1, 10).toArray();
+
+        {
+            long[] actual = LongStream.iterate(1, i -> i + 1).limit(9).toArray();
+            Assert.assertTrue(Arrays.equals(expected, actual));
+        }
+
+        {
+            long[] actual = LongStream.range(1, 100).parallel().limit(9).toArray();
+            Assert.assertTrue(Arrays.equals(expected, actual));
+        }
+    }
+
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/MapOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/MapOpTest.java
new file mode 100644
index 0000000..9225ddd
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/MapOpTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.function.DoubleToIntFunction;
+import java.util.function.DoubleToLongFunction;
+import java.util.function.Function;
+import java.util.function.IntToDoubleFunction;
+import java.util.function.IntToLongFunction;
+import java.util.function.LongToDoubleFunction;
+import java.util.function.LongToIntFunction;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+import java.util.stream.*;
+
+import static java.util.stream.LambdaTestHelpers.*;
+
+/**
+ * MapOpTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class MapOpTest extends OpTestCase {
+
+    public void testMap() {
+        assertCountSum(countTo(0).stream().map(mId), 0, 0);
+        assertCountSum(countTo(10).stream().map(mId), 10, 55);
+        assertCountSum(countTo(10).stream().map(mZero), 10, 0);
+        assertCountSum(countTo(0).stream().map(mDoubler), 0, 0);
+        assertCountSum(countTo(10).stream().map(mDoubler), 10, 110);
+        assertCountSum(countTo(10).stream().map(mDoubler).map(mDoubler), 10, 220);
+
+        exerciseOps(countTo(0), s -> s.map(LambdaTestHelpers.identity()), countTo(0));
+        exerciseOps(countTo(1000), s -> s.map(LambdaTestHelpers.identity()), countTo(1000));
+        // @@@ Force cast to integer so output is Stream<Integer> rather an IntStream
+        //     this just ensures that no warnings are logged about boxing
+        //     when the result is compared with the output
+        exerciseOps(countTo(1000), s -> s.map(e -> (Integer) (1000 + e)), range(1001, 2000));
+    }
+
+    public void testEveryMapShape() {
+        assertCountSum(countTo(1000).stream()
+                               .mapToInt(i -> i - 1)
+                               .mapToObj(i -> i + 1)
+                               .mapToLong(i -> i - 1)
+                               .mapToObj(i -> i + 1)
+                               .mapToDouble(i -> i - 1)
+                               .mapToObj(i -> i + 1)
+                               .mapToInt(i -> (int) (double) i)
+                               .mapToLong(i -> i)
+                               .mapToDouble(i -> i)
+                               .mapToLong(i -> (long) i)
+                               .mapToInt(i -> (int) i)
+                               .mapToObj(i -> i),
+                       1000, countTo(1000).stream().mapToInt(i -> i).sum());
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfRef<Integer> data) {
+        exerciseOpsInt(data, s -> s.map(mId), s -> s.map(e -> e), s -> s.map(e -> e), s -> s.map(e -> e));
+        exerciseOpsInt(data, s -> s.map(mZero), s -> s.map(e -> 0), s -> s.map(e -> 0), s -> s.map(e -> 0));
+        exerciseOpsInt(data, s -> s.map(mDoubler), s -> s.map(e -> 2*e), s -> s.map(e -> 2*e), s -> s.map(e -> 2*e));
+        exerciseOpsInt(data, s -> s.map(LambdaTestHelpers.compose(mId, mDoubler)), s -> s.map(e -> 2*e), s -> s.map(e -> 2*e), s -> s.map(e -> 2*e));
+        exerciseOpsInt(data, s -> s.map(LambdaTestHelpers.compose(mDoubler, mDoubler)), s -> s.map(e -> 4*e), s -> s.map(e -> 4*e), s -> s.map(e -> 4*e));
+        exerciseOps(data, s -> s.mapToInt(i -> i));
+        exerciseOps(data, s -> s.mapToLong(i -> i));
+        exerciseOps(data, s -> s.mapToDouble(i -> i));
+    }
+
+    //
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntOps(String name, TestData.OfInt data) {
+        exerciseOps(data, s -> s.mapToObj(i -> i));
+        exerciseOps(data, s -> s.map(i -> 0));
+        exerciseOps(data, s -> s.map(i -> i * 2));
+        exerciseOps(data, s -> s.longs());
+        exerciseOps(data, s -> s.doubles());
+        exerciseOps(data, s -> s.boxed());
+        exerciseOps(data, s -> s.mapToObj(Integer::toString));
+        exerciseOps(data, s -> s.mapToLong(i -> i));
+        exerciseOps(data, s -> s.mapToDouble(i -> i));
+    }
+
+    //
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongOps(String name, TestData.OfLong data) {
+        exerciseOps(data, s -> s.mapToObj(i -> i));
+        exerciseOps(data, s -> s.map(i -> 0L));
+        exerciseOps(data, s -> s.map(i -> i * 2L));
+        exerciseOps(data, s -> s.doubles());
+        exerciseOps(data, s -> s.boxed());
+        exerciseOps(data, s -> s.mapToObj(e -> Long.toString(e)));
+        exerciseOps(data, s -> s.mapToInt(i -> (int) i));
+        exerciseOps(data, s -> s.mapToDouble(i -> i));
+    }
+
+    //
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleOps(String name, TestData.OfDouble data) {
+        exerciseOps(data, s -> s.mapToObj(i -> i));
+        exerciseOps(data, s -> s.map(i -> 0.0));
+        exerciseOps(data, s -> s.map(i -> i * 2.0));
+        exerciseOps(data, s -> s.boxed());
+        exerciseOps(data, s -> s.mapToObj(e -> Double.toString(e)));
+        exerciseOps(data, s -> s.mapToLong(i -> (long) i));
+        exerciseOps(data, s -> s.mapToInt(i -> (int) i));
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/MatchOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/MatchOpTest.java
new file mode 100644
index 0000000..a651611
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/MatchOpTest.java
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.PrimitiveIterator;
+import java.util.function.DoublePredicate;
+import java.util.function.DoubleSupplier;
+import java.util.function.Function;
+import java.util.function.IntPredicate;
+import java.util.function.IntSupplier;
+import java.util.function.LongPredicate;
+import java.util.function.LongSupplier;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.stream.DoubleStream;
+import java.util.stream.DoubleStreamTestDataProvider;
+import java.util.stream.IntStream;
+import java.util.stream.IntStreamTestDataProvider;
+import java.util.stream.LongStream;
+import java.util.stream.LongStreamTestDataProvider;
+import java.util.stream.OpTestCase;
+import java.util.stream.Stream;
+import java.util.stream.StreamTestDataProvider;
+import java.util.stream.TestData;
+
+import org.testng.annotations.Test;
+
+import static java.util.stream.LambdaTestHelpers.countTo;
+import static java.util.stream.LambdaTestHelpers.dpEven;
+import static java.util.stream.LambdaTestHelpers.dpFalse;
+import static java.util.stream.LambdaTestHelpers.dpOdd;
+import static java.util.stream.LambdaTestHelpers.dpTrue;
+import static java.util.stream.LambdaTestHelpers.ipEven;
+import static java.util.stream.LambdaTestHelpers.ipFalse;
+import static java.util.stream.LambdaTestHelpers.ipOdd;
+import static java.util.stream.LambdaTestHelpers.ipTrue;
+import static java.util.stream.LambdaTestHelpers.lpEven;
+import static java.util.stream.LambdaTestHelpers.lpFalse;
+import static java.util.stream.LambdaTestHelpers.lpOdd;
+import static java.util.stream.LambdaTestHelpers.lpTrue;
+import static java.util.stream.LambdaTestHelpers.pEven;
+import static java.util.stream.LambdaTestHelpers.pFalse;
+import static java.util.stream.LambdaTestHelpers.pOdd;
+import static java.util.stream.LambdaTestHelpers.pTrue;
+
+/**
+ * MatchOpTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class MatchOpTest extends OpTestCase {
+    private enum Kind { ANY, ALL, NONE }
+
+    @SuppressWarnings("unchecked")
+    private static final Predicate<Integer>[] INTEGER_PREDICATES
+            = (Predicate<Integer>[]) new Predicate<?>[]{pTrue, pFalse, pEven, pOdd};
+
+    @SuppressWarnings({"serial", "rawtypes"})
+    private final Map kinds
+            = new HashMap<Kind, Function<Predicate<Integer>, Function<Stream<Integer>, Boolean>>>() {{
+        put(Kind.ANY, p -> s -> s.anyMatch(p));
+        put(Kind.ALL, p -> s -> s.allMatch(p));
+        put(Kind.NONE, p -> s -> s.noneMatch(p));
+    }};
+
+    @SuppressWarnings("unchecked")
+    private <T> Map<Kind, Function<Predicate<T>, Function<Stream<T>, Boolean>>> kinds() {
+        return (Map<Kind, Function<Predicate<T>, Function<Stream<T>, Boolean>>>) kinds;
+    }
+
+    private <T> void assertPredicates(List<T> source, Kind kind, Predicate<T>[] predicates, boolean... answers) {
+        for (int i = 0; i < predicates.length; i++) {
+            boolean match = this.<T>kinds().get(kind).apply(predicates[i]).apply(source.stream());
+            assertEquals(answers[i], match, kind.toString() + predicates[i].toString());
+        }
+    }
+
+    public void testStreamMatches() {
+        assertPredicates(countTo(0), Kind.ANY, INTEGER_PREDICATES, false, false, false, false);
+        assertPredicates(countTo(0), Kind.ALL, INTEGER_PREDICATES, true, true, true, true);
+        assertPredicates(countTo(0), Kind.NONE, INTEGER_PREDICATES, true, true, true, true);
+
+        assertPredicates(countTo(1), Kind.ANY, INTEGER_PREDICATES, true, false, false, true);
+        assertPredicates(countTo(1), Kind.ALL, INTEGER_PREDICATES, true, false, false, true);
+        assertPredicates(countTo(1), Kind.NONE, INTEGER_PREDICATES, false, true, true, false);
+
+        assertPredicates(countTo(5), Kind.ANY, INTEGER_PREDICATES, true, false, true, true);
+        assertPredicates(countTo(5), Kind.ALL, INTEGER_PREDICATES, true, false, false, false);
+        assertPredicates(countTo(5), Kind.NONE, INTEGER_PREDICATES, false, true, false, false);
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testStream(String name, TestData.OfRef<Integer> data) {
+        for (Predicate<Integer> p : INTEGER_PREDICATES) {
+            for (Kind kind : Kind.values()) {
+                exerciseTerminalOps(data, this.<Integer>kinds().get(kind).apply(p));
+                exerciseTerminalOps(data, s -> s.filter(pFalse), this.<Integer>kinds().get(kind).apply(p));
+                exerciseTerminalOps(data, s -> s.filter(pEven), this.<Integer>kinds().get(kind).apply(p));
+            }
+        }
+    }
+
+    public void testInfinite() {
+        class CycleSupplier<T> implements Supplier<T> {
+            final Iterable<T> source;
+            Iterator<T> i = Collections.emptyIterator();
+
+            CycleSupplier(Iterable<T> source) {
+                this.source = source;
+            }
+
+            @Override
+            public T get() {
+                if (!i.hasNext()) {
+                    i = source.iterator();
+                }
+                return i.next();
+            }
+        }
+
+        assertFalse(Stream.generate(new CycleSupplier<>(Arrays.asList(1, 2, 3, 4))).allMatch(i -> i > 3));
+        assertTrue(Stream.generate(new CycleSupplier<>(Arrays.asList(1, 2, 3, 4))).anyMatch(i -> i > 3));
+        assertFalse(Stream.generate(new CycleSupplier<>(Arrays.asList(1, 2, 3, 4))).noneMatch(i -> i > 3));
+        assertFalse(Stream.generate(new CycleSupplier<>(Arrays.asList(1, 2, 3, 4))).parallel().allMatch(i -> i > 3));
+        assertTrue(Stream.generate(new CycleSupplier<>(Arrays.asList(1, 2, 3, 4))).parallel().anyMatch(i -> i > 3));
+        assertFalse(Stream.generate(new CycleSupplier<>(Arrays.asList(1, 2, 3, 4))).parallel().noneMatch(i -> i > 3));
+    }
+
+    //
+
+    private static final IntPredicate[] INT_PREDICATES
+            = new IntPredicate[]{ipTrue, ipFalse, ipEven, ipOdd};
+
+    @SuppressWarnings("serial")
+    private final Map<Kind, Function<IntPredicate, Function<IntStream, Boolean>>> intKinds
+            = new HashMap<Kind, Function<IntPredicate, Function<IntStream, Boolean>>>() {{
+        put(Kind.ANY, p -> s -> s.anyMatch(p));
+        put(Kind.ALL, p -> s -> s.allMatch(p));
+        put(Kind.NONE, p -> s -> s.noneMatch(p));
+    }};
+
+    private void assertIntPredicates(Supplier<IntStream> source, Kind kind, IntPredicate[] predicates, boolean... answers) {
+        for (int i = 0; i < predicates.length; i++) {
+            boolean match = intKinds.get(kind).apply(predicates[i]).apply(source.get());
+            assertEquals(answers[i], match, kind.toString() + predicates[i].toString());
+        }
+    }
+
+    public void testIntStreamMatches() {
+        assertIntPredicates(() -> IntStream.range(0, 0), Kind.ANY, INT_PREDICATES, false, false, false, false);
+        assertIntPredicates(() -> IntStream.range(0, 0), Kind.ALL, INT_PREDICATES, true, true, true, true);
+        assertIntPredicates(() -> IntStream.range(0, 0), Kind.NONE, INT_PREDICATES, true, true, true, true);
+
+        assertIntPredicates(() -> IntStream.range(1, 2), Kind.ANY, INT_PREDICATES, true, false, false, true);
+        assertIntPredicates(() -> IntStream.range(1, 2), Kind.ALL, INT_PREDICATES, true, false, false, true);
+        assertIntPredicates(() -> IntStream.range(1, 2), Kind.NONE, INT_PREDICATES, false, true, true, false);
+
+        assertIntPredicates(() -> IntStream.range(1, 6), Kind.ANY, INT_PREDICATES, true, false, true, true);
+        assertIntPredicates(() -> IntStream.range(1, 6), Kind.ALL, INT_PREDICATES, true, false, false, false);
+        assertIntPredicates(() -> IntStream.range(1, 6), Kind.NONE, INT_PREDICATES, false, true, false, false);
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntStream(String name, TestData.OfInt data) {
+        for (IntPredicate p : INT_PREDICATES)
+            for (Kind kind : Kind.values()) {
+                exerciseTerminalOps(data, intKinds.get(kind).apply(p));
+                exerciseTerminalOps(data, s -> s.filter(ipFalse), intKinds.get(kind).apply(p));
+                exerciseTerminalOps(data, s -> s.filter(ipEven), intKinds.get(kind).apply(p));
+            }
+    }
+
+    public void testIntInfinite() {
+        class CycleSupplier implements IntSupplier {
+            final Supplier<PrimitiveIterator.OfInt> source;
+            PrimitiveIterator.OfInt i = null;
+
+            CycleSupplier(Supplier<PrimitiveIterator.OfInt> source) {
+                this.source = source;
+            }
+
+            @Override
+            public int getAsInt() {
+                if (i == null || !i.hasNext()) {
+                    i = source.get();
+                }
+                return i.nextInt();
+            }
+        }
+
+        Supplier<PrimitiveIterator.OfInt> source = () -> Arrays.stream(new int[]{1, 2, 3, 4}).iterator();
+
+        assertFalse(IntStream.generate(new CycleSupplier(source)).allMatch(i -> i > 3));
+        assertTrue(IntStream.generate(new CycleSupplier(source)).anyMatch(i -> i > 3));
+        assertFalse(IntStream.generate(new CycleSupplier(source)).noneMatch(i -> i > 3));
+        assertFalse(IntStream.generate(new CycleSupplier(source)).parallel().allMatch(i -> i > 3));
+        assertTrue(IntStream.generate(new CycleSupplier(source)).parallel().anyMatch(i -> i > 3));
+        assertFalse(IntStream.generate(new CycleSupplier(source)).parallel().noneMatch(i -> i > 3));
+    }
+
+    //
+
+    private static final LongPredicate[] LONG_PREDICATES
+            = new LongPredicate[]{lpTrue, lpFalse, lpEven, lpOdd};
+
+    @SuppressWarnings("serial")
+    private final Map<Kind, Function<LongPredicate, Function<LongStream, Boolean>>> longKinds
+            = new HashMap<Kind, Function<LongPredicate, Function<LongStream, Boolean>>>() {{
+        put(Kind.ANY, p -> s -> s.anyMatch(p));
+        put(Kind.ALL, p -> s -> s.allMatch(p));
+        put(Kind.NONE, p -> s -> s.noneMatch(p));
+    }};
+
+    private void assertLongPredicates(Supplier<LongStream> source, Kind kind, LongPredicate[] predicates, boolean... answers) {
+        for (int i = 0; i < predicates.length; i++) {
+            boolean match = longKinds.get(kind).apply(predicates[i]).apply(source.get());
+            assertEquals(answers[i], match, kind.toString() + predicates[i].toString());
+        }
+    }
+
+    public void testLongStreamMatches() {
+        assertLongPredicates(() -> LongStream.range(0, 0), Kind.ANY, LONG_PREDICATES, false, false, false, false);
+        assertLongPredicates(() -> LongStream.range(0, 0), Kind.ALL, LONG_PREDICATES, true, true, true, true);
+        assertLongPredicates(() -> LongStream.range(0, 0), Kind.NONE, LONG_PREDICATES, true, true, true, true);
+
+        assertLongPredicates(() -> LongStream.range(1, 2), Kind.ANY, LONG_PREDICATES, true, false, false, true);
+        assertLongPredicates(() -> LongStream.range(1, 2), Kind.ALL, LONG_PREDICATES, true, false, false, true);
+        assertLongPredicates(() -> LongStream.range(1, 2), Kind.NONE, LONG_PREDICATES, false, true, true, false);
+
+        assertLongPredicates(() -> LongStream.range(1, 6), Kind.ANY, LONG_PREDICATES, true, false, true, true);
+        assertLongPredicates(() -> LongStream.range(1, 6), Kind.ALL, LONG_PREDICATES, true, false, false, false);
+        assertLongPredicates(() -> LongStream.range(1, 6), Kind.NONE, LONG_PREDICATES, false, true, false, false);
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongStream(String name, TestData.OfLong data) {
+        for (LongPredicate p : LONG_PREDICATES)
+            for (Kind kind : Kind.values()) {
+                exerciseTerminalOps(data, longKinds.get(kind).apply(p));
+                exerciseTerminalOps(data, s -> s.filter(lpFalse), longKinds.get(kind).apply(p));
+                exerciseTerminalOps(data, s -> s.filter(lpEven), longKinds.get(kind).apply(p));
+            }
+    }
+
+    public void testLongInfinite() {
+        class CycleSupplier implements LongSupplier {
+            final Supplier<PrimitiveIterator.OfLong> source;
+            PrimitiveIterator.OfLong i = null;
+
+            CycleSupplier(Supplier<PrimitiveIterator.OfLong> source) {
+                this.source = source;
+            }
+
+            @Override
+            public long getAsLong() {
+                if (i == null || !i.hasNext()) {
+                    i = source.get();
+                }
+                return i.nextLong();
+            }
+        }
+
+        Supplier<PrimitiveIterator.OfLong> source = () -> Arrays.stream(new long[]{1, 2, 3, 4}).iterator();
+
+        assertFalse(LongStream.generate(new CycleSupplier(source)).allMatch(i -> i > 3));
+        assertTrue(LongStream.generate(new CycleSupplier(source)).anyMatch(i -> i > 3));
+        assertFalse(LongStream.generate(new CycleSupplier(source)).noneMatch(i -> i > 3));
+        assertFalse(LongStream.generate(new CycleSupplier(source)).parallel().allMatch(i -> i > 3));
+        assertTrue(LongStream.generate(new CycleSupplier(source)).parallel().anyMatch(i -> i > 3));
+        assertFalse(LongStream.generate(new CycleSupplier(source)).parallel().noneMatch(i -> i > 3));
+    }
+
+    //
+
+    private static final DoublePredicate[] DOUBLE_PREDICATES
+            = new DoublePredicate[]{dpTrue, dpFalse, dpEven, dpOdd};
+
+    @SuppressWarnings("serial")
+    private final Map<Kind, Function<DoublePredicate, Function<DoubleStream, Boolean>>> doubleKinds
+            = new HashMap<Kind, Function<DoublePredicate, Function<DoubleStream, Boolean>>>() {{
+        put(Kind.ANY, p -> s -> s.anyMatch(p));
+        put(Kind.ALL, p -> s -> s.allMatch(p));
+        put(Kind.NONE, p -> s -> s.noneMatch(p));
+    }};
+
+    private void assertDoublePredicates(Supplier<DoubleStream> source, Kind kind, DoublePredicate[] predicates, boolean... answers) {
+        for (int i = 0; i < predicates.length; i++) {
+            boolean match = doubleKinds.get(kind).apply(predicates[i]).apply(source.get());
+            assertEquals(answers[i], match, kind.toString() + predicates[i].toString());
+        }
+    }
+
+    public void testDoubleStreamMatches() {
+        assertDoublePredicates(() -> LongStream.range(0, 0).doubles(), Kind.ANY, DOUBLE_PREDICATES, false, false, false, false);
+        assertDoublePredicates(() -> LongStream.range(0, 0).doubles(), Kind.ALL, DOUBLE_PREDICATES, true, true, true, true);
+        assertDoublePredicates(() -> LongStream.range(0, 0).doubles(), Kind.NONE, DOUBLE_PREDICATES, true, true, true, true);
+
+        assertDoublePredicates(() -> LongStream.range(1, 2).doubles(), Kind.ANY, DOUBLE_PREDICATES, true, false, false, true);
+        assertDoublePredicates(() -> LongStream.range(1, 2).doubles(), Kind.ALL, DOUBLE_PREDICATES, true, false, false, true);
+        assertDoublePredicates(() -> LongStream.range(1, 2).doubles(), Kind.NONE, DOUBLE_PREDICATES, false, true, true, false);
+
+        assertDoublePredicates(() -> LongStream.range(1, 6).doubles(), Kind.ANY, DOUBLE_PREDICATES, true, false, true, true);
+        assertDoublePredicates(() -> LongStream.range(1, 6).doubles(), Kind.ALL, DOUBLE_PREDICATES, true, false, false, false);
+        assertDoublePredicates(() -> LongStream.range(1, 6).doubles(), Kind.NONE, DOUBLE_PREDICATES, false, true, false, false);
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleStream(String name, TestData.OfDouble data) {
+        for (DoublePredicate p : DOUBLE_PREDICATES)
+            for (Kind kind : Kind.values()) {
+                exerciseTerminalOps(data, doubleKinds.get(kind).apply(p));
+                exerciseTerminalOps(data, s -> s.filter(dpFalse), doubleKinds.get(kind).apply(p));
+                exerciseTerminalOps(data, s -> s.filter(dpEven), doubleKinds.get(kind).apply(p));
+            }
+    }
+
+    public void testDoubleInfinite() {
+        class CycleSupplier implements DoubleSupplier {
+            final Supplier<PrimitiveIterator.OfDouble> source;
+            PrimitiveIterator.OfDouble i = null;
+
+            CycleSupplier(Supplier<PrimitiveIterator.OfDouble> source) {
+                this.source = source;
+            }
+
+            @Override
+            public double getAsDouble() {
+                if (i == null || !i.hasNext()) {
+                    i = source.get();
+                }
+                return i.nextDouble();
+            }
+        }
+
+        Supplier<PrimitiveIterator.OfDouble> source = () -> Arrays.stream(new double[]{1, 2, 3, 4}).iterator();
+
+        assertFalse(DoubleStream.generate(new CycleSupplier(source)).allMatch(i -> i > 3));
+        assertTrue(DoubleStream.generate(new CycleSupplier(source)).anyMatch(i -> i > 3));
+        assertFalse(DoubleStream.generate(new CycleSupplier(source)).noneMatch(i -> i > 3));
+        assertFalse(DoubleStream.generate(new CycleSupplier(source)).parallel().allMatch(i -> i > 3));
+        assertTrue(DoubleStream.generate(new CycleSupplier(source)).parallel().anyMatch(i -> i > 3));
+        assertFalse(DoubleStream.generate(new CycleSupplier(source)).parallel().noneMatch(i -> i > 3));
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/MinMaxTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/MinMaxTest.java
new file mode 100644
index 0000000..6ae3609
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/MinMaxTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.OptionalDouble;
+import java.util.OptionalInt;
+import java.util.OptionalLong;
+import java.util.stream.*;
+
+import org.testng.annotations.Test;
+
+import static java.util.stream.LambdaTestHelpers.countTo;
+
+/**
+ * MinMaxTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class MinMaxTest extends OpTestCase {
+    public void testMinMax() {
+        assertTrue(!countTo(0).stream().min(Integer::compare).isPresent());
+        assertTrue(!countTo(0).stream().max(Integer::compare).isPresent());
+        assertEquals(1, (int) countTo(1000).stream().min(Integer::compare).get());
+        assertEquals(1000, (int) countTo(1000).stream().max(Integer::compare).get());
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfRef<Integer> data) {
+        exerciseTerminalOps(data, s -> s.min(Integer::compare));
+        exerciseTerminalOps(data, s -> s.max(Integer::compare));
+    }
+
+    public void testIntMinMax() {
+        assertEquals(IntStream.empty().min(), OptionalInt.empty());
+        assertEquals(IntStream.empty().max(), OptionalInt.empty());
+        assertEquals(1, IntStream.range(1, 1001).min().getAsInt());
+        assertEquals(1000, IntStream.range(1, 1001).max().getAsInt());
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntOps(String name, TestData.OfInt data) {
+        exerciseTerminalOps(data, s -> s.min());
+        exerciseTerminalOps(data, s -> s.max());
+    }
+
+    public void testLongMinMax() {
+        assertEquals(LongStream.empty().min(), OptionalLong.empty());
+        assertEquals(LongStream.empty().max(), OptionalLong.empty());
+        assertEquals(1, LongStream.range(1, 1001).min().getAsLong());
+        assertEquals(1000, LongStream.range(1, 1001).max().getAsLong());
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongOps(String name, TestData.OfLong data) {
+        exerciseTerminalOps(data, s -> s.min());
+        exerciseTerminalOps(data, s -> s.max());
+    }
+
+    public void testDoubleMinMax() {
+        assertEquals(DoubleStream.empty().min(), OptionalDouble.empty());
+        assertEquals(DoubleStream.empty().max(), OptionalDouble.empty());
+        assertEquals(1.0, LongStream.range(1, 1001).doubles().min().getAsDouble());
+        assertEquals(1000.0, LongStream.range(1, 1001).doubles().max().getAsDouble());
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleOps(String name, TestData.OfDouble data) {
+        exerciseTerminalOps(data, s -> s.min());
+        exerciseTerminalOps(data, s -> s.max());
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/PrimitiveAverageOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/PrimitiveAverageOpTest.java
new file mode 100644
index 0000000..82491e5
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/PrimitiveAverageOpTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.stream.*;
+
+import org.testng.annotations.Test;
+
+public class PrimitiveAverageOpTest extends OpTestCase {
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfInt data) {
+        exerciseTerminalOps(data, s -> s.average());
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfLong data) {
+        exerciseTerminalOps(data, s -> s.average());
+    }
+
+    // @@@ For Double depending on the input data the average algorithm may produce slightly
+    //     different results for the sequential and parallel evaluation.results are within
+    //     While the following works at the moment, it could change when double data, not cast from long
+    //     values is introduced, or if the average/sum algorithm is modified.
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfDouble data) {
+        exerciseTerminalOps(data, s -> s.average());
+    }
+
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/PrimitiveSumTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/PrimitiveSumTest.java
new file mode 100644
index 0000000..98c9351
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/PrimitiveSumTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.stream.*;
+
+import org.testng.annotations.Test;
+
+public class PrimitiveSumTest extends OpTestCase {
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfInt data) {
+        exerciseTerminalOps(data, s -> s.sum());
+
+        withData(data).
+                terminal(s -> (long) s.sum()).
+                expectedResult(data.stream().longs().reduce(0, LambdaTestHelpers.lrPlus)).
+                exercise();
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfLong data) {
+        exerciseTerminalOps(data, s -> s.sum());
+
+        withData(data).
+                terminal(s -> s.sum()).
+                expectedResult(data.stream().reduce(0, LambdaTestHelpers.lrPlus)).
+                exercise();
+    }
+
+    // @@@ For Double depending on the input data the average algorithm may produce slightly
+    //     different results for the sequential and parallel evaluation.results are within
+    //     While the following works at the moment, it could change when double data, not cast from long
+    //     values is introduced, or if the sum algorithm is modified.
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfDouble data) {
+        exerciseTerminalOps(data, s -> s.sum());
+
+        withData(data).
+                terminal(s -> s.sum()).
+                expectedResult(data.stream().reduce(0, LambdaTestHelpers.drPlus)).
+                exercise();
+    }
+}
+
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/RangeTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/RangeTest.java
new file mode 100644
index 0000000..182b98c
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/RangeTest.java
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.OpTestCase;
+import java.util.stream.Stream;
+import java.util.stream.TestData;
+
+import org.testng.annotations.Test;
+
+/**
+ * Primitive range tests
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class RangeTest extends OpTestCase {
+
+    public void testInfiniteRangeFindFirst() {
+        Integer first = Stream.iterate(0, i -> i + 1).filter(i -> i > 10000).findFirst().get();
+        assertEquals(first, Stream.iterate(0, i -> i + 1).parallel().filter(i -> i > 10000).findFirst().get());
+
+        // Limit is required to transform the infinite stream to a finite stream
+        // since the exercising requires a finite stream
+        withData(TestData.Factory.ofSupplier(
+                "", () -> Stream.iterate(0, i -> i + 1).filter(i -> i > 10000).limit(20000))).
+                terminal(s->s.findFirst()).expectedResult(Optional.of(10001)).exercise();
+    }
+
+    //
+
+    public void testIntRangeErrors() {
+        for (int start : Arrays.asList(1, 10, -1, -10)) {
+            for (int end : Arrays.asList(1, 10, -1, -10)) {
+                for (int step : Arrays.asList(0, 1, -1, Integer.MAX_VALUE, Integer.MIN_VALUE)) {
+                    if (step > 0)
+                        executeAndNoCatch(() -> IntStream.range(start, end, step));
+                    else
+                        executeAndCatch(() -> IntStream.range(start, end, step));
+                }
+            }
+        }
+    }
+
+    public void testIntRange() {
+        // Without step
+        for (int start : Arrays.asList(1, 10, -1, -10)) {
+            for (int end : Arrays.asList(1, 10, -1, -10)) {
+                int step = 1;
+                int size = (start < end) ? end - start : 0;
+                int[] exp = new int[size];
+                if (start < end) {
+                    for (int i = start, p = 0; i < end; i++, p++) {
+                        exp[p] = i;
+                    }
+                }
+
+                int[] inc = IntStream.range(start, end).toArray();
+                assertEquals(inc.length, size);
+                assertTrue(Arrays.equals(exp, inc));
+
+                withData(intRangeData(start, end, step)).stream(s -> s).
+                        expectedResult(exp).exercise();
+            }
+        }
+
+        // With step
+        for (int start : Arrays.asList(1, 10, -1, -10)) {
+            for (int end : Arrays.asList(1, 10, -1, -10)) {
+                for (int step : Arrays.asList(1, -1, -2, 2)) {
+                    if (step > 0) {
+                        int d = end - start;
+                        int size = (start < end) ? (d / step) + ((d % step == 0) ? 0 : 1) : 0;
+                        int[] exp = new int[size];
+                        if (start < end) {
+                            for (int i = start, p = 0; i < end; i += step, p++) {
+                                exp[p] = i;
+                            }
+                        }
+
+                        int[] inc = IntStream.range(start, end, step).toArray();
+                        assertEquals(inc.length, size);
+                        assertTrue(Arrays.equals(exp, inc));
+
+                        withData(intRangeData(start, end, step)).stream(s -> s).
+                                expectedResult(exp).exercise();
+                    }
+                }
+            }
+        }
+    }
+
+    TestData.OfInt intRangeData(int start, int end, int step) {
+        return TestData.Factory.ofIntSupplier("int range", () -> IntStream.range(start, end, step));
+    }
+
+    public void tesIntRangeReduce() {
+        withData(intRangeData(0, 10000, 1)).
+                terminal(s -> s.reduce(0, Integer::sum)).exercise();
+    }
+
+    public void testIntInfiniteRangeLimit() {
+        withData(TestData.Factory.ofIntSupplier(
+                "int range", () -> IntStream.iterate(0, i -> i + 1).limit(10000))).
+                terminal(s -> s.reduce(0, Integer::sum)).exercise();
+    }
+
+    public void testIntInfiniteRangeFindFirst() {
+        int first = IntStream.iterate(0, i -> i + 1).filter(i -> i > 10000).findFirst().getAsInt();
+        assertEquals(first, IntStream.iterate(0, i -> i + 1).parallel().filter(i -> i > 10000).findFirst().getAsInt());
+    }
+
+    //
+
+    public void testLongRangeErrors() {
+        for (long start : Arrays.asList(1, 10, -1, -10)) {
+            for (long end : Arrays.asList(1, 10, -1, -10)) {
+                for (long step : Arrays.asList(0L, 1L, -1L, Long.MAX_VALUE, Long.MIN_VALUE)) {
+                    if (step > 0)
+                        executeAndNoCatch(() -> LongStream.range(start, end, step));
+                    else
+                        executeAndCatch(() -> LongStream.range(start, end, step));
+                }
+            }
+        }
+    }
+
+    public void testLongRange() {
+        // Without step
+        for (long start : Arrays.asList(1, 1000, -1, -1000)) {
+            for (long end : Arrays.asList(1, 1000, -1, -1000)) {
+                long step = 1;
+                long size = start < end ? end - start : 0;
+                long[] exp = new long[(int) size];
+                if (start < end) {
+                    for (long i = start, p = 0; i < end; i++, p++) {
+                        exp[(int) p] = i;
+                    }
+                }
+
+                long[] inc = LongStream.range(start, end).toArray();
+                assertEquals(inc.length, size);
+                assertTrue(Arrays.equals(exp, inc));
+
+                withData(longRangeData(start, end, step)).stream(s -> s).
+                        expectedResult(exp).exercise();
+            }
+        }
+
+        // With step
+        for (long start : Arrays.asList(1, 1000, -1, -1000)) {
+            for (long end : Arrays.asList(1, 1000, -1, -1000)) {
+                for (long step : Arrays.asList(1, -1, -2, 2)) {
+                    if (step > 0) {
+
+                        long d = end - start;
+                        long size = start < end ? (d / step) + ((d % step == 0) ? 0 : 1) : 0;
+                        long[] exp = new long[(int) size];
+                        if (start < end) {
+                            for (long i = start, p = 0; i < end; i += step, p++) {
+                                exp[(int) p] = i;
+                            }
+                        }
+
+                        long[] inc = LongStream.range(start, end, step).toArray();
+                        assertEquals(inc.length, size);
+                        assertTrue(Arrays.equals(exp, inc));
+
+                        withData(longRangeData(start, end, step)).stream(s -> s).
+                                expectedResult(exp).exercise();
+                    }
+                }
+            }
+        }
+    }
+
+    TestData.OfLong longRangeData(long start, long end, long step) {
+        return TestData.Factory.ofLongSupplier("long range", () -> LongStream.range(start, end, step));
+    }
+
+    public void testLongRangeReduce() {
+        withData(longRangeData(0, 10000, 1)).
+                terminal(s -> s.reduce(0, Long::sum)).exercise();
+    }
+
+    public void testLongInfiniteRangeLimit() {
+        withData(TestData.Factory.ofLongSupplier(
+                "long range", () -> LongStream.iterate(0, i -> i + 1).limit(10000))).
+                terminal(s -> s.reduce(0, Long::sum)).exercise();
+    }
+
+    public void testLongInfiniteRangeFindFirst() {
+        long first = LongStream.iterate(0, i -> i + 1).filter(i -> i > 10000).findFirst().getAsLong();
+        assertEquals(first, LongStream.iterate(0, i -> i + 1).parallel().filter(i -> i > 10000).findFirst().getAsLong());
+    }
+
+    //
+
+    public void testDoubleRangeErrors() {
+        for (double start : Arrays.asList(1, 10, -1, -10)) {
+            for (double end : Arrays.asList(1, 10, -1, -10)) {
+                for (double step : Arrays.asList(0.0, +0.0, -0.0, 1.0, -1.0, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY)) {
+                    try {
+                        if (step > 0)
+                            executeAndNoCatch(() -> DoubleStream.range(start, end, step));
+                        else
+                            executeAndCatch(() -> DoubleStream.range(start, end, step));
+                    }
+                    catch (AssertionError e) {
+                        System.out.printf("start=%f, end=%f, step=%f%n", start, end, step);
+                        throw e;
+                    }
+                }
+            }
+        }
+
+        for (double start : Arrays.asList(0.0, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NaN)) {
+            for (double end : Arrays.asList(0.0, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NaN)) {
+                for (double step : Arrays.asList(1.0, -1.0, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NaN)) {
+                    try {
+                        if ((start == 0.0 && end == 0.0 && step > 0)
+                            || (start > end && step > 0)) {
+                            executeAndNoCatch(() -> DoubleStream.range(start, end, step));
+                        }
+                        else {
+                            executeAndCatch(() -> DoubleStream.range(start, end, step));
+                        }
+                    }
+                    catch (AssertionError e) {
+                        System.out.printf("start=%f, end=%f, step=%f%n", start, end, step);
+                        throw e;
+                    }
+                }
+            }
+        }
+    }
+
+    public void testDoubleRange() {
+        // Without step
+        for (double start : Arrays.asList(1, 1000, -1, -1000)) {
+            for (double end : Arrays.asList(1, 1000, -1, -1000)) {
+                double step = 1;
+                double size = start < end ? Math.ceil((end - start) / step) : 0;
+                double[] exp = new double[(int) size];
+                for (long i = 0; i < size; i++) {
+                    exp[(int) i] = start + i * step;
+                }
+
+                double[] inc = DoubleStream.range(start, end).toArray();
+                assertEquals(inc.length, (int) size);
+                assertTrue(Arrays.equals(exp, inc));
+
+                withData(doubleRangeData(start, end, step)).stream(s -> s).
+                        expectedResult(exp).exercise();
+            }
+        }
+
+        // With step
+        for (double start : Arrays.asList(1, 1000, -1, -1000)) {
+            for (double end : Arrays.asList(1, 1000, -1, -1000)) {
+                for (double step : Arrays.asList(1, -1, -2, 2)) {
+                    if (step <= 0)
+                        continue;
+                    double size = start < end ? Math.ceil((end - start) / step) : 0;
+                    double[] exp = new double[(int) size];
+                    for (long i = 0; i < size; i++) {
+                        exp[(int) i] = start + i * step;
+                    }
+
+                    double[] inc = DoubleStream.range(start, end, step).toArray();
+                    assertEquals(inc.length, (int) size);
+                    assertTrue(Arrays.equals(exp, inc));
+
+                    withData(doubleRangeData(start, end, step)).stream(s -> s).
+                            expectedResult(exp).exercise();
+                }
+            }
+        }
+
+        // With non-integer values
+        for (double step : Arrays.asList(Math.PI / 1000.0, Math.PI / 1000.0, Math.PI / 10000.0)) {
+            double start = -Math.PI;
+            double end = Math.PI;
+            double size = start < end ? Math.ceil((end - start) / step) : 0;
+            double[] exp = new double[(int) size];
+            for (long i = 0; i < size; i++) {
+                exp[(int) i] = start + i * step;
+            }
+
+            withData(doubleRangeData(start, end, step)).stream(s -> s).
+                    expectedResult(exp).exercise();
+        }
+    }
+
+    TestData.OfDouble doubleRangeData(double start, double end, double step) {
+        return TestData.Factory.ofDoubleSupplier("double range", () -> DoubleStream.range(start, end, step));
+    }
+
+    public void tesDoubleRangeReduce() {
+        withData(doubleRangeData(0, 10000, 1)).
+                terminal(s -> s.reduce(0, Double::sum)).exercise();
+    }
+
+    public void testDoubleInfiniteRangeLimit() {
+        withData(TestData.Factory.ofDoubleSupplier(
+                "double range", () -> DoubleStream.iterate(0, i -> i + 1).limit(10000))).
+                terminal(s -> s.reduce(0, Double::sum)).exercise();
+    }
+
+    public void testDoubleInfiniteRangeFindFirst() {
+        double first = DoubleStream.iterate(0, i -> i + 1).filter(i -> i > 10000).findFirst().getAsDouble();
+        assertEquals(first, DoubleStream.iterate(0, i -> i + 1).parallel().filter(i -> i > 10000).findFirst().getAsDouble());
+    }
+
+    //
+
+    private static int[] reverse(int[] a) {
+        int[] b = new int[a.length];
+        for (int i = 0; i < a.length; i++) {
+            b[b.length - i - 1] = a[i];
+        }
+        return b;
+    }
+
+    private static long[] reverse(long[] a) {
+        long[] b = new long[a.length];
+        for (int i = 0; i < a.length; i++) {
+            b[b.length - i - 1] = a[i];
+        }
+        return b;
+    }
+
+    private static double[] reverse(double[] a) {
+        double[] b = new double[a.length];
+        for (int i = 0; i < a.length; i++) {
+            b[b.length - i - 1] = a[i];
+        }
+        return b;
+    }
+
+    private void executeAndCatch(Runnable r) {
+        executeAndCatch(IllegalArgumentException.class, r);
+    }
+
+    private void executeAndNoCatch(Runnable r) {
+        executeAndCatch(null, r);
+    }
+
+    private void executeAndCatch(Class<? extends Exception> expected, Runnable r) {
+        Exception caught = null;
+        try {
+            r.run();
+        }
+        catch (Exception e) {
+            caught = e;
+        }
+
+        if (expected != null) {
+            assertNotNull(caught,
+                          String.format("No Exception was thrown, expected an Exception of %s to be thrown",
+                                        expected.getName()));
+            assertTrue(expected.isInstance(caught),
+                       String.format("Exception thrown %s not an instance of %s",
+                                     caught.getClass().getName(), expected.getName()));
+        }
+        else {
+            if (caught != null) {
+                assertNull(caught,
+                           String.format("Unexpected exception of %s was thrown",
+                                         caught.getClass().getName()));
+            }
+        }
+    }
+
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ReduceByOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ReduceByOpTest.java
new file mode 100644
index 0000000..539ed9b
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ReduceByOpTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.List;
+import java.util.stream.LambdaTestHelpers;
+import java.util.stream.OpTestCase;
+import java.util.stream.Stream;
+import java.util.stream.StreamTestDataProvider;
+import org.testng.annotations.Test;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.stream.TestData;
+
+import static java.util.stream.Collectors.groupingBy;
+import static java.util.stream.Collectors.reducing;
+import static java.util.stream.LambdaTestHelpers.*;
+
+/**
+ * ReduceByOpTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class ReduceByOpTest extends OpTestCase {
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfRef<Integer> data) {
+        Map<Boolean,List<Integer>> gbResult = data.stream().collect(groupingBy(LambdaTestHelpers.forPredicate(pEven, true, false)));
+        Map<Boolean, Integer> result = data.stream().collect(groupingBy(LambdaTestHelpers.forPredicate(pEven, true, false), reducing(0, rPlus)));
+        assertEquals(result.size(), gbResult.size());
+        for (Map.Entry<Boolean, Integer> entry : result.entrySet()) {
+            Boolean key = entry.getKey();
+            assertEquals(entry.getValue(), data.stream().filter(e -> pEven.test(e) == key).reduce(0, rPlus));
+        }
+
+        int uniqueSize = data.into(new HashSet<Integer>()).size();
+        Map<Integer, List<Integer>> mgResult = exerciseTerminalOps(data, s -> s.collect(groupingBy(mId)));
+        Map<Integer, Integer> miResult = exerciseTerminalOps(data, s -> s.collect(groupingBy(mId, reducing(0, e -> 1, Integer::sum))));
+        assertEquals(miResult.keySet().size(), uniqueSize);
+        for (Map.Entry<Integer, Integer> entry : miResult.entrySet())
+            assertEquals((int) entry.getValue(), mgResult.get(entry.getKey()).size());
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ReduceTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ReduceTest.java
new file mode 100644
index 0000000..fd4c687
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ReduceTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.stream.OpTestCase;
+import java.util.stream.Stream;
+import java.util.stream.StreamTestDataProvider;
+import org.testng.annotations.Test;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.TestData;
+
+import static java.util.stream.LambdaTestHelpers.*;
+
+/**
+ * ReduceOpTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class ReduceTest extends OpTestCase {
+    public void testReduce() {
+        List<Integer> list = countTo(10);
+
+        assertEquals(55, (int) list.stream().reduce(rPlus).get());
+        assertEquals(55, (int) list.stream().reduce(0, rPlus));
+        assertEquals(10, (int) list.stream().reduce(rMax).get());
+        assertEquals(1, (int) list.stream().reduce(rMin).get());
+
+        assertEquals(0, (int) countTo(0).stream().reduce(0, rPlus));
+        assertTrue(!countTo(0).stream().reduce(rPlus).isPresent());
+
+        assertEquals(110, (int) list.stream().map(mDoubler).reduce(rPlus).get());
+        assertEquals(20, (int) list.stream().map(mDoubler).reduce(rMax).get());
+        assertEquals(2, (int) list.stream().map(mDoubler).reduce(rMin).get());
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfRef<Integer> data) {
+        assertEquals(0, (int) exerciseTerminalOps(data, s -> s.filter(pFalse), s -> s.reduce(0, rPlus, rPlus)));
+
+        Optional<Integer> seedless = exerciseTerminalOps(data, s -> s.reduce(rPlus));
+        Integer folded = exerciseTerminalOps(data, s -> s.reduce(0, rPlus, rPlus));
+        assertEquals(folded, seedless.orElse(0));
+
+        seedless = exerciseTerminalOps(data, s -> s.reduce(rMin));
+        folded = exerciseTerminalOps(data, s -> s.reduce(Integer.MAX_VALUE, rMin, rMin));
+        assertEquals(folded, seedless.orElse(Integer.MAX_VALUE));
+
+        seedless = exerciseTerminalOps(data, s -> s.reduce(rMax));
+        folded = exerciseTerminalOps(data, s -> s.reduce(Integer.MIN_VALUE, rMax, rMax));
+        assertEquals(folded, seedless.orElse(Integer.MIN_VALUE));
+
+        seedless = exerciseTerminalOps(data, s -> s.map(mDoubler), s -> s.reduce(rPlus));
+        folded = exerciseTerminalOps(data, s -> s.map(mDoubler), s -> s.reduce(0, rPlus, rPlus));
+        assertEquals(folded, seedless.orElse(0));
+
+        seedless = exerciseTerminalOps(data, s -> s.map(mDoubler), s -> s.reduce(rMin));
+        folded = exerciseTerminalOps(data, s -> s.map(mDoubler), s -> s.reduce(Integer.MAX_VALUE, rMin, rMin));
+        assertEquals(folded, seedless.orElse(Integer.MAX_VALUE));
+
+        seedless = exerciseTerminalOps(data, s -> s.map(mDoubler), s -> s.reduce(rMax));
+        folded = exerciseTerminalOps(data, s -> s.map(mDoubler), s -> s.reduce(Integer.MIN_VALUE, rMax, rMax));
+        assertEquals(folded, seedless.orElse(Integer.MIN_VALUE));
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SequentialOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SequentialOpTest.java
new file mode 100644
index 0000000..e748100
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SequentialOpTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.stream.LambdaTestHelpers;
+import java.util.stream.OpTestCase;
+import java.util.stream.StreamTestDataProvider;
+import org.testng.annotations.Test;
+
+import java.util.Comparators;
+import java.util.Iterator;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
+import java.util.Spliterator;
+import java.util.stream.Stream;
+import java.util.stream.TestData;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * SequentialOpTest
+ *
+ * @author Brian Goetz
+ */
+public class SequentialOpTest extends OpTestCase {
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class,
+          groups = { "serialization-hostile" })
+    public void testLazy(String name, TestData.OfRef<Integer> data) {
+        Function<Integer, Integer> id = LambdaTestHelpers.identity();
+        AtomicInteger counter = new AtomicInteger();
+        Supplier<Stream<Integer>>[] suppliers = new Supplier[] { () -> data.stream(), () -> data.parallelStream() };
+        UnaryOperator<Stream<Integer>>[] configs
+                = new UnaryOperator[] {
+                    (UnaryOperator<Stream<Integer>>) s -> s.peek(e -> { counter.incrementAndGet(); }),
+                    (UnaryOperator<Stream<Integer>>) s -> s.map(id).peek(e -> { counter.incrementAndGet(); }).sequential().map(id),
+                    (UnaryOperator<Stream<Integer>>) s -> s.map(id).peek(e -> { counter.incrementAndGet(); }).parallel().map(id),
+                    (UnaryOperator<Stream<Integer>>) s -> s.sequential().map(id).peek(e -> {
+                        counter.incrementAndGet();
+                    }).map(id),
+                    (UnaryOperator<Stream<Integer>>) s -> s.parallel().map(id).peek(e -> { counter.incrementAndGet(); }).map(id)
+        };
+
+        for (Supplier<Stream<Integer>> supp : suppliers)
+            for (UnaryOperator<Stream<Integer>> config : configs) {
+                counter.set(0);
+                Stream<Integer> stream = config.apply(supp.get());
+                assertEquals(0, counter.get());
+
+                Iterator<Integer> iterator = stream.iterator();
+                assertEquals(0, counter.get());
+
+                if (iterator.hasNext())
+                    iterator.next();
+                assertTrue(data.size() == 0 || counter.get() > 0);
+
+                counter.set(0);
+                stream = config.apply(supp.get());
+                Spliterator<Integer> spliterator = stream.spliterator();
+                assertEquals(0, counter.get());
+
+                spliterator.forEachRemaining(e -> {
+                });
+                assertTrue(data.size() == 0 || counter.get() > 0);
+            }
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testMixedSeqPar(String name, TestData.OfRef<Integer> data) {
+        Function<Integer, Integer> id = LambdaTestHelpers.identity();
+        UnaryOperator<Stream<Integer>>[] changers
+                = new UnaryOperator[] {
+                (UnaryOperator<Stream<Integer>>) s -> s,
+                (UnaryOperator<Stream<Integer>>) s -> s.sequential(),
+                (UnaryOperator<Stream<Integer>>) s -> s.parallel()
+        };
+        UnaryOperator<Stream<Integer>>[] stuff
+                = new UnaryOperator[] {
+                (UnaryOperator<Stream<Integer>>) s -> s,
+                (UnaryOperator<Stream<Integer>>) s -> s.map(id),
+                (UnaryOperator<Stream<Integer>>) s -> s.sorted(Comparators.naturalOrder()),
+                (UnaryOperator<Stream<Integer>>) s -> s.map(id).sorted(Comparators.naturalOrder()).map(id),
+                (UnaryOperator<Stream<Integer>>) s -> s.filter(LambdaTestHelpers.pEven).sorted(Comparators.naturalOrder()).map(id),
+        };
+
+        for (UnaryOperator<Stream<Integer>> c1 : changers)
+            for (UnaryOperator<Stream<Integer>> s1 : stuff)
+                for (UnaryOperator<Stream<Integer>> c2 : changers)
+                    for (UnaryOperator<Stream<Integer>> s2 : stuff) {
+                        UnaryOperator<Stream<Integer>> composed = s -> s2.apply(c2.apply(s1.apply(c1.apply(s))));
+                        exerciseOps(data, composed);
+                    }
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java
new file mode 100644
index 0000000..5074ce9
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+import java.util.stream.OpTestCase;
+import java.util.stream.Stream;
+import java.util.stream.StreamTestDataProvider;
+import java.util.stream.TestData;
+
+import static java.util.stream.LambdaTestHelpers.*;
+
+/**
+ * SliceOpTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class SliceOpTest extends OpTestCase {
+
+    public void testSkip() {
+        assertCountSum(countTo(0).stream().substream(0), 0, 0);
+        assertCountSum(countTo(0).stream().substream(4), 0, 0);
+        assertCountSum(countTo(4).stream().substream(4), 0, 0);
+        assertCountSum(countTo(4).stream().substream(2), 2, 7);
+        assertCountSum(countTo(4).stream().substream(0), 4, 10);
+
+        assertCountSum(countTo(0).parallelStream().substream(0), 0, 0);
+        assertCountSum(countTo(0).parallelStream().substream(4), 0, 0);
+        assertCountSum(countTo(4).parallelStream().substream(4), 0, 0);
+        assertCountSum(countTo(4).parallelStream().substream(2), 2, 7);
+        assertCountSum(countTo(4).parallelStream().substream(0), 4, 10);
+
+        exerciseOps(Collections.emptyList(), s -> s.substream(0), Collections.emptyList());
+        exerciseOps(Collections.emptyList(), s -> s.substream(10), Collections.emptyList());
+
+        exerciseOps(countTo(1), s -> s.substream(0), countTo(1));
+        exerciseOps(countTo(1), s -> s.substream(1), Collections.emptyList());
+        exerciseOps(countTo(100), s -> s.substream(0), countTo(100));
+        exerciseOps(countTo(100), s -> s.substream(10), range(11, 100));
+        exerciseOps(countTo(100), s -> s.substream(100), Collections.emptyList());
+        exerciseOps(countTo(100), s -> s.substream(200), Collections.emptyList());
+    }
+
+    public void testLimit() {
+        assertCountSum(countTo(0).stream().limit(4), 0, 0);
+        assertCountSum(countTo(2).stream().limit(4), 2, 3);
+        assertCountSum(countTo(4).stream().limit(4), 4, 10);
+        assertCountSum(countTo(8).stream().limit(4), 4, 10);
+
+        assertCountSum(countTo(0).parallelStream().limit(4), 0, 0);
+        assertCountSum(countTo(2).parallelStream().limit(4), 2, 3);
+        assertCountSum(countTo(4).parallelStream().limit(4), 4, 10);
+        assertCountSum(countTo(8).parallelStream().limit(4), 4, 10);
+
+        exerciseOps(Collections.emptyList(), s -> s.limit(0), Collections.emptyList());
+        exerciseOps(Collections.emptyList(), s -> s.limit(10), Collections.emptyList());
+        exerciseOps(countTo(1), s -> s.limit(0), Collections.emptyList());
+        exerciseOps(countTo(1), s -> s.limit(1), countTo(1));
+        exerciseOps(countTo(100), s -> s.limit(0), Collections.emptyList());
+        exerciseOps(countTo(100), s -> s.limit(10), countTo(10));
+        exerciseOps(countTo(100), s -> s.limit(10).limit(10), countTo(10));
+        exerciseOps(countTo(100), s -> s.limit(100), countTo(100));
+        exerciseOps(countTo(100), s -> s.limit(100).limit(10), countTo(10));
+        exerciseOps(countTo(100), s -> s.limit(200), countTo(100));
+    }
+
+    public void testSkipLimit() {
+        exerciseOps(Collections.emptyList(), s -> s.substream(0).limit(0), Collections.emptyList());
+        exerciseOps(Collections.emptyList(), s -> s.substream(0).limit(10), Collections.emptyList());
+        exerciseOps(Collections.emptyList(), s -> s.substream(10).limit(0), Collections.emptyList());
+        exerciseOps(Collections.emptyList(), s -> s.substream(10).limit(10), Collections.emptyList());
+
+        exerciseOps(countTo(100), s -> s.substream(0).limit(100), countTo(100));
+        exerciseOps(countTo(100), s -> s.substream(0).limit(10), countTo(10));
+        exerciseOps(countTo(100), s -> s.substream(0).limit(0), Collections.emptyList());
+        exerciseOps(countTo(100), s -> s.substream(10).limit(100), range(11, 100));
+        exerciseOps(countTo(100), s -> s.substream(10).limit(10), range(11, 20));
+        exerciseOps(countTo(100), s -> s.substream(10).limit(0), Collections.emptyList());
+        exerciseOps(countTo(100), s -> s.substream(100).limit(100), Collections.emptyList());
+        exerciseOps(countTo(100), s -> s.substream(100).limit(10), Collections.emptyList());
+        exerciseOps(countTo(100), s -> s.substream(100).limit(0), Collections.emptyList());
+        exerciseOps(countTo(100), s -> s.substream(200).limit(100), Collections.emptyList());
+        exerciseOps(countTo(100), s -> s.substream(200).limit(10), Collections.emptyList());
+        exerciseOps(countTo(100), s -> s.substream(200).limit(0), Collections.emptyList());
+    }
+
+    public void testSlice() {
+        exerciseOps(Collections.emptyList(), s -> s.substream(0, 0), Collections.emptyList());
+        exerciseOps(Collections.emptyList(), s -> s.substream(0, 10), Collections.emptyList());
+        exerciseOps(Collections.emptyList(), s -> s.substream(10, 10), Collections.emptyList());
+        exerciseOps(Collections.emptyList(), s -> s.substream(10, 20), Collections.emptyList());
+
+        exerciseOps(countTo(100), s -> s.substream(0, 100), countTo(100));
+        exerciseOps(countTo(100), s -> s.substream(0, 10), countTo(10));
+        exerciseOps(countTo(100), s -> s.substream(0, 0), Collections.emptyList());
+        exerciseOps(countTo(100), s -> s.substream(10, 110), range(11, 100));
+        exerciseOps(countTo(100), s -> s.substream(10, 20), range(11, 20));
+        exerciseOps(countTo(100), s -> s.substream(10, 10), Collections.emptyList());
+        exerciseOps(countTo(100), s -> s.substream(100, 200), Collections.emptyList());
+        exerciseOps(countTo(100), s -> s.substream(100, 110), Collections.emptyList());
+        exerciseOps(countTo(100), s -> s.substream(100, 100), Collections.emptyList());
+        exerciseOps(countTo(100), s -> s.substream(200, 300), Collections.emptyList());
+        exerciseOps(countTo(100), s -> s.substream(200, 210), Collections.emptyList());
+        exerciseOps(countTo(100), s -> s.substream(200, 200), Collections.emptyList());
+    }
+
+    private int sliceSize(int dataSize, int skip, int limit) {
+        int size = Math.max(0, dataSize - skip);
+        if (limit >= 0)
+            size = Math.min(size, limit);
+        return size;
+    }
+
+    private int sliceSize(int dataSize, int skip) {
+        return Math.max(0, dataSize - skip);
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testSkipOps(String name, TestData.OfRef<Integer> data) {
+        List<Integer> skips = sizes(data.size());
+
+        for (int s : skips) {
+            Collection<Integer> sr = exerciseOpsInt(data,
+                                                      st -> st.substream(s),
+                                                      st -> st.substream(s),
+                                                      st -> st.substream(s),
+                                                      st -> st.substream(s));
+            assertEquals(sr.size(), sliceSize(data.size(), s));
+
+            sr = exerciseOpsInt(data,
+                                  st -> st.substream(s).substream(s / 2),
+                                  st -> st.substream(s).substream(s / 2),
+                                  st -> st.substream(s).substream(s / 2),
+                                  st -> st.substream(s).substream(s / 2));
+            assertEquals(sr.size(), sliceSize(sliceSize(data.size(), s), s/2));
+        }
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testSkipLimitOps(String name, TestData.OfRef<Integer> data) {
+        List<Integer> skips = sizes(data.size());
+        List<Integer> limits = skips;
+
+        for (int s : skips) {
+            for (int limit : limits) {
+                Collection<Integer> sr = exerciseOpsInt(data,
+                                                        st -> st.substream(s).limit(limit),
+                                                        st -> st.substream(s).limit(limit),
+                                                        st -> st.substream(s).limit(limit),
+                                                        st -> st.substream(s).limit(limit));
+                assertEquals(sr.size(), sliceSize(sliceSize(data.size(), s), 0, limit));
+
+                sr = exerciseOpsInt(data,
+                                    st -> st.substream(s, limit+s),
+                                    st -> st.substream(s, limit+s),
+                                    st -> st.substream(s, limit+s),
+                                    st -> st.substream(s, limit+s));
+                assertEquals(sr.size(), sliceSize(data.size(), s, limit));
+            }
+        }
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testLimitOps(String name, TestData.OfRef<Integer> data) {
+        List<Integer> limits = sizes(data.size());
+
+        for (int limit : limits) {
+            Collection<Integer> sr = exerciseOpsInt(data,
+                                                    st -> st.limit(limit),
+                                                    st -> st.limit(limit),
+                                                    st -> st.limit(limit),
+                                                    st -> st.limit(limit));
+            assertEquals(sr.size(), sliceSize(data.size(), 0, limit));
+
+            sr = exerciseOpsInt(data,
+                                st -> st.limit(limit).limit(limit / 2),
+                                st -> st.limit(limit).limit(limit / 2),
+                                st -> st.limit(limit).limit(limit / 2),
+                                st -> st.limit(limit).limit(limit / 2));
+            assertEquals(sr.size(), sliceSize(sliceSize(data.size(), 0, limit), 0, limit/2));
+        }
+    }
+
+    public void testLimitSort() {
+        List<Integer> l = countTo(100);
+        Collections.reverse(l);
+        exerciseOps(l, s -> s.limit(10).sorted(Comparators.naturalOrder()));
+    }
+
+    @Test(groups = { "serialization-hostile" })
+    public void testLimitShortCircuit() {
+        for (int l : Arrays.asList(0, 10)) {
+            AtomicInteger ai = new AtomicInteger();
+            countTo(100).stream()
+                    .peek(i -> ai.getAndIncrement())
+                    .limit(l).toArray();
+            // For the case of a zero limit, one element will get pushed through the sink chain
+            assertEquals(ai.get(), l, "tee block was called too many times");
+        }
+    }
+
+    public void testSkipParallel() {
+        List<Integer> l = countTo(1000).parallelStream().substream(200).limit(200).sequential().collect(Collectors.toList());
+        assertEquals(l.size(), 200);
+        assertEquals(l.get(l.size() -1).intValue(), 400);
+    }
+
+    public void testLimitParallel() {
+        List<Integer> l = countTo(1000).parallelStream().limit(500).sequential().collect(Collectors.toList());
+        assertEquals(l.size(), 500);
+        assertEquals(l.get(l.size() -1).intValue(), 500);
+    }
+
+    private List<Integer> sizes(int size) {
+        if (size < 4) {
+            return Arrays.asList(0, 1, 2, 3, 4, 6);
+        }
+        else {
+            return Arrays.asList(0, 1, size / 2, size - 1, size, size + 1, 2 * size);
+        }
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SortedOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SortedOpTest.java
new file mode 100644
index 0000000..2d1886b
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SortedOpTest.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.*;
+import java.util.Spliterators;
+import java.util.stream.*;
+
+import static java.util.stream.LambdaTestHelpers.*;
+
+/**
+ * SortedOpTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class SortedOpTest extends OpTestCase {
+    public void testSorted() {
+        assertCountSum(countTo(0).stream().sorted(), 0, 0);
+        assertCountSum(countTo(10).stream().sorted(), 10, 55);
+        assertCountSum(countTo(10).stream().sorted(cInteger.reverseOrder()), 10, 55);
+
+        List<Integer> to10 = countTo(10);
+        assertSorted(to10.stream().sorted(cInteger.reverseOrder()).iterator(), cInteger.reverseOrder());
+
+        Collections.reverse(to10);
+        assertSorted(to10.stream().sorted().iterator());
+
+        Spliterator<Integer> s = to10.stream().sorted().spliterator();
+        assertTrue(s.hasCharacteristics(Spliterator.SORTED));
+
+        s = to10.stream().sorted(cInteger.reverseOrder()).spliterator();
+        assertFalse(s.hasCharacteristics(Spliterator.SORTED));
+    }
+
+    @Test(groups = { "serialization-hostile" })
+    public void testSequentialShortCircuitTerminal() {
+        // The sorted op for sequential evaluation will buffer all elements when accepting
+        // then at the end sort those elements and push those elements downstream
+
+        List<Integer> l = Arrays.asList(5, 4, 3, 2, 1);
+
+        // Find
+        assertEquals(l.stream().sorted().findFirst(), Optional.of(1));
+        assertEquals(l.stream().sorted().findAny(), Optional.of(1));
+        assertEquals(unknownSizeStream(l).sorted().findFirst(), Optional.of(1));
+        assertEquals(unknownSizeStream(l).sorted().findAny(), Optional.of(1));
+
+        // Match
+        assertEquals(l.stream().sorted().anyMatch(i -> i == 2), true);
+        assertEquals(l.stream().sorted().noneMatch(i -> i == 2), false);
+        assertEquals(l.stream().sorted().allMatch(i -> i == 2), false);
+        assertEquals(unknownSizeStream(l).sorted().anyMatch(i -> i == 2), true);
+        assertEquals(unknownSizeStream(l).sorted().noneMatch(i -> i == 2), false);
+        assertEquals(unknownSizeStream(l).sorted().allMatch(i -> i == 2), false);
+    }
+
+    private <T> Stream<T> unknownSizeStream(List<T> l) {
+        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(l.iterator(), 0));
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfRef<Integer> data) {
+        Collection<Integer> result = exerciseOpsInt(data, Stream::sorted, IntStream::sorted, LongStream::sorted, DoubleStream::sorted);
+        assertSorted(result.iterator());
+        assertContentsUnordered(data, result);
+
+        result = exerciseOps(data, s -> s.sorted(cInteger.reverseOrder()));
+        assertSorted(result.iterator(), cInteger.reverseOrder());
+        assertContentsUnordered(data, result);
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testSortSort(String name, TestData.OfRef<Integer> data) {
+        // For parallel cases ensure the size is known
+        Collection<Integer> result = withData(data)
+                .stream(s -> s.sorted().sorted(),
+                        new CollectorOps.TestParallelSizedOp<Integer>())
+                .exercise();
+
+        assertSorted(result);
+        assertContentsUnordered(data, result);
+
+        result = withData(data)
+                .stream(s -> s.sorted(cInteger.reverseOrder()).sorted(cInteger.reverseOrder()),
+                        new CollectorOps.TestParallelSizedOp<Integer>())
+                .exercise();
+
+        assertSorted(result, cInteger.reverseOrder());
+        assertContentsUnordered(data, result);
+
+        result = withData(data)
+                .stream(s -> s.sorted().sorted(cInteger.reverseOrder()),
+                        new CollectorOps.TestParallelSizedOp<Integer>())
+                .exercise();
+
+        assertSorted(result, cInteger.reverseOrder());
+        assertContentsUnordered(data, result);
+
+        result = withData(data)
+                .stream(s -> s.sorted(cInteger.reverseOrder()).sorted(),
+                        new CollectorOps.TestParallelSizedOp<Integer>())
+                .exercise();
+
+        assertSorted(result);
+        assertContentsUnordered(data, result);
+    }
+
+    //
+
+    @Test(groups = { "serialization-hostile" })
+    public void testIntSequentialShortCircuitTerminal() {
+        int[] a = new int[]{5, 4, 3, 2, 1};
+
+        // Find
+        assertEquals(Arrays.stream(a).sorted().findFirst(), OptionalInt.of(1));
+        assertEquals(Arrays.stream(a).sorted().findAny(), OptionalInt.of(1));
+        assertEquals(unknownSizeIntStream(a).sorted().findFirst(), OptionalInt.of(1));
+        assertEquals(unknownSizeIntStream(a).sorted().findAny(), OptionalInt.of(1));
+
+        // Match
+        assertEquals(Arrays.stream(a).sorted().anyMatch(i -> i == 2), true);
+        assertEquals(Arrays.stream(a).sorted().noneMatch(i -> i == 2), false);
+        assertEquals(Arrays.stream(a).sorted().allMatch(i -> i == 2), false);
+        assertEquals(unknownSizeIntStream(a).sorted().anyMatch(i -> i == 2), true);
+        assertEquals(unknownSizeIntStream(a).sorted().noneMatch(i -> i == 2), false);
+        assertEquals(unknownSizeIntStream(a).sorted().allMatch(i -> i == 2), false);
+    }
+
+    private IntStream unknownSizeIntStream(int[] a) {
+        return StreamSupport.intStream(Spliterators.spliteratorUnknownSize(Spliterators.iteratorFromSpliterator(Arrays.spliterator(a)), 0));
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntOps(String name, TestData.OfInt data) {
+        Collection<Integer> result = exerciseOps(data, s -> s.sorted());
+        assertSorted(result);
+        assertContentsUnordered(data, result);
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntSortSort(String name, TestData.OfInt data) {
+        // For parallel cases ensure the size is known
+        Collection<Integer> result = withData(data)
+                .stream(s -> s.sorted().sorted(), new CollectorOps.TestParallelSizedOp.OfInt())
+                .exercise();
+
+        assertSorted(result);
+        assertContentsUnordered(data, result);
+    }
+
+    //
+
+    @Test(groups = { "serialization-hostile" })
+    public void testLongSequentialShortCircuitTerminal() {
+        long[] a = new long[]{5, 4, 3, 2, 1};
+
+        // Find
+        assertEquals(Arrays.stream(a).sorted().findFirst(), OptionalLong.of(1));
+        assertEquals(Arrays.stream(a).sorted().findAny(), OptionalLong.of(1));
+        assertEquals(unknownSizeLongStream(a).sorted().findFirst(), OptionalLong.of(1));
+        assertEquals(unknownSizeLongStream(a).sorted().findAny(), OptionalLong.of(1));
+
+        // Match
+        assertEquals(Arrays.stream(a).sorted().anyMatch(i -> i == 2), true);
+        assertEquals(Arrays.stream(a).sorted().noneMatch(i -> i == 2), false);
+        assertEquals(Arrays.stream(a).sorted().allMatch(i -> i == 2), false);
+        assertEquals(unknownSizeLongStream(a).sorted().anyMatch(i -> i == 2), true);
+        assertEquals(unknownSizeLongStream(a).sorted().noneMatch(i -> i == 2), false);
+        assertEquals(unknownSizeLongStream(a).sorted().allMatch(i -> i == 2), false);
+    }
+
+    private LongStream unknownSizeLongStream(long[] a) {
+        return StreamSupport.longStream(Spliterators.spliteratorUnknownSize(Spliterators.iteratorFromSpliterator(Arrays.spliterator(a)), 0));
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongOps(String name, TestData.OfLong data) {
+        Collection<Long> result = exerciseOps(data, s -> s.sorted());
+        assertSorted(result);
+        assertContentsUnordered(data, result);
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongSortSort(String name, TestData.OfLong data) {
+        // For parallel cases ensure the size is known
+        Collection<Long> result = withData(data)
+                .stream(s -> s.sorted().sorted(), new CollectorOps.TestParallelSizedOp.OfLong())
+                .exercise();
+
+        assertSorted(result);
+        assertContentsUnordered(data, result);
+    }
+
+    //
+
+    @Test(groups = { "serialization-hostile" })
+    public void testDoubleSequentialShortCircuitTerminal() {
+        double[] a = new double[]{5.0, 4.0, 3.0, 2.0, 1.0};
+
+        // Find
+        assertEquals(Arrays.stream(a).sorted().findFirst(), OptionalDouble.of(1));
+        assertEquals(Arrays.stream(a).sorted().findAny(), OptionalDouble.of(1));
+        assertEquals(unknownSizeDoubleStream(a).sorted().findFirst(), OptionalDouble.of(1));
+        assertEquals(unknownSizeDoubleStream(a).sorted().findAny(), OptionalDouble.of(1));
+
+        // Match
+        assertEquals(Arrays.stream(a).sorted().anyMatch(i -> i == 2.0), true);
+        assertEquals(Arrays.stream(a).sorted().noneMatch(i -> i == 2.0), false);
+        assertEquals(Arrays.stream(a).sorted().allMatch(i -> i == 2.0), false);
+        assertEquals(unknownSizeDoubleStream(a).sorted().anyMatch(i -> i == 2.0), true);
+        assertEquals(unknownSizeDoubleStream(a).sorted().noneMatch(i -> i == 2.0), false);
+        assertEquals(unknownSizeDoubleStream(a).sorted().allMatch(i -> i == 2.0), false);
+    }
+
+    private DoubleStream unknownSizeDoubleStream(double[] a) {
+        return StreamSupport.doubleStream(Spliterators.spliteratorUnknownSize(Spliterators.iteratorFromSpliterator(Arrays.spliterator(a)), 0));
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleOps(String name, TestData.OfDouble data) {
+        Collection<Double> result = exerciseOps(data, s -> s.sorted());
+        assertSorted(result);
+        assertContentsUnordered(data, result);
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleSortSort(String name, TestData.OfDouble data) {
+        // For parallel cases ensure the size is known
+        Collection<Double> result = withData(data)
+                .stream(s -> s.sorted().sorted(), new CollectorOps.TestParallelSizedOp.OfDouble())
+                .exercise();
+
+        assertSorted(result);
+        assertContentsUnordered(data, result);
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SpliteratorLateBindingFailFastTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SpliteratorLateBindingFailFastTest.java
new file mode 100644
index 0000000..af7ddbf
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SpliteratorLateBindingFailFastTest.java
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.ConcurrentModificationException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.PriorityQueue;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.Stack;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Vector;
+import java.util.WeakHashMap;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import static org.testng.Assert.*;
+
+/**
+ * @test
+ * @summary Spliterator last-binding and fail-fast tests
+ * @run testng SpliteratorLateBindingFailFastTest
+ */
+
+@Test(groups = { "serialization-hostile" })
+public class SpliteratorLateBindingFailFastTest {
+
+    private interface Source<T> {
+        Collection<T> asCollection();
+        void update();
+    }
+
+    private static class SpliteratorDataBuilder<T> {
+        final List<Object[]> data;
+
+        final T newValue;
+
+        final List<T> exp;
+
+        final Map<T, T> mExp;
+
+        SpliteratorDataBuilder(List<Object[]> data, T newValue, List<T> exp) {
+            this.data = data;
+            this.newValue = newValue;
+            this.exp = exp;
+            this.mExp = createMap(exp);
+        }
+
+        Map<T, T> createMap(List<T> l) {
+            Map<T, T> m = new LinkedHashMap<>();
+            for (T t : l) {
+                m.put(t, t);
+            }
+            return m;
+        }
+
+        void add(String description, Supplier<Source<?>> s) {
+            description = joiner(description).toString();
+            data.add(new Object[]{description, s});
+        }
+
+        void addCollection(Function<Collection<T>, ? extends Collection<T>> f) {
+            class CollectionSource implements Source<T> {
+                final Collection<T> c = f.apply(exp);
+
+                final Consumer<Collection<T>> updater;
+
+                CollectionSource(Consumer<Collection<T>> updater) {
+                    this.updater = updater;
+                }
+
+                @Override
+                public Collection<T> asCollection() {
+                    return c;
+                }
+
+                @Override
+                public void update() {
+                    updater.accept(c);
+                }
+            }
+
+            String description = "new " + f.apply(Collections.<T>emptyList()).getClass().getName() + ".spliterator() ";
+            add(description + "ADD", () -> new CollectionSource(c -> c.add(newValue)));
+            add(description + "REMOVE", () -> new CollectionSource(c -> c.remove(c.iterator().next())));
+        }
+
+        void addList(Function<Collection<T>, ? extends List<T>> l) {
+            // @@@ If collection is instance of List then add sub-list tests
+            addCollection(l);
+        }
+
+        void addMap(Function<Map<T, T>, ? extends Map<T, T>> mapConstructor) {
+            class MapSource<U> implements Source<U> {
+                final Map<T, T> m = mapConstructor.apply(mExp);
+
+                final Collection<U> c;
+
+                final Consumer<Map<T, T>> updater;
+
+                MapSource(Function<Map<T, T>, Collection<U>> f, Consumer<Map<T, T>> updater) {
+                    this.c = f.apply(m);
+                    this.updater = updater;
+                }
+
+                @Override
+                public Collection<U> asCollection() {
+                    return c;
+                }
+
+                @Override
+                public void update() {
+                    updater.accept(m);
+                }
+            }
+
+            Map<String, Consumer<Map<T, T>>> actions = new HashMap<>();
+            actions.put("ADD", m -> m.put(newValue, newValue));
+            actions.put("REMOVE", m -> m.remove(m.keySet().iterator().next()));
+
+            String description = "new " + mapConstructor.apply(Collections.<T, T>emptyMap()).getClass().getName();
+            for (Map.Entry<String, Consumer<Map<T, T>>> e : actions.entrySet()) {
+                add(description + ".keySet().spliterator() " + e.getKey(),
+                    () -> new MapSource<T>(m -> m.keySet(), e.getValue()));
+                add(description + ".values().spliterator() " + e.getKey(),
+                    () -> new MapSource<T>(m -> m.values(), e.getValue()));
+                add(description + ".entrySet().spliterator() " + e.getKey(),
+                    () -> new MapSource<Map.Entry<T, T>>(m -> m.entrySet(), e.getValue()));
+            }
+        }
+
+        StringBuilder joiner(String description) {
+            return new StringBuilder(description).
+                    append(" {").
+                    append("size=").append(exp.size()).
+                    append("}");
+        }
+    }
+
+    static Object[][] spliteratorDataProvider;
+
+    @DataProvider(name = "Source")
+    public static Object[][] spliteratorDataProvider() {
+        if (spliteratorDataProvider != null) {
+            return spliteratorDataProvider;
+        }
+
+        List<Object[]> data = new ArrayList<>();
+        SpliteratorDataBuilder<Integer> db = new SpliteratorDataBuilder<>(data, 5, Arrays.asList(1, 2, 3, 4));
+
+        // Collections
+
+        db.addList(ArrayList::new);
+
+        db.addList(LinkedList::new);
+
+        db.addList(Vector::new);
+
+
+        db.addCollection(HashSet::new);
+
+        db.addCollection(LinkedHashSet::new);
+
+        db.addCollection(TreeSet::new);
+
+
+        db.addCollection(c -> { Stack<Integer> s = new Stack<>(); s.addAll(c); return s;});
+
+        db.addCollection(PriorityQueue::new);
+
+        // ArrayDeque fails some tests since it's fail-fast support is weaker
+        // than other collections and limited to detecting most, but not all,
+        // removals.  It probably requires it's own test since it is difficult
+        // to abstract out the conditions under which it fails-fast.
+//        db.addCollection(ArrayDeque::new);
+
+        // Maps
+
+        db.addMap(HashMap::new);
+
+        db.addMap(LinkedHashMap::new);
+
+        // This fails when run through jrteg but passes when run though
+        // ant
+//        db.addMap(IdentityHashMap::new);
+
+        db.addMap(WeakHashMap::new);
+
+        // @@@  Descending maps etc
+        db.addMap(TreeMap::new);
+
+        return spliteratorDataProvider = data.toArray(new Object[0][]);
+    }
+
+    @Test(dataProvider = "Source")
+    public <T> void lateBindingTestWithForEach(String description, Supplier<Source<T>> ss) {
+        Source<T> source = ss.get();
+        Collection<T> c = source.asCollection();
+        Spliterator<T> s = c.spliterator();
+
+        source.update();
+
+        Set<T> r = new HashSet<>();
+        s.forEachRemaining(r::add);
+
+        assertEquals(r, new HashSet<>(c));
+    }
+
+    @Test(dataProvider = "Source")
+    public <T> void lateBindingTestWithTryAdvance(String description, Supplier<Source<T>> ss) {
+        Source<T> source = ss.get();
+        Collection<T> c = source.asCollection();
+        Spliterator<T> s = c.spliterator();
+
+        source.update();
+
+        Set<T> r = new HashSet<>();
+        while (s.tryAdvance(r::add)) { }
+
+        assertEquals(r, new HashSet<>(c));
+    }
+
+    @Test(dataProvider = "Source")
+    public <T> void lateBindingTestWithCharacteritics(String description, Supplier<Source<T>> ss) {
+        Source<T> source = ss.get();
+        Collection<T> c = source.asCollection();
+        Spliterator<T> s = c.spliterator();
+        s.characteristics();
+
+        Set<T> r = new HashSet<>();
+        s.forEachRemaining(r::add);
+
+        assertEquals(r, new HashSet<>(c));
+    }
+
+
+    @Test(dataProvider = "Source")
+    public <T> void testFailFastTestWithTryAdvance(String description, Supplier<Source<T>> ss) {
+        {
+            Source<T> source = ss.get();
+            Collection<T> c = source.asCollection();
+            Spliterator<T> s = c.spliterator();
+
+            s.tryAdvance(e -> {
+            });
+            source.update();
+
+            executeAndCatch(() -> s.tryAdvance(e -> { }));
+        }
+
+        {
+            Source<T> source = ss.get();
+            Collection<T> c = source.asCollection();
+            Spliterator<T> s = c.spliterator();
+
+            s.tryAdvance(e -> {
+            });
+            source.update();
+
+            executeAndCatch(() -> s.forEachRemaining(e -> {
+            }));
+        }
+    }
+
+    @Test(dataProvider = "Source")
+    public <T> void testFailFastTestWithForEach(String description, Supplier<Source<T>> ss) {
+        Source<T> source = ss.get();
+        Collection<T> c = source.asCollection();
+        Spliterator<T> s = c.spliterator();
+
+        executeAndCatch(() -> s.forEachRemaining(e -> {
+            source.update();
+        }));
+    }
+
+    @Test(dataProvider = "Source")
+    public <T> void testFailFastTestWithEstimateSize(String description, Supplier<Source<T>> ss) {
+        {
+            Source<T> source = ss.get();
+            Collection<T> c = source.asCollection();
+            Spliterator<T> s = c.spliterator();
+
+            s.estimateSize();
+            source.update();
+
+            executeAndCatch(() -> s.tryAdvance(e -> { }));
+        }
+
+        {
+            Source<T> source = ss.get();
+            Collection<T> c = source.asCollection();
+            Spliterator<T> s = c.spliterator();
+
+            s.estimateSize();
+            source.update();
+
+            executeAndCatch(() -> s.forEachRemaining(e -> {
+            }));
+        }
+    }
+
+    private void executeAndCatch(Runnable r) {
+        executeAndCatch(ConcurrentModificationException.class, r);
+    }
+
+    private void executeAndCatch(Class<? extends Exception> expected, Runnable r) {
+        Exception caught = null;
+        try {
+            r.run();
+        }
+        catch (Exception e) {
+            caught = e;
+        }
+
+        assertNotNull(caught,
+                      String.format("No Exception was thrown, expected an Exception of %s to be thrown",
+                                    expected.getName()));
+        assertTrue(expected.isInstance(caught),
+                   String.format("Exception thrown %s not an instance of %s",
+                                 caught.getClass().getName(), expected.getName()));
+    }
+
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SpliteratorTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SpliteratorTest.java
new file mode 100644
index 0000000..d69c585
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SpliteratorTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Supplier;
+import java.util.Spliterator;
+import java.util.stream.*;
+
+import static org.testng.Assert.*;
+import static org.testng.Assert.assertEquals;
+
+/**
+ * SpliteratorTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class SpliteratorTest {
+
+    @Test(dataProvider = "Spliterator<Integer>", dataProviderClass = StreamTestDataProvider.class )
+    public void testSpliterator(String name, Supplier<Spliterator<Integer>> supplier) {
+        SpliteratorTestHelper.testSpliterator(supplier);
+    }
+
+    @Test(dataProvider = "IntSpliterator", dataProviderClass = IntStreamTestDataProvider.class )
+    public void testIntSpliterator(String name, Supplier<Spliterator.OfInt> supplier) {
+        SpliteratorTestHelper.testIntSpliterator(supplier);
+    }
+
+    @Test(dataProvider = "LongSpliterator", dataProviderClass = LongStreamTestDataProvider.class )
+    public void testLongSpliterator(String name, Supplier<Spliterator.OfLong> supplier) {
+        SpliteratorTestHelper.testLongSpliterator(supplier);
+    }
+
+    @Test(dataProvider = "DoubleSpliterator", dataProviderClass = DoubleStreamTestDataProvider.class )
+    public void testDoubleSpliterator(String name, Supplier<Spliterator.OfDouble> supplier) {
+        SpliteratorTestHelper.testDoubleSpliterator(supplier);
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SpliteratorTraversingAndSplittingTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SpliteratorTraversingAndSplittingTest.java
new file mode 100644
index 0000000..de9d51c
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SpliteratorTraversingAndSplittingTest.java
@@ -0,0 +1,1411 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+/**
+ * @test
+ * @summary Spliterator traversing and splitting tests
+ * @run testng SpliteratorTraversingAndSplittingTest
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.AbstractCollection;
+import java.util.AbstractList;
+import java.util.AbstractSet;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.PriorityQueue;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.Stack;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Vector;
+import java.util.WeakHashMap;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.LinkedTransferQueue;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.function.Consumer;
+import java.util.function.DoubleConsumer;
+import java.util.function.Function;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
+
+import static org.testng.Assert.*;
+import static org.testng.Assert.assertEquals;
+
+@Test(groups = { "serialization-hostile" })
+public class SpliteratorTraversingAndSplittingTest {
+
+    private static List<Integer> SIZES = Arrays.asList(0, 1, 10, 100, 1000);
+
+    private static class SpliteratorDataBuilder<T> {
+        List<Object[]> data;
+
+        List<T> exp;
+
+        Map<T, T> mExp;
+
+        SpliteratorDataBuilder(List<Object[]> data, List<T> exp) {
+            this.data = data;
+            this.exp = exp;
+            this.mExp = createMap(exp);
+        }
+
+        Map<T, T> createMap(List<T> l) {
+            Map<T, T> m = new LinkedHashMap<>();
+            for (T t : l) {
+                m.put(t, t);
+            }
+            return m;
+        }
+
+        void add(String description, Collection<?> expected, Supplier<Spliterator<?>> s) {
+            description = joiner(description).toString();
+            data.add(new Object[]{description, expected, s});
+        }
+
+        void add(String description, Supplier<Spliterator<?>> s) {
+            add(description, exp, s);
+        }
+
+        void addCollection(Function<Collection<T>, ? extends Collection<T>> c) {
+            add("new " + c.apply(Collections.<T>emptyList()).getClass().getName() + ".spliterator()",
+                () -> c.apply(exp).spliterator());
+        }
+
+        void addList(Function<Collection<T>, ? extends List<T>> l) {
+            // @@@ If collection is instance of List then add sub-list tests
+            addCollection(l);
+        }
+
+        void addMap(Function<Map<T, T>, ? extends Map<T, T>> m) {
+            String description = "new " + m.apply(Collections.<T, T>emptyMap()).getClass().getName();
+            add(description + ".keySet().spliterator()", () -> m.apply(mExp).keySet().spliterator());
+            add(description + ".values().spliterator()", () -> m.apply(mExp).values().spliterator());
+            add(description + ".entrySet().spliterator()", mExp.entrySet(), () -> m.apply(mExp).entrySet().spliterator());
+        }
+
+        StringBuilder joiner(String description) {
+            return new StringBuilder(description).
+                    append(" {").
+                    append("size=").append(exp.size()).
+                    append("}");
+        }
+    }
+
+    static Object[][] spliteratorDataProvider;
+
+    @DataProvider(name = "Spliterator<Integer>")
+    public static Object[][] spliteratorDataProvider() {
+        if (spliteratorDataProvider != null) {
+            return spliteratorDataProvider;
+        }
+
+        List<Object[]> data = new ArrayList<>();
+        for (int size : SIZES) {
+            List<Integer> exp = listIntRange(size);
+            SpliteratorDataBuilder<Integer> db = new SpliteratorDataBuilder<>(data, exp);
+
+            // Direct spliterator methods
+
+            db.add("Spliterators.spliterator(Collection, ...)",
+                   () -> Spliterators.spliterator(exp, 0));
+
+            db.add("Spliterators.spliterator(Iterator, ...)",
+                   () -> Spliterators.spliterator(exp.iterator(), exp.size(), 0));
+
+            db.add("Spliterators.spliteratorUnknownSize(Iterator, ...)",
+                   () -> Spliterators.spliteratorUnknownSize(exp.iterator(), 0));
+
+            db.add("Spliterators.spliterator(Spliterators.iteratorFromSpliterator(Spliterator ), ...)",
+                   () -> Spliterators.spliterator(Spliterators.iteratorFromSpliterator(exp.spliterator()), exp.size(), 0));
+
+            db.add("Spliterators.spliterator(T[], ...)",
+                   () -> Spliterators.spliterator(exp.toArray(new Integer[0]), 0));
+
+            db.add("Arrays.spliterator(T[], ...)",
+                   () -> Arrays.spliterator(exp.toArray(new Integer[0])));
+
+            class SpliteratorFromIterator extends Spliterators.AbstractSpliterator<Integer> {
+                Iterator<Integer> it;
+
+                SpliteratorFromIterator(Iterator<Integer> it, long est) {
+                    super(est, Spliterator.SIZED);
+                    this.it = it;
+                }
+
+                @Override
+                public boolean tryAdvance(Consumer<? super Integer> action) {
+                    if (action == null)
+                        throw new NullPointerException();
+                    if (it.hasNext()) {
+                        action.accept(it.next());
+                        return true;
+                    }
+                    else {
+                        return false;
+                    }
+                }
+            }
+            db.add("new Spliterators.AbstractSpliterator()",
+                   () -> new SpliteratorFromIterator(exp.iterator(), exp.size()));
+
+            // Collections
+
+            // default method implementations
+
+            class AbstractCollectionImpl extends AbstractCollection<Integer> {
+                Collection<Integer> c;
+
+                AbstractCollectionImpl(Collection<Integer> c) {
+                    this.c = c;
+                }
+
+                @Override
+                public Iterator<Integer> iterator() {
+                    return c.iterator();
+                }
+
+                @Override
+                public int size() {
+                    return c.size();
+                }
+            }
+            db.addCollection(
+                    c -> new AbstractCollectionImpl(c));
+
+            class AbstractListImpl extends AbstractList<Integer> {
+                List<Integer> l;
+
+                AbstractListImpl(Collection<Integer> c) {
+                    this.l = new ArrayList<>(c);
+                }
+
+                @Override
+                public Integer get(int index) {
+                    return l.get(index);
+                }
+
+                @Override
+                public int size() {
+                    return l.size();
+                }
+            }
+            db.addCollection(
+                    c -> new AbstractListImpl(c));
+
+            class AbstractSetImpl extends AbstractSet<Integer> {
+                Set<Integer> s;
+
+                AbstractSetImpl(Collection<Integer> c) {
+                    this.s = new HashSet<>(c);
+                }
+
+                @Override
+                public Iterator<Integer> iterator() {
+                    return s.iterator();
+                }
+
+                @Override
+                public int size() {
+                    return s.size();
+                }
+            }
+            db.addCollection(
+                    c -> new AbstractSetImpl(c));
+
+            class AbstractSortedSetImpl extends AbstractSet<Integer> implements SortedSet<Integer> {
+                SortedSet<Integer> s;
+
+                AbstractSortedSetImpl(Collection<Integer> c) {
+                    this.s = new TreeSet<>(c);
+                }
+
+                @Override
+                public Iterator<Integer> iterator() {
+                    return s.iterator();
+                }
+
+                @Override
+                public int size() {
+                    return s.size();
+                }
+
+                @Override
+                public Comparator<? super Integer> comparator() {
+                    return s.comparator();
+                }
+
+                @Override
+                public SortedSet<Integer> subSet(Integer fromElement, Integer toElement) {
+                    return s.subSet(fromElement, toElement);
+                }
+
+                @Override
+                public SortedSet<Integer> headSet(Integer toElement) {
+                    return s.headSet(toElement);
+                }
+
+                @Override
+                public SortedSet<Integer> tailSet(Integer fromElement) {
+                    return s.tailSet(fromElement);
+                }
+
+                @Override
+                public Integer first() {
+                    return s.first();
+                }
+
+                @Override
+                public Integer last() {
+                    return s.last();
+                }
+
+                @Override
+                public Spliterator<Integer> spliterator() {
+                    return SortedSet.super.spliterator();
+                }
+            }
+            db.addCollection(
+                    c -> new AbstractSortedSetImpl(c));
+
+            //
+
+            db.add("Arrays.asList().spliterator()",
+                   () -> Spliterators.spliterator(Arrays.asList(exp.toArray(new Integer[0])), 0));
+
+            db.addList(ArrayList::new);
+
+            db.addList(LinkedList::new);
+
+            db.addList(Vector::new);
+
+
+            db.addCollection(HashSet::new);
+
+            db.addCollection(LinkedHashSet::new);
+
+            db.addCollection(TreeSet::new);
+
+
+            db.addCollection(c -> { Stack<Integer> s = new Stack<>(); s.addAll(c); return s;});
+
+            db.addCollection(PriorityQueue::new);
+
+            db.addCollection(ArrayDeque::new);
+
+
+            db.addCollection(ConcurrentSkipListSet::new);
+
+            if (size > 0) {
+                db.addCollection(c -> {
+                    ArrayBlockingQueue<Integer> abq = new ArrayBlockingQueue<>(size);
+                    abq.addAll(c);
+                    return abq;
+                });
+            }
+
+            db.addCollection(PriorityBlockingQueue::new);
+
+            db.addCollection(LinkedBlockingQueue::new);
+
+            db.addCollection(LinkedTransferQueue::new);
+
+            db.addCollection(ConcurrentLinkedQueue::new);
+
+            db.addCollection(LinkedBlockingDeque::new);
+
+            db.addCollection(CopyOnWriteArrayList::new);
+
+            db.addCollection(CopyOnWriteArraySet::new);
+
+            if (size == 1) {
+                db.addCollection(c -> Collections.singleton(exp.get(0)));
+                db.addCollection(c -> Collections.singletonList(exp.get(0)));
+            }
+
+            // Collections.synchronized/unmodifiable/checked wrappers
+            db.addCollection(Collections::unmodifiableCollection);
+            db.addCollection(c -> Collections.unmodifiableSet(new HashSet<>(c)));
+            db.addCollection(c -> Collections.unmodifiableSortedSet(new TreeSet<>(c)));
+            db.addList(c -> Collections.unmodifiableList(new ArrayList<>(c)));
+            db.addMap(Collections::unmodifiableMap);
+            db.addMap(m -> Collections.unmodifiableSortedMap(new TreeMap<>(m)));
+
+            db.addCollection(Collections::synchronizedCollection);
+            db.addCollection(c -> Collections.synchronizedSet(new HashSet<>(c)));
+            db.addCollection(c -> Collections.synchronizedSortedSet(new TreeSet<>(c)));
+            db.addList(c -> Collections.synchronizedList(new ArrayList<>(c)));
+            db.addMap(Collections::synchronizedMap);
+            db.addMap(m -> Collections.synchronizedSortedMap(new TreeMap<>(m)));
+
+            db.addCollection(c -> Collections.checkedCollection(c, Integer.class));
+            db.addCollection(c -> Collections.checkedQueue(new ArrayDeque<>(c), Integer.class));
+            db.addCollection(c -> Collections.checkedSet(new HashSet<>(c), Integer.class));
+            db.addCollection(c -> Collections.checkedSortedSet(new TreeSet<>(c), Integer.class));
+            db.addList(c -> Collections.checkedList(new ArrayList<>(c), Integer.class));
+            db.addMap(c -> Collections.checkedMap(c, Integer.class, Integer.class));
+            db.addMap(m -> Collections.checkedSortedMap(new TreeMap<>(m), Integer.class, Integer.class));
+
+            // Maps
+
+            db.addMap(HashMap::new);
+
+            db.addMap(LinkedHashMap::new);
+
+            db.addMap(IdentityHashMap::new);
+
+            db.addMap(WeakHashMap::new);
+
+            // @@@  Descending maps etc
+            db.addMap(TreeMap::new);
+
+            db.addMap(ConcurrentHashMap::new);
+
+            db.addMap(ConcurrentSkipListMap::new);
+        }
+
+        return spliteratorDataProvider = data.toArray(new Object[0][]);
+    }
+
+    private static List<Integer> listIntRange(int upTo) {
+        List<Integer> exp = new ArrayList<>();
+        for (int i = 0; i < upTo; i++)
+            exp.add(i);
+        return Collections.unmodifiableList(exp);
+    }
+
+    @Test(dataProvider = "Spliterator<Integer>")
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public void testNullPointerException(String description, Collection exp, Supplier<Spliterator> s) {
+        executeAndCatch(NullPointerException.class, () -> s.get().forEachRemaining(null));
+        executeAndCatch(NullPointerException.class, () -> s.get().tryAdvance(null));
+    }
+
+    @Test(dataProvider = "Spliterator<Integer>")
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public void testForEach(String description, Collection exp, Supplier<Spliterator> s) {
+        testForEach(exp, s, (Consumer<Object> b) -> b);
+    }
+
+    @Test(dataProvider = "Spliterator<Integer>")
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public void testTryAdvance(String description, Collection exp, Supplier<Spliterator> s) {
+        testTryAdvance(exp, s, (Consumer<Object> b) -> b);
+    }
+
+    @Test(dataProvider = "Spliterator<Integer>")
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public void testMixedTryAdvanceForEach(String description, Collection exp, Supplier<Spliterator> s) {
+        testMixedTryAdvanceForEach(exp, s, (Consumer<Object> b) -> b);
+    }
+
+    @Test(dataProvider = "Spliterator<Integer>")
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public void testMixedTraverseAndSplit(String description, Collection exp, Supplier<Spliterator> s) {
+        testMixedTraverseAndSplit(exp, s, (Consumer<Object> b) -> b);
+    }
+
+    @Test(dataProvider = "Spliterator<Integer>")
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public void testSplitAfterFullTraversal(String description, Collection exp, Supplier<Spliterator> s) {
+        testSplitAfterFullTraversal(s, (Consumer<Object> b) -> b);
+    }
+
+    @Test(dataProvider = "Spliterator<Integer>")
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public void testSplitOnce(String description, Collection exp, Supplier<Spliterator> s) {
+        testSplitOnce(exp, s, (Consumer<Object> b) -> b);
+    }
+
+    @Test(dataProvider = "Spliterator<Integer>")
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public void testSplitSixDeep(String description, Collection exp, Supplier<Spliterator> s) {
+        testSplitSixDeep(exp, s, (Consumer<Object> b) -> b);
+    }
+
+    @Test(dataProvider = "Spliterator<Integer>")
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public void testSplitUntilNull(String description, Collection exp, Supplier<Spliterator> s) {
+        testSplitUntilNull(exp, s, (Consumer<Object> b) -> b);
+    }
+
+    //
+
+    private static class SpliteratorOfIntDataBuilder {
+        List<Object[]> data;
+
+        List<Integer> exp;
+
+        SpliteratorOfIntDataBuilder(List<Object[]> data, List<Integer> exp) {
+            this.data = data;
+            this.exp = exp;
+        }
+
+        void add(String description, List<Integer> expected, Supplier<Spliterator.OfInt> s) {
+            description = joiner(description).toString();
+            data.add(new Object[]{description, expected, s});
+        }
+
+        void add(String description, Supplier<Spliterator.OfInt> s) {
+            add(description, exp, s);
+        }
+
+        StringBuilder joiner(String description) {
+            return new StringBuilder(description).
+                    append(" {").
+                    append("size=").append(exp.size()).
+                    append("}");
+        }
+    }
+
+    static Object[][] spliteratorOfIntDataProvider;
+
+    @DataProvider(name = "Spliterator.OfInt")
+    public static Object[][] spliteratorOfIntDataProvider() {
+        if (spliteratorOfIntDataProvider != null) {
+            return spliteratorOfIntDataProvider;
+        }
+
+        List<Object[]> data = new ArrayList<>();
+        for (int size : SIZES) {
+            int exp[] = arrayIntRange(size);
+            SpliteratorOfIntDataBuilder db = new SpliteratorOfIntDataBuilder(data, listIntRange(size));
+
+            db.add("Spliterators.spliterator(int[], ...)",
+                   () -> Spliterators.spliterator(exp, 0));
+
+            db.add("Arrays.spliterator(int[], ...)",
+                   () -> Arrays.spliterator(exp));
+
+            db.add("Spliterators.spliterator(PrimitiveIterator.OfInt, ...)",
+                   () -> Spliterators.spliterator(Spliterators.iteratorFromSpliterator(Arrays.spliterator(exp)), exp.length, 0));
+
+            db.add("Spliterators.spliteratorUnknownSize(PrimitiveIterator.OfInt, ...)",
+                   () -> Spliterators.spliteratorUnknownSize(Spliterators.iteratorFromSpliterator(Arrays.spliterator(exp)), 0));
+
+            class IntSpliteratorFromArray extends Spliterators.AbstractIntSpliterator {
+                int[] a;
+                int index = 0;
+
+                IntSpliteratorFromArray(int[] a) {
+                    super(a.length, Spliterator.SIZED);
+                    this.a = a;
+                }
+
+                @Override
+                public boolean tryAdvance(IntConsumer action) {
+                    if (action == null)
+                        throw new NullPointerException();
+                    if (index < a.length) {
+                        action.accept(a[index++]);
+                        return true;
+                    }
+                    else {
+                        return false;
+                    }
+                }
+            }
+            db.add("new Spliterators.AbstractIntAdvancingSpliterator()",
+                   () -> new IntSpliteratorFromArray(exp));
+        }
+
+        return spliteratorOfIntDataProvider = data.toArray(new Object[0][]);
+    }
+
+    private static int[] arrayIntRange(int upTo) {
+        int[] exp = new int[upTo];
+        for (int i = 0; i < upTo; i++)
+            exp[i] = i;
+        return exp;
+    }
+
+    private static UnaryOperator<Consumer<Integer>> intBoxingConsumer() {
+        class BoxingAdapter implements Consumer<Integer>, IntConsumer {
+            private final Consumer<Integer> b;
+
+            BoxingAdapter(Consumer<Integer> b) {
+                this.b = b;
+            }
+
+            @Override
+            public void accept(Integer value) {
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public void accept(int value) {
+                b.accept(value);
+            }
+        }
+
+        return b -> new BoxingAdapter(b);
+    }
+
+    @Test(dataProvider = "Spliterator.OfInt")
+    public void testIntNullPointerException(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+        executeAndCatch(NullPointerException.class, () -> s.get().forEachRemaining((IntConsumer) null));
+        executeAndCatch(NullPointerException.class, () -> s.get().tryAdvance((IntConsumer) null));
+    }
+
+    @Test(dataProvider = "Spliterator.OfInt")
+    public void testIntForEach(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+        testForEach(exp, s, intBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfInt")
+    public void testIntTryAdvance(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+        testTryAdvance(exp, s, intBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfInt")
+    public void testIntMixedTryAdvanceForEach(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+        testMixedTryAdvanceForEach(exp, s, intBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfInt")
+    public void testIntMixedTraverseAndSplit(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+        testMixedTraverseAndSplit(exp, s, intBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfInt")
+    public void testIntSplitAfterFullTraversal(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+        testSplitAfterFullTraversal(s, intBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfInt")
+    public void testIntSplitOnce(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+        testSplitOnce(exp, s, intBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfInt")
+    public void testIntSplitSixDeep(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+        testSplitSixDeep(exp, s, intBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfInt")
+    public void testIntSplitUntilNull(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+        testSplitUntilNull(exp, s, intBoxingConsumer());
+    }
+
+    //
+
+    private static class SpliteratorOfLongDataBuilder {
+        List<Object[]> data;
+
+        List<Long> exp;
+
+        SpliteratorOfLongDataBuilder(List<Object[]> data, List<Long> exp) {
+            this.data = data;
+            this.exp = exp;
+        }
+
+        void add(String description, List<Long> expected, Supplier<Spliterator.OfLong> s) {
+            description = joiner(description).toString();
+            data.add(new Object[]{description, expected, s});
+        }
+
+        void add(String description, Supplier<Spliterator.OfLong> s) {
+            add(description, exp, s);
+        }
+
+        StringBuilder joiner(String description) {
+            return new StringBuilder(description).
+                    append(" {").
+                    append("size=").append(exp.size()).
+                    append("}");
+        }
+    }
+
+    static Object[][] spliteratorOfLongDataProvider;
+
+    @DataProvider(name = "Spliterator.OfLong")
+    public static Object[][] spliteratorOfLongDataProvider() {
+        if (spliteratorOfLongDataProvider != null) {
+            return spliteratorOfLongDataProvider;
+        }
+
+        List<Object[]> data = new ArrayList<>();
+        for (int size : SIZES) {
+            long exp[] = arrayLongRange(size);
+            SpliteratorOfLongDataBuilder db = new SpliteratorOfLongDataBuilder(data, listLongRange(size));
+
+            db.add("Spliterators.spliterator(long[], ...)",
+                   () -> Spliterators.spliterator(exp, 0));
+
+            db.add("Arrays.spliterator(long[], ...)",
+                   () -> Arrays.spliterator(exp));
+
+            db.add("Spliterators.spliterator(PrimitiveIterator.OfLong, ...)",
+                   () -> Spliterators.spliterator(Spliterators.iteratorFromSpliterator(Arrays.spliterator(exp)), exp.length, 0));
+
+            db.add("Spliterators.spliteratorUnknownSize(PrimitiveIterator.OfLong, ...)",
+                   () -> Spliterators.spliteratorUnknownSize(Spliterators.iteratorFromSpliterator(Arrays.spliterator(exp)), 0));
+
+            class LongSpliteratorFromArray extends Spliterators.AbstractLongSpliterator {
+                long[] a;
+                int index = 0;
+
+                LongSpliteratorFromArray(long[] a) {
+                    super(a.length, Spliterator.SIZED);
+                    this.a = a;
+                }
+
+                @Override
+                public boolean tryAdvance(LongConsumer action) {
+                    if (action == null)
+                        throw new NullPointerException();
+                    if (index < a.length) {
+                        action.accept(a[index++]);
+                        return true;
+                    }
+                    else {
+                        return false;
+                    }
+                }
+            }
+            db.add("new Spliterators.AbstractLongAdvancingSpliterator()",
+                   () -> new LongSpliteratorFromArray(exp));
+        }
+
+        return spliteratorOfLongDataProvider = data.toArray(new Object[0][]);
+    }
+
+    private static List<Long> listLongRange(int upTo) {
+        List<Long> exp = new ArrayList<>();
+        for (long i = 0; i < upTo; i++)
+            exp.add(i);
+        return Collections.unmodifiableList(exp);
+    }
+
+    private static long[] arrayLongRange(int upTo) {
+        long[] exp = new long[upTo];
+        for (int i = 0; i < upTo; i++)
+            exp[i] = i;
+        return exp;
+    }
+
+    private static UnaryOperator<Consumer<Long>> longBoxingConsumer() {
+        class BoxingAdapter implements Consumer<Long>, LongConsumer {
+            private final Consumer<Long> b;
+
+            BoxingAdapter(Consumer<Long> b) {
+                this.b = b;
+            }
+
+            @Override
+            public void accept(Long value) {
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public void accept(long value) {
+                b.accept(value);
+            }
+        }
+
+        return b -> new BoxingAdapter(b);
+    }
+
+    @Test(dataProvider = "Spliterator.OfLong")
+    public void testLongNullPointerException(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
+        executeAndCatch(NullPointerException.class, () -> s.get().forEachRemaining((LongConsumer) null));
+        executeAndCatch(NullPointerException.class, () -> s.get().tryAdvance((LongConsumer) null));
+    }
+
+    @Test(dataProvider = "Spliterator.OfLong")
+    public void testLongForEach(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
+        testForEach(exp, s, longBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfLong")
+    public void testLongTryAdvance(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
+        testTryAdvance(exp, s, longBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfLong")
+    public void testLongMixedTryAdvanceForEach(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
+        testMixedTryAdvanceForEach(exp, s, longBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfLong")
+    public void testLongMixedTraverseAndSplit(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
+        testMixedTraverseAndSplit(exp, s, longBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfLong")
+    public void testLongSplitAfterFullTraversal(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
+        testSplitAfterFullTraversal(s, longBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfLong")
+    public void testLongSplitOnce(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
+        testSplitOnce(exp, s, longBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfLong")
+    public void testLongSplitSixDeep(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
+        testSplitSixDeep(exp, s, longBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfLong")
+    public void testLongSplitUntilNull(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
+        testSplitUntilNull(exp, s, longBoxingConsumer());
+    }
+
+    //
+
+    private static class SpliteratorOfDoubleDataBuilder {
+        List<Object[]> data;
+
+        List<Double> exp;
+
+        SpliteratorOfDoubleDataBuilder(List<Object[]> data, List<Double> exp) {
+            this.data = data;
+            this.exp = exp;
+        }
+
+        void add(String description, List<Double> expected, Supplier<Spliterator.OfDouble> s) {
+            description = joiner(description).toString();
+            data.add(new Object[]{description, expected, s});
+        }
+
+        void add(String description, Supplier<Spliterator.OfDouble> s) {
+            add(description, exp, s);
+        }
+
+        StringBuilder joiner(String description) {
+            return new StringBuilder(description).
+                    append(" {").
+                    append("size=").append(exp.size()).
+                    append("}");
+        }
+    }
+
+    static Object[][] spliteratorOfDoubleDataProvider;
+
+    @DataProvider(name = "Spliterator.OfDouble")
+    public static Object[][] spliteratorOfDoubleDataProvider() {
+        if (spliteratorOfDoubleDataProvider != null) {
+            return spliteratorOfDoubleDataProvider;
+        }
+
+        List<Object[]> data = new ArrayList<>();
+        for (int size : SIZES) {
+            double exp[] = arrayDoubleRange(size);
+            SpliteratorOfDoubleDataBuilder db = new SpliteratorOfDoubleDataBuilder(data, listDoubleRange(size));
+
+            db.add("Spliterators.spliterator(double[], ...)",
+                   () -> Spliterators.spliterator(exp, 0));
+
+            db.add("Arrays.spliterator(double[], ...)",
+                   () -> Arrays.spliterator(exp));
+
+            db.add("Spliterators.spliterator(PrimitiveIterator.OfDouble, ...)",
+                   () -> Spliterators.spliterator(Spliterators.iteratorFromSpliterator(Arrays.spliterator(exp)), exp.length, 0));
+
+            db.add("Spliterators.spliteratorUnknownSize(PrimitiveIterator.OfDouble, ...)",
+                   () -> Spliterators.spliteratorUnknownSize(Spliterators.iteratorFromSpliterator(Arrays.spliterator(exp)), 0));
+
+            class DoubleSpliteratorFromArray extends Spliterators.AbstractDoubleSpliterator {
+                double[] a;
+                int index = 0;
+
+                DoubleSpliteratorFromArray(double[] a) {
+                    super(a.length, Spliterator.SIZED);
+                    this.a = a;
+                }
+
+                @Override
+                public boolean tryAdvance(DoubleConsumer action) {
+                    if (action == null)
+                        throw new NullPointerException();
+                    if (index < a.length) {
+                        action.accept(a[index++]);
+                        return true;
+                    }
+                    else {
+                        return false;
+                    }
+                }
+            }
+            db.add("new Spliterators.AbstractDoubleAdvancingSpliterator()",
+                   () -> new DoubleSpliteratorFromArray(exp));
+        }
+
+        return spliteratorOfDoubleDataProvider = data.toArray(new Object[0][]);
+    }
+
+    private static List<Double> listDoubleRange(int upTo) {
+        List<Double> exp = new ArrayList<>();
+        for (double i = 0; i < upTo; i++)
+            exp.add(i);
+        return Collections.unmodifiableList(exp);
+    }
+
+    private static double[] arrayDoubleRange(int upTo) {
+        double[] exp = new double[upTo];
+        for (int i = 0; i < upTo; i++)
+            exp[i] = i;
+        return exp;
+    }
+
+    private static UnaryOperator<Consumer<Double>> doubleBoxingConsumer() {
+        class BoxingAdapter implements Consumer<Double>, DoubleConsumer {
+            private final Consumer<Double> b;
+
+            BoxingAdapter(Consumer<Double> b) {
+                this.b = b;
+            }
+
+            @Override
+            public void accept(Double value) {
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public void accept(double value) {
+                b.accept(value);
+            }
+        }
+
+        return b -> new BoxingAdapter(b);
+    }
+
+    @Test(dataProvider = "Spliterator.OfDouble")
+    public void testDoubleNullPointerException(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
+        executeAndCatch(NullPointerException.class, () -> s.get().forEachRemaining((DoubleConsumer) null));
+        executeAndCatch(NullPointerException.class, () -> s.get().tryAdvance((DoubleConsumer) null));
+    }
+
+    @Test(dataProvider = "Spliterator.OfDouble")
+    public void testDoubleForEach(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
+        testForEach(exp, s, doubleBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfDouble")
+    public void testDoubleTryAdvance(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
+        testTryAdvance(exp, s, doubleBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfDouble")
+    public void testDoubleMixedTryAdvanceForEach(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
+        testMixedTryAdvanceForEach(exp, s, doubleBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfDouble")
+    public void testDoubleMixedTraverseAndSplit(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
+        testMixedTraverseAndSplit(exp, s, doubleBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfDouble")
+    public void testDoubleSplitAfterFullTraversal(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
+        testSplitAfterFullTraversal(s, doubleBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfDouble")
+    public void testDoubleSplitOnce(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
+        testSplitOnce(exp, s, doubleBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfDouble")
+    public void testDoubleSplitSixDeep(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
+        testSplitSixDeep(exp, s, doubleBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfDouble")
+    public void testDoubleSplitUntilNull(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
+        testSplitUntilNull(exp, s, doubleBoxingConsumer());
+    }
+
+    //
+
+    private static <T, S extends Spliterator<T>> void testForEach(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter) {
+        S spliterator = supplier.get();
+        long sizeIfKnown = spliterator.getExactSizeIfKnown();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        ArrayList<T> fromForEach = new ArrayList<>();
+        spliterator = supplier.get();
+        Consumer<T> addToFromForEach = boxingAdapter.apply(fromForEach::add);
+        spliterator.forEachRemaining(addToFromForEach);
+
+        // Assert that forEach now produces no elements
+        spliterator.forEachRemaining(boxingAdapter.apply(
+                e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
+        // Assert that tryAdvance now produce no elements
+        spliterator.tryAdvance(boxingAdapter.apply(
+                e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
+
+        // assert that size, tryAdvance, and forEach are consistent
+        if (sizeIfKnown >= 0) {
+            assertEquals(sizeIfKnown, exp.size());
+        }
+        assertEquals(fromForEach.size(), exp.size());
+
+        assertContents(fromForEach, exp, isOrdered);
+    }
+
+    private static <T, S extends Spliterator<T>> void testTryAdvance(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter) {
+        S spliterator = supplier.get();
+        long sizeIfKnown = spliterator.getExactSizeIfKnown();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        spliterator = supplier.get();
+        ArrayList<T> fromTryAdvance = new ArrayList<>();
+        Consumer<T> addToFromTryAdvance = boxingAdapter.apply(fromTryAdvance::add);
+        while (spliterator.tryAdvance(addToFromTryAdvance)) { }
+
+        // Assert that forEach now produces no elements
+        spliterator.forEachRemaining(boxingAdapter.apply(
+                e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
+        // Assert that tryAdvance now produce no elements
+        spliterator.tryAdvance(boxingAdapter.apply(
+                e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
+
+        // assert that size, tryAdvance, and forEach are consistent
+        if (sizeIfKnown >= 0) {
+            assertEquals(sizeIfKnown, exp.size());
+        }
+        assertEquals(fromTryAdvance.size(), exp.size());
+
+        assertContents(fromTryAdvance, exp, isOrdered);
+    }
+
+    private static <T, S extends Spliterator<T>> void testMixedTryAdvanceForEach(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter) {
+        S spliterator = supplier.get();
+        long sizeIfKnown = spliterator.getExactSizeIfKnown();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        // tryAdvance first few elements, then forEach rest
+        ArrayList<T> dest = new ArrayList<>();
+        spliterator = supplier.get();
+        Consumer<T> addToDest = boxingAdapter.apply(dest::add);
+        for (int i = 0; i < 10 && spliterator.tryAdvance(addToDest); i++) { }
+        spliterator.forEachRemaining(addToDest);
+
+        // Assert that forEach now produces no elements
+        spliterator.forEachRemaining(boxingAdapter.apply(
+                e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
+        // Assert that tryAdvance now produce no elements
+        spliterator.tryAdvance(boxingAdapter.apply(
+                e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
+
+        if (sizeIfKnown >= 0) {
+            assertEquals(sizeIfKnown, dest.size());
+        }
+        assertEquals(dest.size(), exp.size());
+
+        if (isOrdered) {
+            assertEquals(dest, exp);
+        }
+        else {
+            assertContentsUnordered(dest, exp);
+        }
+    }
+
+    private static <T, S extends Spliterator<T>> void testMixedTraverseAndSplit(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter) {
+        S spliterator = supplier.get();
+        long sizeIfKnown = spliterator.getExactSizeIfKnown();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        ArrayList<T> dest = new ArrayList<>();
+        spliterator = supplier.get();
+        Consumer<T> b = boxingAdapter.apply(dest::add);
+
+        Spliterator<T> spl1, spl2, spl3;
+        spliterator.tryAdvance(b);
+        spl2 = spliterator.trySplit();
+        if (spl2 != null) {
+            spl2.tryAdvance(b);
+            spl1 = spl2.trySplit();
+            if (spl1 != null) {
+                spl1.tryAdvance(b);
+                spl1.forEachRemaining(b);
+            }
+            spl2.tryAdvance(b);
+            spl2.forEachRemaining(b);
+        }
+        spliterator.tryAdvance(b);
+        spl3 = spliterator.trySplit();
+        if (spl3 != null) {
+            spl3.tryAdvance(b);
+            spl3.forEachRemaining(b);
+        }
+        spliterator.tryAdvance(b);
+        spliterator.forEachRemaining(b);
+
+        if (sizeIfKnown >= 0) {
+            assertEquals(sizeIfKnown, dest.size());
+        }
+        assertEquals(dest.size(), exp.size());
+
+        if (isOrdered) {
+            assertEquals(dest, exp);
+        }
+        else {
+            assertContentsUnordered(dest, exp);
+        }
+    }
+
+    private static <T, S extends Spliterator<T>> void testSplitAfterFullTraversal(
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter) {
+        // Full traversal using tryAdvance
+        Spliterator<T> spliterator = supplier.get();
+        while (spliterator.tryAdvance(boxingAdapter.apply(e -> { }))) { }
+        Spliterator<T> split = spliterator.trySplit();
+        assertNull(split);
+
+        // Full traversal using forEach
+        spliterator = supplier.get();
+        spliterator.forEachRemaining(boxingAdapter.apply(e -> {
+        }));
+        split = spliterator.trySplit();
+        assertNull(split);
+
+        // Full traversal using tryAdvance then forEach
+        spliterator = supplier.get();
+        spliterator.tryAdvance(boxingAdapter.apply(e -> { }));
+        spliterator.forEachRemaining(boxingAdapter.apply(e -> {
+        }));
+        split = spliterator.trySplit();
+        assertNull(split);
+    }
+
+    private static <T, S extends Spliterator<T>> void testSplitOnce(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter) {
+        S spliterator = supplier.get();
+        long sizeIfKnown = spliterator.getExactSizeIfKnown();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        ArrayList<T> fromSplit = new ArrayList<>();
+        Spliterator<T> s1 = supplier.get();
+        Spliterator<T> s2 = s1.trySplit();
+        long s1Size = s1.getExactSizeIfKnown();
+        long s2Size = (s2 != null) ? s2.getExactSizeIfKnown() : 0;
+        Consumer<T> addToFromSplit = boxingAdapter.apply(fromSplit::add);
+        if (s2 != null)
+            s2.forEachRemaining(addToFromSplit);
+        s1.forEachRemaining(addToFromSplit);
+
+        if (sizeIfKnown >= 0) {
+            assertEquals(sizeIfKnown, fromSplit.size());
+            if (s1Size >= 0 && s2Size >= 0)
+                assertEquals(sizeIfKnown, s1Size + s2Size);
+        }
+        assertContents(fromSplit, exp, isOrdered);
+    }
+
+    private static <T, S extends Spliterator<T>> void testSplitSixDeep(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter) {
+        S spliterator = supplier.get();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        for (int depth=0; depth < 6; depth++) {
+            List<T> dest = new ArrayList<>();
+            spliterator = supplier.get();
+
+            assertSpliterator(spliterator);
+
+            // verify splitting with forEach
+            visit(depth, 0, dest, spliterator, boxingAdapter, spliterator.characteristics(), false);
+            assertContents(dest, exp, isOrdered);
+
+            // verify splitting with tryAdvance
+            dest.clear();
+            spliterator = supplier.get();
+            visit(depth, 0, dest, spliterator, boxingAdapter, spliterator.characteristics(), true);
+            assertContents(dest, exp, isOrdered);
+        }
+    }
+
+    private static <T, S extends Spliterator<T>>
+    void visit(int depth, int curLevel,
+               List<T> dest, S spliterator, UnaryOperator<Consumer<T>> boxingAdapter,
+               int rootCharacteristics, boolean useTryAdvance) {
+        if (curLevel < depth) {
+            long beforeSize = spliterator.getExactSizeIfKnown();
+            Spliterator<T> split = spliterator.trySplit();
+            if (split != null) {
+                assertSpliterator(split, rootCharacteristics);
+                assertSpliterator(spliterator, rootCharacteristics);
+
+                if ((rootCharacteristics & Spliterator.SUBSIZED) != 0 &&
+                    (rootCharacteristics & Spliterator.SIZED) != 0) {
+                    assertEquals(beforeSize, split.estimateSize() + spliterator.estimateSize());
+                }
+                visit(depth, curLevel + 1, dest, split, boxingAdapter, rootCharacteristics, useTryAdvance);
+            }
+            visit(depth, curLevel + 1, dest, spliterator, boxingAdapter, rootCharacteristics, useTryAdvance);
+        }
+        else {
+            long sizeIfKnown = spliterator.getExactSizeIfKnown();
+            if (useTryAdvance) {
+                Consumer<T> addToDest = boxingAdapter.apply(dest::add);
+                int count = 0;
+                while (spliterator.tryAdvance(addToDest)) {
+                    ++count;
+                }
+
+                if (sizeIfKnown >= 0)
+                    assertEquals(sizeIfKnown, count);
+
+                // Assert that forEach now produces no elements
+                spliterator.forEachRemaining(boxingAdapter.apply(
+                        e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
+
+                Spliterator<T> split = spliterator.trySplit();
+                assertNull(split);
+            }
+            else {
+                List<T> leafDest = new ArrayList<>();
+                Consumer<T> addToLeafDest = boxingAdapter.apply(leafDest::add);
+                spliterator.forEachRemaining(addToLeafDest);
+
+                if (sizeIfKnown >= 0)
+                    assertEquals(sizeIfKnown, leafDest.size());
+
+                // Assert that forEach now produces no elements
+                spliterator.tryAdvance(boxingAdapter.apply(
+                        e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
+
+                Spliterator<T> split = spliterator.trySplit();
+                assertNull(split);
+
+                dest.addAll(leafDest);
+            }
+        }
+    }
+
+    private static <T, S extends Spliterator<T>> void testSplitUntilNull(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter) {
+        Spliterator<T> s = supplier.get();
+        boolean isOrdered = s.hasCharacteristics(Spliterator.ORDERED);
+        assertSpliterator(s);
+
+        List<T> splits = new ArrayList<>();
+        Consumer<T> c = boxingAdapter.apply(splits::add);
+
+        testSplitUntilNull(new SplitNode<T>(c, s));
+        assertContents(splits, exp, isOrdered);
+    }
+
+    private static class SplitNode<T> {
+        // Constant for every node
+        final Consumer<T> c;
+        final int rootCharacteristics;
+
+        final Spliterator<T> s;
+
+        SplitNode(Consumer<T> c, Spliterator<T> s) {
+            this(c, s.characteristics(), s);
+        }
+
+        private SplitNode(Consumer<T> c, int rootCharacteristics, Spliterator<T> s) {
+            this.c = c;
+            this.rootCharacteristics = rootCharacteristics;
+            this.s = s;
+        }
+
+        SplitNode<T> fromSplit(Spliterator<T> split) {
+            return new SplitNode<>(c, rootCharacteristics, split);
+        }
+    }
+
+    /**
+     * Set the maximum stack capacity to 0.25MB. This should be more than enough to detect a bad spliterator
+     * while not unduly disrupting test infrastructure given the test data sizes that are used are small.
+     * Note that j.u.c.ForkJoinPool sets the max queue size to 64M (1 << 26).
+     */
+    private static final int MAXIMUM_STACK_CAPACITY = 1 << 18; // 0.25MB
+
+    private static <T> void testSplitUntilNull(SplitNode<T> e) {
+        // Use an explicit stack to avoid a StackOverflowException when testing a Spliterator
+        // that when repeatedly split produces a right-balanced (and maybe degenerate) tree, or
+        // for a spliterator that is badly behaved.
+        Deque<SplitNode<T>> stack = new ArrayDeque<>();
+        stack.push(e);
+
+        int iteration = 0;
+        while (!stack.isEmpty()) {
+            assertTrue(iteration++ < MAXIMUM_STACK_CAPACITY, "Exceeded maximum stack modification count of 1 << 18");
+
+            e = stack.pop();
+            Spliterator<T> parentAndRightSplit = e.s;
+
+            long parentEstimateSize = parentAndRightSplit.estimateSize();
+            assertTrue(parentEstimateSize >= 0,
+                       String.format("Split size estimate %d < 0", parentEstimateSize));
+
+            long parentSize = parentAndRightSplit.getExactSizeIfKnown();
+            Spliterator<T> leftSplit = parentAndRightSplit.trySplit();
+            if (leftSplit == null) {
+                parentAndRightSplit.forEachRemaining(e.c);
+                continue;
+            }
+
+            assertSpliterator(leftSplit, e.rootCharacteristics);
+            assertSpliterator(parentAndRightSplit, e.rootCharacteristics);
+
+            if (parentEstimateSize != Long.MAX_VALUE && leftSplit.estimateSize() > 0 && parentAndRightSplit.estimateSize() > 0) {
+                assertTrue(leftSplit.estimateSize() < parentEstimateSize,
+                           String.format("Left split size estimate %d >= parent split size estimate %d",
+                                         leftSplit.estimateSize(), parentEstimateSize));
+                assertTrue(parentAndRightSplit.estimateSize() < parentEstimateSize,
+                           String.format("Right split size estimate %d >= parent split size estimate %d",
+                                         leftSplit.estimateSize(), parentEstimateSize));
+            }
+            else {
+                assertTrue(leftSplit.estimateSize() <= parentEstimateSize,
+                           String.format("Left split size estimate %d > parent split size estimate %d",
+                                         leftSplit.estimateSize(), parentEstimateSize));
+                assertTrue(parentAndRightSplit.estimateSize() <= parentEstimateSize,
+                           String.format("Right split size estimate %d > parent split size estimate %d",
+                                         leftSplit.estimateSize(), parentEstimateSize));
+            }
+
+            long leftSize = leftSplit.getExactSizeIfKnown();
+            long rightSize = parentAndRightSplit.getExactSizeIfKnown();
+            if (parentSize >= 0 && leftSize >= 0 && rightSize >= 0)
+                assertEquals(parentSize, leftSize + rightSize,
+                             String.format("exact left split size %d + exact right split size %d != parent exact split size %d",
+                                           leftSize, rightSize, parentSize));
+
+            // Add right side to stack first so left side is popped off first
+            stack.push(e.fromSplit(parentAndRightSplit));
+            stack.push(e.fromSplit(leftSplit));
+        }
+    }
+
+    private static void assertSpliterator(Spliterator<?> s, int rootCharacteristics) {
+        if ((rootCharacteristics & Spliterator.SUBSIZED) != 0) {
+            assertTrue(s.hasCharacteristics(Spliterator.SUBSIZED),
+                       "Child split is not SUBSIZED when root split is SUBSIZED");
+        }
+        assertSpliterator(s);
+    }
+
+    private static void assertSpliterator(Spliterator<?> s) {
+        if (s.hasCharacteristics(Spliterator.SUBSIZED)) {
+            assertTrue(s.hasCharacteristics(Spliterator.SIZED));
+        }
+        if (s.hasCharacteristics(Spliterator.SIZED)) {
+            assertTrue(s.estimateSize() != Long.MAX_VALUE);
+            assertTrue(s.getExactSizeIfKnown() >= 0);
+        }
+        try {
+            s.getComparator();
+            assertTrue(s.hasCharacteristics(Spliterator.SORTED));
+        } catch (IllegalStateException e) {
+            assertFalse(s.hasCharacteristics(Spliterator.SORTED));
+        }
+    }
+
+    private static<T> void assertContents(Collection<T> actual, Collection<T> expected, boolean isOrdered) {
+        if (isOrdered) {
+            assertEquals(actual, expected);
+        }
+        else {
+            assertContentsUnordered(actual, expected);
+        }
+    }
+
+    private static<T> void assertContentsUnordered(Iterable<T> actual, Iterable<T> expected) {
+        assertEquals(toBoxedMultiset(actual), toBoxedMultiset(expected));
+    }
+
+    private static <T> Map<T, Integer> toBoxedMultiset(Iterable<T> c) {
+        Map<T, Integer> result = new HashMap<>();
+        c.forEach(e -> {
+            if (result.containsKey(e)) result.put(e, result.get(e) + 1);
+            else result.put(e, 1);
+        });
+        return result;
+    }
+
+    private void executeAndCatch(Class<? extends Exception> expected, Runnable r) {
+        Exception caught = null;
+        try {
+            r.run();
+        }
+        catch (Exception e) {
+            caught = e;
+        }
+
+        assertNotNull(caught,
+                      String.format("No Exception was thrown, expected an Exception of %s to be thrown",
+                                    expected.getName()));
+        assertTrue(expected.isInstance(caught),
+                   String.format("Exception thrown %s not an instance of %s",
+                                 caught.getClass().getName(), expected.getName()));
+    }
+
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamBuilderTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamBuilderTest.java
new file mode 100644
index 0000000..8898c10
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamBuilderTest.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LambdaTestHelpers;
+import java.util.stream.LongStream;
+import java.util.stream.OpTestCase;
+import java.util.stream.Stream;
+import java.util.stream.StreamBuilder;
+import java.util.stream.TestData;
+
+import static java.util.stream.Collectors.toList;
+
+@Test
+public class StreamBuilderTest extends OpTestCase {
+
+    List<Integer> sizes = Arrays.asList(0, 1, 4, 16, 256,
+                                        1023, 1024, 1025,
+                                        2047, 2048, 2049,
+                                        1024 * 32 - 1, 1024 * 32, 1024 * 32 + 1);
+
+    @DataProvider(name = "sizes")
+    public Object[][] createStreamBuilders() {
+        return sizes.stream().map(i -> new Object[] { i }).toArray(Object[][]::new);
+    }
+
+    private void checkException(Class<? extends Exception> ce, Runnable r) {
+        Exception caught = null;
+        try {
+            r.run();
+        } catch (Exception e) {
+            caught = e;
+        }
+
+        assertNotNull(caught);
+        assertTrue(ce.isInstance(caught));
+    }
+
+    private void checkISE(Runnable r) {
+        checkException(IllegalStateException.class, r);
+    }
+
+        //
+
+    @Test
+    public void testSingleton() {
+        TestData.OfRef<Integer> data = TestData.Factory.ofSupplier("[0, 1)",
+                                                                   () -> Stream.of(1));
+
+        withData(data).
+                stream(s -> s).
+                expectedResult(Collections.singletonList(1)).
+                exercise();
+
+        withData(data).
+                stream(s -> s.map(LambdaTestHelpers.identity())).
+                expectedResult(Collections.singletonList(1)).
+                exercise();
+    }
+
+    @Test(dataProvider = "sizes")
+    public void testAfterBuilding(int size) {
+        StreamBuilder<Integer> sb = Stream.builder();
+        IntStream.range(0, size).boxed().forEach(sb);
+        sb.build();
+
+        checkISE(() -> sb.accept(1));
+        checkISE(() -> sb.add(1));
+        checkISE(() -> sb.build());
+    }
+
+    @Test(dataProvider = "sizes")
+    public void testStreamBuilder(int size) {
+        testStreamBuilder(size, (s) -> {
+            StreamBuilder<Integer> sb = Stream.builder();
+            IntStream.range(0, s).boxed().forEach(sb);
+            return sb.build();
+        });
+
+        testStreamBuilder(size, (s) -> {
+            StreamBuilder<Integer> sb = Stream.builder();
+            IntStream.range(0, s).boxed().forEach(i -> {
+                StreamBuilder<Integer> _sb = sb.add(i);
+                assertTrue(sb == _sb);
+            });
+            return sb.build();
+        });
+    }
+
+    private void testStreamBuilder(int size, Function<Integer, Stream<Integer>> supplier) {
+        TestData.OfRef<Integer> data = TestData.Factory.ofSupplier(String.format("[0, %d)", size),
+                                                                   () -> supplier.apply(size));
+
+        withData(data).
+                stream(s -> s).
+                expectedResult(IntStream.range(0, size).boxed().collect(toList())).
+                exercise();
+
+        withData(data).
+                stream(s -> s.map(LambdaTestHelpers.identity())).
+                expectedResult(IntStream.range(0, size).boxed().collect(toList())).
+                exercise();
+    }
+
+    //
+
+    @Test
+    public void testIntSingleton() {
+        TestData.OfInt data = TestData.Factory.ofIntSupplier("[0, 1)",
+                                                             () -> IntStream.of(1));
+
+        withData(data).
+                stream(s -> s).
+                expectedResult(Collections.singletonList(1)).
+                exercise();
+
+        withData(data).
+                stream(s -> s.map(i -> i)).
+                expectedResult(Collections.singletonList(1)).
+                exercise();
+    }
+
+    @Test(dataProvider = "sizes")
+    public void testIntAfterBuilding(int size) {
+        StreamBuilder.OfInt sb = IntStream.builder();
+        IntStream.range(0, size).forEach(sb);
+        sb.build();
+
+        checkISE(() -> sb.accept(1));
+        checkISE(() -> sb.add(1));
+        checkISE(() -> sb.build());
+    }
+
+    @Test(dataProvider = "sizes")
+    public void testIntStreamBuilder(int size) {
+        testIntStreamBuilder(size, (s) -> {
+            StreamBuilder.OfInt sb = IntStream.builder();
+            IntStream.range(0, s).forEach(sb);
+            return sb.build();
+        });
+
+        testIntStreamBuilder(size, (s) -> {
+            StreamBuilder.OfInt sb = IntStream.builder();
+            IntStream.range(0, s).forEach(i -> {
+                StreamBuilder.OfInt _sb = sb.add(i);
+                assertTrue(sb == _sb);
+            });
+            return sb.build();
+        });
+    }
+
+    private void testIntStreamBuilder(int size, Function<Integer, IntStream> supplier) {
+        TestData.OfInt data = TestData.Factory.ofIntSupplier(String.format("[0, %d)", size),
+                                                             () -> supplier.apply(size));
+
+        withData(data).
+                stream(s -> s).
+                expectedResult(IntStream.range(0, size).toArray()).
+                exercise();
+
+        withData(data).
+                stream(s -> s.map(i -> i)).
+                expectedResult(IntStream.range(0, size).toArray()).
+                exercise();
+    }
+
+    //
+
+    @Test
+    public void testLongSingleton() {
+        TestData.OfLong data = TestData.Factory.ofLongSupplier("[0, 1)",
+                                                               () -> LongStream.of(1));
+
+        withData(data).
+                stream(s -> s).
+                expectedResult(Collections.singletonList(1L)).
+                exercise();
+
+        withData(data).
+                stream(s -> s.map(i -> i)).
+                expectedResult(Collections.singletonList(1L)).
+                exercise();
+    }
+
+    @Test(dataProvider = "sizes")
+    public void testLongAfterBuilding(int size) {
+        StreamBuilder.OfLong sb = LongStream.builder();
+        LongStream.range(0, size).forEach(sb);
+        sb.build();
+
+        checkISE(() -> sb.accept(1));
+        checkISE(() -> sb.add(1));
+        checkISE(() -> sb.build());
+    }
+
+    @Test(dataProvider = "sizes")
+    public void testLongStreamBuilder(int size) {
+        testLongStreamBuilder(size, (s) -> {
+            StreamBuilder.OfLong sb = LongStream.builder();
+            LongStream.range(0, s).forEach(sb);
+            return sb.build();
+        });
+
+        testLongStreamBuilder(size, (s) -> {
+            StreamBuilder.OfLong sb = LongStream.builder();
+            LongStream.range(0, s).forEach(i -> {
+                StreamBuilder.OfLong _sb = sb.add(i);
+                assertTrue(sb == _sb);
+            });
+            return sb.build();
+        });
+    }
+
+    private void testLongStreamBuilder(int size, Function<Integer, LongStream> supplier) {
+        TestData.OfLong data = TestData.Factory.ofLongSupplier(String.format("[0, %d)", size),
+                                                               () -> supplier.apply(size));
+
+        withData(data).
+                stream(s -> s).
+                expectedResult(LongStream.range(0, size).toArray()).
+                exercise();
+
+        withData(data).
+                stream(s -> s.map(i -> i)).
+                expectedResult(LongStream.range(0, size).toArray()).
+                exercise();
+    }
+
+    //
+
+    @Test
+    public void testDoubleSingleton() {
+        TestData.OfDouble data = TestData.Factory.ofDoubleSupplier("[0, 1)", () -> DoubleStream.of(1));
+
+        withData(data).
+                stream(s -> s).
+                expectedResult(Collections.singletonList(1.0)).
+                exercise();
+
+        withData(data).
+                stream(s -> s.map(i -> i)).
+                expectedResult(Collections.singletonList(1.0)).
+                exercise();
+    }
+
+    @Test(dataProvider = "sizes")
+    public void testDoubleAfterBuilding(int size) {
+        StreamBuilder.OfDouble sb = DoubleStream.builder();
+        DoubleStream.range(0, size).forEach(sb);
+        sb.build();
+
+        checkISE(() -> sb.accept(1));
+        checkISE(() -> sb.add(1));
+        checkISE(() -> sb.build());
+    }
+
+    @Test(dataProvider = "sizes")
+    public void testDoubleStreamBuilder(int size) {
+        testDoubleStreamBuilder(size, (s) -> {
+            StreamBuilder.OfDouble sb = DoubleStream.builder();
+            DoubleStream.range(0, s).forEach(sb);
+            return sb.build();
+        });
+
+        testDoubleStreamBuilder(size, (s) -> {
+            StreamBuilder.OfDouble sb = DoubleStream.builder();
+            DoubleStream.range(0, s).forEach(i -> {
+                StreamBuilder.OfDouble _sb = sb.add(i);
+                assertTrue(sb == _sb);
+            });
+            return sb.build();
+        });
+    }
+
+    private void testDoubleStreamBuilder(int size, Function<Integer, DoubleStream> supplier) {
+        TestData.OfDouble data = TestData.Factory.ofDoubleSupplier(String.format("[0, %d)", size),
+                                                                   () -> supplier.apply(size));
+
+        withData(data).
+                stream(s -> s).
+                expectedResult(DoubleStream.range(0, size).toArray()).
+                exercise();
+
+        withData(data).
+                stream(s -> s.map(i -> i)).
+                expectedResult(DoubleStream.range(0, size).toArray()).
+                exercise();
+    }
+
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamLinkTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamLinkTest.java
new file mode 100644
index 0000000..e7629ad
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamLinkTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.stream.*;
+
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Function;
+
+@Test
+public class StreamLinkTest extends OpTestCase {
+
+    private <S> Function<S, S> apply(int n, Function<S, S> f) {
+        return s -> {
+            for (int i = 0; i < n; i++) {
+                s = f.apply(s);
+            }
+            return s;
+        };
+    }
+
+    private List<Integer> sizes = Arrays.asList(0, 1, 2, 3, 4, 5, 255, 1000);
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testManyStreams(String name, TestData.OfRef<Integer> data) {
+        for (int n : sizes) {
+            List<Integer> expected = data.stream().map(e -> (Integer) (e + n)).collect(Collectors.toList());
+
+            withData(data).
+                    stream(apply(n, (Stream<Integer> s) -> s.map(e -> (Integer) (e + 1)))).
+                    expectedResult(expected).
+                    exercise();
+        }
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntManyStreams(String name, TestData.OfInt data) {
+        for (int n : sizes) {
+            int[] expected = data.stream().map(e -> e + n).toArray();
+
+            withData(data).
+                    stream(apply(n, (IntStream s) -> s.map(e -> e + 1))).
+                    expectedResult(expected).
+                    exercise();
+        }
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongManyStreams(String name, TestData.OfLong data) {
+        for (int n : sizes) {
+            long[] expected = data.stream().map(e -> e + n).toArray();
+
+            withData(data).
+                    stream(apply(n, (LongStream s) -> s.map(e -> e + 1L))).
+                    expectedResult(expected).
+                    exercise();
+        }
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleManyStreams(String name, TestData.OfDouble data) {
+        for (int n : sizes) {
+            double[] expected = data.stream().map(e -> accumulate(e, n)).toArray();
+
+            withData(data).
+                    stream(apply(n, (DoubleStream s) -> s.map(e -> e + 1.0))).
+                    expectedResult(expected).
+                    exercise();
+        }
+    }
+    private double accumulate(double e, int n) {
+        while (n-- > 0) {
+            e = e + 1.0;
+        }
+        return e;
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamParSeqTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamParSeqTest.java
new file mode 100644
index 0000000..650edc1
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamParSeqTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.stream.Stream;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+@Test
+public class StreamParSeqTest {
+
+    public void testParSeq() {
+        Stream<Integer> s = Arrays.asList(1, 2, 3, 4).stream().parallel();
+        assertTrue(s.isParallel());
+
+        s = s.sequential();
+        assertFalse(s.isParallel());
+
+        s = s.sequential();
+        assertFalse(s.isParallel());
+
+        s = s.parallel();
+        assertTrue(s.isParallel());
+
+        s = s.parallel();
+        assertTrue(s.isParallel());
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamSpliteratorTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamSpliteratorTest.java
new file mode 100644
index 0000000..bc56b2f
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamSpliteratorTest.java
@@ -0,0 +1,596 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.function.DoubleConsumer;
+import java.util.function.Function;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+import java.util.function.UnaryOperator;
+import java.util.stream.DoubleStream;
+import java.util.stream.DoubleStreamTestDataProvider;
+import java.util.stream.IntStream;
+import java.util.stream.IntStreamTestDataProvider;
+import java.util.stream.LambdaTestHelpers;
+import java.util.stream.LongStream;
+import java.util.stream.LongStreamTestDataProvider;
+import java.util.stream.OpTestCase;
+import java.util.stream.SpliteratorTestHelper;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+import java.util.stream.StreamTestDataProvider;
+import java.util.stream.TestData;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import static java.util.stream.LambdaTestHelpers.countTo;
+import static java.util.stream.LambdaTestHelpers.dpEven;
+import static java.util.stream.LambdaTestHelpers.ipEven;
+import static java.util.stream.LambdaTestHelpers.irDoubler;
+import static java.util.stream.LambdaTestHelpers.lpEven;
+import static java.util.stream.LambdaTestHelpers.mDoubler;
+import static java.util.stream.LambdaTestHelpers.pEven;
+import static java.util.stream.LambdaTestHelpers.permuteStreamFunctions;
+
+@Test
+public class StreamSpliteratorTest extends OpTestCase {
+
+    private static class ProxyNoExactSizeSpliterator<T> implements Spliterator<T> {
+        final Spliterator<T> sp;
+        final boolean proxyEstimateSize;
+        int splits = 0;
+        int prefixSplits = 0;
+
+        long sizeOnTraversal = -1;
+
+        ProxyNoExactSizeSpliterator(Spliterator<T> sp, boolean proxyEstimateSize) {
+            this.sp = sp;
+            this.proxyEstimateSize = proxyEstimateSize;
+        }
+
+        @Override
+        public Spliterator<T> trySplit() {
+            splits++;
+            Spliterator<T> prefix = sp.trySplit();
+            if (prefix != null)
+                prefixSplits++;
+            return prefix;
+        }
+
+        @Override
+        public boolean tryAdvance(Consumer<? super T> consumer) {
+            if (sizeOnTraversal == -1)
+                sizeOnTraversal = sp.getExactSizeIfKnown();
+            return sp.tryAdvance(consumer);
+        }
+
+        @Override
+        public void forEachRemaining(Consumer<? super T> consumer) {
+            sizeOnTraversal = sp.getExactSizeIfKnown();
+            sp.forEachRemaining(consumer);
+        }
+
+        @Override
+        public long estimateSize() {
+            return proxyEstimateSize ? sp.estimateSize() : Long.MAX_VALUE;
+        }
+
+        @Override
+        public Comparator<? super T> getComparator() {
+            return sp.getComparator();
+        }
+
+        @Override
+        public int characteristics() {
+            if (proxyEstimateSize)
+                return sp.characteristics();
+            else
+                return sp.characteristics() & ~(Spliterator.SUBSIZED | Spliterator.SIZED);
+        }
+
+        private static class OfInt extends ProxyNoExactSizeSpliterator<Integer> implements Spliterator.OfInt {
+            final Spliterator.OfInt psp;
+
+            private OfInt(Spliterator.OfInt sp, boolean proxyEstimateSize) {
+                super(sp, proxyEstimateSize);
+                this.psp = sp;
+            }
+
+            @Override
+            public Spliterator.OfInt trySplit() {
+                splits++;
+                Spliterator.OfInt prefix = psp.trySplit();
+                if (prefix != null)
+                    prefixSplits++;
+                return prefix;
+            }
+
+            @Override
+            public boolean tryAdvance(Consumer<? super Integer> consumer) {
+                return Spliterator.OfInt.super.tryAdvance(consumer);
+            }
+
+            @Override
+            public void forEachRemaining(Consumer<? super Integer> consumer) {
+                Spliterator.OfInt.super.forEachRemaining(consumer);
+            }
+
+            @Override
+            public boolean tryAdvance(IntConsumer consumer) {
+                if (sizeOnTraversal == -1)
+                    sizeOnTraversal = sp.getExactSizeIfKnown();
+                return psp.tryAdvance(consumer);
+            }
+
+            @Override
+            public void forEachRemaining(IntConsumer consumer) {
+                sizeOnTraversal = sp.getExactSizeIfKnown();
+                psp.forEachRemaining(consumer);
+            }
+        }
+
+        private static class OfLong extends ProxyNoExactSizeSpliterator<Long> implements Spliterator.OfLong {
+            final Spliterator.OfLong psp;
+
+            private OfLong(Spliterator.OfLong sp, boolean proxyEstimateSize) {
+                super(sp, proxyEstimateSize);
+                this.psp = sp;
+            }
+
+            @Override
+            public Spliterator.OfLong trySplit() {
+                splits++;
+                Spliterator.OfLong prefix = psp.trySplit();
+                if (prefix != null)
+                    prefixSplits++;
+                return prefix;
+            }
+
+            @Override
+            public boolean tryAdvance(Consumer<? super Long> consumer) {
+                return Spliterator.OfLong.super.tryAdvance(consumer);
+            }
+
+            @Override
+            public void forEachRemaining(Consumer<? super Long> consumer) {
+                Spliterator.OfLong.super.forEachRemaining(consumer);
+            }
+
+            @Override
+            public boolean tryAdvance(LongConsumer consumer) {
+                if (sizeOnTraversal == -1)
+                    sizeOnTraversal = sp.getExactSizeIfKnown();
+                return psp.tryAdvance(consumer);
+            }
+
+            @Override
+            public void forEachRemaining(LongConsumer consumer) {
+                sizeOnTraversal = sp.getExactSizeIfKnown();
+                psp.forEachRemaining(consumer);
+            }
+        }
+
+        private static class OfDouble extends ProxyNoExactSizeSpliterator<Double>
+                implements Spliterator.OfDouble {
+            final Spliterator.OfDouble psp;
+
+            private OfDouble(Spliterator.OfDouble sp, boolean proxyEstimateSize) {
+                super(sp, proxyEstimateSize);
+                this.psp = sp;
+            }
+
+            @Override
+            public Spliterator.OfDouble trySplit() {
+                splits++;
+                Spliterator.OfDouble prefix = psp.trySplit();
+                if (prefix != null)
+                    prefixSplits++;
+                return prefix;
+            }
+
+            @Override
+            public boolean tryAdvance(Consumer<? super Double> consumer) {
+                return Spliterator.OfDouble.super.tryAdvance(consumer);
+            }
+
+            @Override
+            public void forEachRemaining(Consumer<? super Double> consumer) {
+                Spliterator.OfDouble.super.forEachRemaining(consumer);
+            }
+
+            @Override
+            public boolean tryAdvance(DoubleConsumer consumer) {
+                if (sizeOnTraversal == -1)
+                    sizeOnTraversal = sp.getExactSizeIfKnown();
+                return psp.tryAdvance(consumer);
+            }
+
+            @Override
+            public void forEachRemaining(DoubleConsumer consumer) {
+                sizeOnTraversal = sp.getExactSizeIfKnown();
+                psp.forEachRemaining(consumer);
+            }
+        }
+    }
+
+    public void testSplitting() {
+        // Size is assumed to be larger than the target size for no splitting
+        // @@@ Need way to obtain the target size
+        List<Integer> l = countTo(1000);
+
+        List<Consumer<Stream<Integer>>> terminalOps = Arrays.asList(
+                s -> s.toArray(),
+                s -> s.forEach(e -> { }),
+                s -> s.reduce(Integer::sum)
+        );
+
+        List<UnaryOperator<Stream<Integer>>> intermediateOps = Arrays.asList(
+                s -> s.parallel(),
+                // The following ensures the wrapping spliterator is tested
+                s -> s.map(LambdaTestHelpers.identity()).parallel()
+        );
+
+        for (Consumer<Stream<Integer>> terminalOp : terminalOps) {
+            for (UnaryOperator<Stream<Integer>> intermediateOp : intermediateOps) {
+                for (boolean proxyEstimateSize : new boolean[]{false, true}) {
+                    Spliterator<Integer> sp = intermediateOp.apply(l.stream()).spliterator();
+                    ProxyNoExactSizeSpliterator<Integer> psp = new ProxyNoExactSizeSpliterator<>(sp, proxyEstimateSize);
+                    Stream<Integer> s = StreamSupport.parallelStream(psp);
+                    terminalOp.accept(s);
+                    Assert.assertTrue(psp.splits > 0,
+                                      String.format("Number of splits should be greater that zero when proxyEstimateSize is %s",
+                                                    proxyEstimateSize));
+                    Assert.assertTrue(psp.prefixSplits > 0,
+                                      String.format("Number of non-null prefix splits should be greater that zero when proxyEstimateSize is %s",
+                                                    proxyEstimateSize));
+                    Assert.assertTrue(psp.sizeOnTraversal < l.size(),
+                                      String.format("Size on traversal of last split should be less than the size of the list, %d, when proxyEstimateSize is %s",
+                                                    l.size(), proxyEstimateSize));
+                }
+            }
+        }
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>",
+          dataProviderClass = StreamTestDataProvider.class,
+          groups = { "serialization-hostile" })
+    public void testStreamSpliterators(String name, TestData.OfRef<Integer> data) {
+        for (Function<Stream<Integer>, Stream<Integer>> f : streamFunctions()) {
+            withData(data).
+                    stream((Stream<Integer> in) -> {
+                        Stream<Integer> out = f.apply(in);
+                        return StreamSupport.stream(() -> out.spliterator(), OpTestCase.getStreamFlags(out));
+                    }).
+                    exercise();
+
+            withData(data).
+                    stream((Stream<Integer> in) -> {
+                        Stream<Integer> out = f.apply(in);
+                        return StreamSupport.parallelStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out));
+                    }).
+                    exercise();
+        }
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testSpliterators(String name, TestData.OfRef<Integer> data) {
+        for (Function<Stream<Integer>, Stream<Integer>> f : streamFunctions()) {
+            SpliteratorTestHelper.testSpliterator(() -> f.apply(data.stream()).spliterator());
+        }
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testParSpliterators(String name, TestData.OfRef<Integer> data) {
+        for (Function<Stream<Integer>, Stream<Integer>> f : streamFunctions()) {
+            SpliteratorTestHelper.testSpliterator(() -> f.apply(data.parallelStream()).spliterator());
+        }
+    }
+
+    private List<Function<Stream<Integer>, Stream<Integer>>> streamFunctions;
+
+    List<Function<Stream<Integer>, Stream<Integer>>> streamFunctions() {
+        if (streamFunctions == null) {
+            List<Function<Stream<Integer>, Stream<Integer>>> opFunctions = Arrays.asList(
+                    s -> s.filter(pEven),
+                    s -> s.map(mDoubler),
+                    // @@@ Add distinct once asserting results with or without order
+                    //     is correctly supported
+//                    s -> s.distinct(),
+                    s -> s.sorted());
+
+            streamFunctions = permuteStreamFunctions(opFunctions);
+        }
+
+        return streamFunctions;
+    }
+
+    //
+
+    public void testIntSplitting() {
+        List<Consumer<IntStream>> terminalOps = Arrays.asList(
+                s -> s.toArray(),
+                s -> s.forEach(e -> {}),
+                s -> s.reduce(Integer::sum)
+        );
+
+        List<UnaryOperator<IntStream>> intermediateOps = Arrays.asList(
+                s -> s.parallel(),
+                // The following ensures the wrapping spliterator is tested
+                s -> s.map(i -> i).parallel()
+        );
+
+        for (Consumer<IntStream> terminalOp : terminalOps) {
+            for (UnaryOperator<IntStream> intermediateOp : intermediateOps) {
+                for (boolean proxyEstimateSize : new boolean[]{false, true}) {
+                    // Size is assumed to be larger than the target size for no splitting
+                    // @@@ Need way to obtain the target size
+                    Spliterator.OfInt sp = intermediateOp.apply(IntStream.range(0, 1000)).spliterator();
+                    ProxyNoExactSizeSpliterator.OfInt psp = new ProxyNoExactSizeSpliterator.OfInt(sp, proxyEstimateSize);
+                    IntStream s = StreamSupport.intParallelStream(psp);
+                    terminalOp.accept(s);
+                    Assert.assertTrue(psp.splits > 0,
+                                      String.format("Number of splits should be greater that zero when proxyEstimateSize is %s",
+                                                    proxyEstimateSize));
+                    Assert.assertTrue(psp.prefixSplits > 0,
+                                      String.format("Number of non-null prefix splits should be greater that zero when proxyEstimateSize is %s",
+                                                    proxyEstimateSize));
+                    Assert.assertTrue(psp.sizeOnTraversal < 1000,
+                                      String.format("Size on traversal of last split should be less than the size of the list, %d, when proxyEstimateSize is %s",
+                                                    1000, proxyEstimateSize));
+                }
+            }
+        }
+    }
+
+    @Test(dataProvider = "IntStreamTestData",
+          dataProviderClass = IntStreamTestDataProvider.class,
+          groups = { "serialization-hostile" })
+    public void testIntStreamSpliterators(String name, TestData.OfInt data) {
+        for (Function<IntStream, IntStream> f : intStreamFunctions()) {
+            withData(data).
+                    stream(in -> {
+                        IntStream out = f.apply(in);
+                        return StreamSupport.intStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out));
+                    }).
+                    exercise();
+
+            withData(data).
+                    stream((in) -> {
+                        IntStream out = f.apply(in);
+                        return StreamSupport.intParallelStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out));
+                    }).
+                    exercise();
+        }
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntSpliterators(String name, TestData.OfInt data) {
+        for (Function<IntStream, IntStream> f : intStreamFunctions()) {
+            SpliteratorTestHelper.testIntSpliterator(() -> f.apply(data.stream()).spliterator());
+        }
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntParSpliterators(String name, TestData.OfInt data) {
+        for (Function<IntStream, IntStream> f : intStreamFunctions()) {
+            SpliteratorTestHelper.testIntSpliterator(() -> f.apply(data.parallelStream()).spliterator());
+        }
+    }
+
+    private List<Function<IntStream, IntStream>> intStreamFunctions;
+
+    List<Function<IntStream, IntStream>> intStreamFunctions() {
+        if (intStreamFunctions == null) {
+            List<Function<IntStream, IntStream>> opFunctions = Arrays.asList(
+                    s -> s.filter(ipEven),
+                    s -> s.map(irDoubler),
+                    s -> s.sorted());
+
+            intStreamFunctions = permuteStreamFunctions(opFunctions);
+        }
+
+        return intStreamFunctions;
+    }
+
+    //
+
+    public void testLongSplitting() {
+        List<Consumer<LongStream>> terminalOps = Arrays.asList(
+                s -> s.toArray(),
+                s -> s.forEach(e -> {}),
+                s -> s.reduce(Long::sum)
+        );
+
+        List<UnaryOperator<LongStream>> intermediateOps = Arrays.asList(
+                s -> s.parallel(),
+                // The following ensures the wrapping spliterator is tested
+                s -> s.map(i -> i).parallel()
+        );
+
+        for (Consumer<LongStream> terminalOp : terminalOps) {
+            for (UnaryOperator<LongStream> intermediateOp : intermediateOps) {
+                for (boolean proxyEstimateSize : new boolean[]{false, true}) {
+                    // Size is assumed to be larger than the target size for no splitting
+                    // @@@ Need way to obtain the target size
+                    Spliterator.OfLong sp = intermediateOp.apply(LongStream.range(0, 1000)).spliterator();
+                    ProxyNoExactSizeSpliterator.OfLong psp = new ProxyNoExactSizeSpliterator.OfLong(sp, proxyEstimateSize);
+                    LongStream s = StreamSupport.longParallelStream(psp);
+                    terminalOp.accept(s);
+                    Assert.assertTrue(psp.splits > 0,
+                                      String.format("Number of splits should be greater that zero when proxyEstimateSize is %s",
+                                                    proxyEstimateSize));
+                    Assert.assertTrue(psp.prefixSplits > 0,
+                                      String.format("Number of non-null prefix splits should be greater that zero when proxyEstimateSize is %s",
+                                                    proxyEstimateSize));
+                    Assert.assertTrue(psp.sizeOnTraversal < 1000,
+                                      String.format("Size on traversal of last split should be less than the size of the list, %d, when proxyEstimateSize is %s",
+                                                    1000, proxyEstimateSize));
+                }
+            }
+        }
+    }
+
+    @Test(dataProvider = "LongStreamTestData",
+          dataProviderClass = LongStreamTestDataProvider.class,
+          groups = { "serialization-hostile" })
+    public void testLongStreamSpliterators(String name, TestData.OfLong data) {
+        for (Function<LongStream, LongStream> f : longStreamFunctions()) {
+            withData(data).
+                    stream(in -> {
+                        LongStream out = f.apply(in);
+                        return StreamSupport.longStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out));
+                    }).
+                    exercise();
+
+            withData(data).
+                    stream((in) -> {
+                        LongStream out = f.apply(in);
+                        return StreamSupport.longParallelStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out));
+                    }).
+                    exercise();
+        }
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongSpliterators(String name, TestData.OfLong data) {
+        for (Function<LongStream, LongStream> f : longStreamFunctions()) {
+            SpliteratorTestHelper.testLongSpliterator(() -> f.apply(data.stream()).spliterator());
+        }
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongParSpliterators(String name, TestData.OfLong data) {
+        for (Function<LongStream, LongStream> f : longStreamFunctions()) {
+            SpliteratorTestHelper.testLongSpliterator(() -> f.apply(data.parallelStream()).spliterator());
+        }
+    }
+
+    private List<Function<LongStream, LongStream>> longStreamFunctions;
+
+    List<Function<LongStream, LongStream>> longStreamFunctions() {
+        if (longStreamFunctions == null) {
+            List<Function<LongStream, LongStream>> opFunctions = Arrays.asList(
+                    s -> s.filter(lpEven),
+                    s -> s.map(x -> x * 2L),
+                    s -> s.sorted());
+
+            longStreamFunctions = permuteStreamFunctions(opFunctions);
+        }
+
+        return longStreamFunctions;
+    }
+
+    //
+
+    public void testDoubleSplitting() {
+        List<Consumer<DoubleStream>> terminalOps = Arrays.asList(
+                s -> s.toArray(),
+                s -> s.forEach(e -> {}),
+                s -> s.reduce(Double::sum)
+        );
+
+        List<UnaryOperator<DoubleStream>> intermediateOps = Arrays.asList(
+                s -> s.parallel(),
+                // The following ensures the wrapping spliterator is tested
+                s -> s.map(i -> i).parallel()
+        );
+
+        for (Consumer<DoubleStream> terminalOp : terminalOps) {
+            for (UnaryOperator<DoubleStream> intermediateOp : intermediateOps) {
+                for (boolean proxyEstimateSize : new boolean[]{false, true}) {
+                    // Size is assumed to be larger than the target size for no splitting
+                    // @@@ Need way to obtain the target size
+                    Spliterator.OfDouble sp = intermediateOp.apply(DoubleStream.range(0, 1000)).spliterator();
+                    ProxyNoExactSizeSpliterator.OfDouble psp = new ProxyNoExactSizeSpliterator.OfDouble(sp, proxyEstimateSize);
+                    DoubleStream s = StreamSupport.doubleParallelStream(psp);
+                    terminalOp.accept(s);
+                    Assert.assertTrue(psp.splits > 0,
+                                      String.format("Number of splits should be greater that zero when proxyEstimateSize is %s",
+                                                    proxyEstimateSize));
+                    Assert.assertTrue(psp.prefixSplits > 0,
+                                      String.format("Number of non-null prefix splits should be greater that zero when proxyEstimateSize is %s",
+                                                    proxyEstimateSize));
+                    Assert.assertTrue(psp.sizeOnTraversal < 1000,
+                                      String.format("Size on traversal of last split should be less than the size of the list, %d, when proxyEstimateSize is %s",
+                                                    1000, proxyEstimateSize));
+                }
+            }
+        }
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData",
+          dataProviderClass = DoubleStreamTestDataProvider.class,
+          groups = { "serialization-hostile" })
+    public void testDoubleStreamSpliterators(String name, TestData.OfDouble data) {
+        for (Function<DoubleStream, DoubleStream> f : doubleStreamFunctions()) {
+            withData(data).
+                    stream(in -> {
+                        DoubleStream out = f.apply(in);
+                        return StreamSupport.doubleStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out));
+                    }).
+                    exercise();
+
+            withData(data).
+                    stream((in) -> {
+                        DoubleStream out = f.apply(in);
+                        return StreamSupport.doubleParallelStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out));
+                    }).
+                    exercise();
+        }
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleSpliterators(String name, TestData.OfDouble data) {
+        for (Function<DoubleStream, DoubleStream> f : doubleStreamFunctions()) {
+            SpliteratorTestHelper.testDoubleSpliterator(() -> f.apply(data.stream()).spliterator());
+        }
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleParSpliterators(String name, TestData.OfDouble data) {
+        for (Function<DoubleStream, DoubleStream> f : doubleStreamFunctions()) {
+            SpliteratorTestHelper.testDoubleSpliterator(() -> f.apply(data.parallelStream()).spliterator());
+        }
+    }
+
+    private List<Function<DoubleStream, DoubleStream>> doubleStreamFunctions;
+
+    List<Function<DoubleStream, DoubleStream>> doubleStreamFunctions() {
+        if (doubleStreamFunctions == null) {
+            List<Function<DoubleStream, DoubleStream>> opFunctions = Arrays.asList(
+                    s -> s.filter(dpEven),
+                    s -> s.map(x -> x * 2.0),
+                    s -> s.sorted());
+
+            doubleStreamFunctions = permuteStreamFunctions(opFunctions);
+        }
+
+        return doubleStreamFunctions;
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SummaryStatisticsTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SummaryStatisticsTest.java
new file mode 100644
index 0000000..fb5a92f
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SummaryStatisticsTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.ArrayList;
+import java.util.DoubleSummaryStatistics;
+import java.util.IntSummaryStatistics;
+import java.util.List;
+import java.util.LongSummaryStatistics;
+import java.util.stream.Collectors;
+import java.util.stream.OpTestCase;
+
+import org.testng.annotations.Test;
+
+import static java.util.stream.LambdaTestHelpers.countTo;
+
+/**
+ * TestSummaryStatistics
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class SummaryStatisticsTest extends OpTestCase {
+    public void testIntStatistics() {
+        List<IntSummaryStatistics> instances = new ArrayList<>();
+        instances.add(countTo(1000).stream().collect(Collectors.toIntSummaryStatistics(i -> i)));
+        instances.add(countTo(1000).stream().mapToInt(i -> i).summaryStatistics());
+        instances.add(countTo(1000).parallelStream().collect(Collectors.toIntSummaryStatistics(i -> i)));
+        instances.add(countTo(1000).parallelStream().mapToInt(i -> i).summaryStatistics());
+
+        for (IntSummaryStatistics stats : instances) {
+            assertEquals(stats.getCount(), 1000);
+            assertEquals(stats.getSum(), countTo(1000).stream().mapToInt(i -> i).sum());
+            assertEquals(stats.getMax(), 1000);
+            assertEquals(stats.getMin(), 1);
+        }
+    }
+
+    public void testLongStatistics() {
+        List<LongSummaryStatistics> instances = new ArrayList<>();
+        instances.add(countTo(1000).stream().collect(Collectors.toLongSummaryStatistics(i -> i)));
+        instances.add(countTo(1000).stream().mapToLong(i -> i).summaryStatistics());
+        instances.add(countTo(1000).parallelStream().collect(Collectors.toLongSummaryStatistics(i -> i)));
+        instances.add(countTo(1000).parallelStream().mapToLong(i -> i).summaryStatistics());
+
+        for (LongSummaryStatistics stats : instances) {
+            assertEquals(stats.getCount(), 1000);
+            assertEquals(stats.getSum(), (long) countTo(1000).stream().mapToInt(i -> i).sum());
+            assertEquals(stats.getMax(), 1000L);
+            assertEquals(stats.getMin(), 1L);
+        }
+    }
+
+    public void testDoubleStatistics() {
+        List<DoubleSummaryStatistics> instances = new ArrayList<>();
+        instances.add(countTo(1000).stream().collect(Collectors.toDoubleSummaryStatistics(i -> i)));
+        instances.add(countTo(1000).stream().mapToDouble(i -> i).summaryStatistics());
+        instances.add(countTo(1000).parallelStream().collect(Collectors.toDoubleSummaryStatistics(i -> i)));
+        instances.add(countTo(1000).parallelStream().mapToDouble(i -> i).summaryStatistics());
+
+        for (DoubleSummaryStatistics stats : instances) {
+            assertEquals(stats.getCount(), 1000);
+            assertEquals(stats.getSum(), (double) countTo(1000).stream().mapToInt(i -> i).sum());
+            assertEquals(stats.getMax(), 1000.0);
+            assertEquals(stats.getMin(), 1.0);
+        }
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java
new file mode 100644
index 0000000..2dd8c55
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java
@@ -0,0 +1,398 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.TreeMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+import java.util.stream.LambdaTestHelpers;
+import java.util.stream.OpTestCase;
+import java.util.stream.Stream;
+import java.util.stream.StreamOpFlagTestHelper;
+import java.util.stream.StreamTestDataProvider;
+import java.util.stream.TestData;
+
+import org.testng.annotations.Test;
+
+import static java.util.stream.Collectors.groupingBy;
+import static java.util.stream.Collectors.groupingByConcurrent;
+import static java.util.stream.Collectors.partitioningBy;
+import static java.util.stream.Collectors.reducing;
+import static java.util.stream.Collectors.toCollection;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.LambdaTestHelpers.assertContents;
+import static java.util.stream.LambdaTestHelpers.assertContentsUnordered;
+import static java.util.stream.LambdaTestHelpers.mDoubler;
+
+/**
+ * TabulatorsTest
+ *
+ * @author Brian Goetz
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class TabulatorsTest extends OpTestCase {
+    // There are 8 versions of groupingBy:
+    //   groupingBy: { map supplier, not } x { downstream collector, not } x { concurrent, not }
+    // There are 2 versions of partition: { map supplier, not }
+    // There are 4 versions of toMap
+    //   mappedTo(function, mapSupplier?, mergeFunction?)
+    // Each variety needs at least one test
+    // Plus a variety of multi-level tests (groupBy(..., partition), partition(..., groupBy))
+    // Plus negative tests for mapping to null
+    // Each test should be matched by a nest of asserters (see TabulationAssertion...)
+
+
+    private static abstract class TabulationAssertion<T, U> {
+        abstract void assertValue(U value,
+                                  Supplier<Stream<T>> source,
+                                  boolean ordered) throws ReflectiveOperationException;
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    static class GroupedMapAssertion<T, K, V, M extends Map<K, ? extends V>> extends TabulationAssertion<T, M> {
+        private final Class<? extends Map> clazz;
+        private final Function<T, K> classifier;
+        private final TabulationAssertion<T,V> downstream;
+
+        protected GroupedMapAssertion(Function<T, K> classifier,
+                                      Class<? extends Map> clazz,
+                                      TabulationAssertion<T, V> downstream) {
+            this.clazz = clazz;
+            this.classifier = classifier;
+            this.downstream = downstream;
+        }
+
+        void assertValue(M map,
+                         Supplier<Stream<T>> source,
+                         boolean ordered) throws ReflectiveOperationException {
+            if (!clazz.isAssignableFrom(map.getClass()))
+                fail(String.format("Class mismatch in GroupedMapAssertion: %s, %s", clazz, map.getClass()));
+            assertContentsUnordered(map.keySet(), source.get().map(classifier).collect(Collectors.toSet()));
+            for (Map.Entry<K, ? extends V> entry : map.entrySet()) {
+                K key = entry.getKey();
+                downstream.assertValue(entry.getValue(),
+                                       () -> source.get().filter(e -> classifier.apply(e).equals(key)),
+                                       ordered);
+            }
+        }
+    }
+
+    static class PartitionAssertion<T, D> extends TabulationAssertion<T, Map<Boolean,D>> {
+        private final Predicate<T> predicate;
+        private final TabulationAssertion<T,D> downstream;
+
+        protected PartitionAssertion(Predicate<T> predicate,
+                                     TabulationAssertion<T, D> downstream) {
+            this.predicate = predicate;
+            this.downstream = downstream;
+        }
+
+        void assertValue(Map<Boolean, D> map,
+                         Supplier<Stream<T>> source,
+                         boolean ordered) throws ReflectiveOperationException {
+            if (!Map.class.isAssignableFrom(map.getClass()))
+                fail(String.format("Class mismatch in PartitionAssertion: %s", map.getClass()));
+            assertEquals(2, map.size());
+            downstream.assertValue(map.get(true), () -> source.get().filter(predicate), ordered);
+            downstream.assertValue(map.get(false), () -> source.get().filter(predicate.negate()), ordered);
+        }
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    static class ListAssertion<T> extends TabulationAssertion<T, List<T>> {
+        @Override
+        void assertValue(List<T> value, Supplier<Stream<T>> source, boolean ordered)
+                throws ReflectiveOperationException {
+            if (!List.class.isAssignableFrom(value.getClass()))
+                fail(String.format("Class mismatch in ListAssertion: %s", value.getClass()));
+            Stream<T> stream = source.get();
+            List<T> result = new ArrayList<>();
+            for (Iterator<T> it = stream.iterator(); it.hasNext(); ) // avoid capturing result::add
+                result.add(it.next());
+            if (StreamOpFlagTestHelper.isStreamOrdered(stream) && ordered)
+                assertContents(value, result);
+            else
+                assertContentsUnordered(value, result);
+        }
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    static class CollectionAssertion<T> extends TabulationAssertion<T, Collection<T>> {
+        private final Class<? extends Collection> clazz;
+        private final boolean targetOrdered;
+
+        protected CollectionAssertion(Class<? extends Collection> clazz, boolean targetOrdered) {
+            this.clazz = clazz;
+            this.targetOrdered = targetOrdered;
+        }
+
+        @Override
+        void assertValue(Collection<T> value, Supplier<Stream<T>> source, boolean ordered)
+                throws ReflectiveOperationException {
+            if (!clazz.isAssignableFrom(value.getClass()))
+                fail(String.format("Class mismatch in CollectionAssertion: %s, %s", clazz, value.getClass()));
+            Stream<T> stream = source.get();
+            Collection<T> result = clazz.newInstance();
+            for (Iterator<T> it = stream.iterator(); it.hasNext(); ) // avoid capturing result::add
+                result.add(it.next());
+            if (StreamOpFlagTestHelper.isStreamOrdered(stream) && targetOrdered && ordered)
+                assertContents(value, result);
+            else
+                assertContentsUnordered(value, result);
+        }
+    }
+
+    static class ReduceAssertion<T, U> extends TabulationAssertion<T, U> {
+        private final U identity;
+        private final Function<T, U> mapper;
+        private final BinaryOperator<U> reducer;
+
+        ReduceAssertion(U identity, Function<T, U> mapper, BinaryOperator<U> reducer) {
+            this.identity = identity;
+            this.mapper = mapper;
+            this.reducer = reducer;
+        }
+
+        @Override
+        void assertValue(U value, Supplier<Stream<T>> source, boolean ordered)
+                throws ReflectiveOperationException {
+            Optional<U> reduced = source.get().map(mapper).reduce(reducer);
+            if (value == null)
+                assertTrue(!reduced.isPresent());
+            else if (!reduced.isPresent()) {
+                assertEquals(value, identity);
+            }
+            else {
+                assertEquals(value, reduced.get());
+            }
+        }
+    }
+
+    private<T, M extends Map>
+    void exerciseMapTabulation(TestData<T, Stream<T>> data,
+                               Collector<T, ? extends M> collector,
+                               TabulationAssertion<T, M> assertion)
+            throws ReflectiveOperationException {
+        boolean ordered = data.isOrdered()
+                          && !collector.characteristics().contains(Collector.Characteristics.UNORDERED);
+        M m = withData(data)
+                .terminal(s -> s.collect(collector))
+                .parallelEqualityAsserter(ordered ? LambdaTestHelpers::assertContentsEqual : this::nestedMapEqualityAssertion)
+                .exercise();
+        assertion.assertValue(m, () -> data.stream(), ordered);
+        m = withData(data)
+                .terminal(s -> s.unordered().collect(collector))
+                .parallelEqualityAsserter(this::nestedMapEqualityAssertion)
+                .exercise();
+        assertion.assertValue(m, () -> data.stream(), false);
+    }
+
+    private void nestedMapEqualityAssertion(Object o1, Object o2) {
+        if (o1 instanceof Map) {
+            Map m1 = (Map) o1;
+            Map m2 = (Map) o2;
+            assertContentsUnordered(m1.keySet(), m2.keySet());
+            for (Object k : m1.keySet())
+                nestedMapEqualityAssertion(m1.get(k), m2.get(k));
+        }
+        else if (o1 instanceof Collection) {
+            assertContentsUnordered(((Collection) o1), ((Collection) o2));
+        }
+        else
+            assertEquals(o1, o2);
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testSimpleGroupBy(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
+        Function<Integer, Integer> classifier = i -> i % 3;
+
+        // Single-level groupBy
+        exerciseMapTabulation(data, groupingBy(classifier),
+                              new GroupedMapAssertion<>(classifier, HashMap.class,
+                                                        new ListAssertion<>()));
+        exerciseMapTabulation(data, groupingByConcurrent(classifier),
+                              new GroupedMapAssertion<>(classifier, ConcurrentHashMap.class,
+                                                        new ListAssertion<>()));
+
+        // With explicit constructors
+        exerciseMapTabulation(data,
+                              groupingBy(classifier, TreeMap::new, toCollection(HashSet::new)),
+                              new GroupedMapAssertion<>(classifier, TreeMap.class,
+                                                        new CollectionAssertion<Integer>(HashSet.class, false)));
+        exerciseMapTabulation(data,
+                              groupingByConcurrent(classifier, ConcurrentSkipListMap::new,
+                                                   toCollection(HashSet::new)),
+                              new GroupedMapAssertion<>(classifier, ConcurrentSkipListMap.class,
+                                                        new CollectionAssertion<Integer>(HashSet.class, false)));
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testTwoLevelGroupBy(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
+        Function<Integer, Integer> classifier = i -> i % 6;
+        Function<Integer, Integer> classifier2 = i -> i % 23;
+
+        // Two-level groupBy
+        exerciseMapTabulation(data,
+                              groupingBy(classifier, groupingBy(classifier2)),
+                              new GroupedMapAssertion<>(classifier, HashMap.class,
+                                                        new GroupedMapAssertion<>(classifier2, HashMap.class,
+                                                                                  new ListAssertion<>())));
+        // with concurrent as upstream
+        exerciseMapTabulation(data,
+                              groupingByConcurrent(classifier, groupingBy(classifier2)),
+                              new GroupedMapAssertion<>(classifier, ConcurrentHashMap.class,
+                                                        new GroupedMapAssertion<>(classifier2, HashMap.class,
+                                                                                  new ListAssertion<>())));
+        // with concurrent as downstream
+        exerciseMapTabulation(data,
+                              groupingBy(classifier, groupingByConcurrent(classifier2)),
+                              new GroupedMapAssertion<>(classifier, HashMap.class,
+                                                        new GroupedMapAssertion<>(classifier2, ConcurrentHashMap.class,
+                                                                                  new ListAssertion<>())));
+        // with concurrent as upstream and downstream
+        exerciseMapTabulation(data,
+                              groupingByConcurrent(classifier, groupingByConcurrent(classifier2)),
+                              new GroupedMapAssertion<>(classifier, ConcurrentHashMap.class,
+                                                        new GroupedMapAssertion<>(classifier2, ConcurrentHashMap.class,
+                                                                                  new ListAssertion<>())));
+
+        // With explicit constructors
+        exerciseMapTabulation(data,
+                              groupingBy(classifier, TreeMap::new, groupingBy(classifier2, TreeMap::new, toCollection(HashSet::new))),
+                              new GroupedMapAssertion<>(classifier, TreeMap.class,
+                                                        new GroupedMapAssertion<>(classifier2, TreeMap.class,
+                                                                                  new CollectionAssertion<Integer>(HashSet.class, false))));
+        // with concurrent as upstream
+        exerciseMapTabulation(data,
+                              groupingByConcurrent(classifier, ConcurrentSkipListMap::new, groupingBy(classifier2, TreeMap::new, toList())),
+                              new GroupedMapAssertion<>(classifier, ConcurrentSkipListMap.class,
+                                                        new GroupedMapAssertion<>(classifier2, TreeMap.class,
+                                                                                  new ListAssertion<>())));
+        // with concurrent as downstream
+        exerciseMapTabulation(data,
+                              groupingBy(classifier, TreeMap::new, groupingByConcurrent(classifier2, ConcurrentSkipListMap::new, toList())),
+                              new GroupedMapAssertion<>(classifier, TreeMap.class,
+                                                        new GroupedMapAssertion<>(classifier2, ConcurrentSkipListMap.class,
+                                                                                  new ListAssertion<>())));
+        // with concurrent as upstream and downstream
+        exerciseMapTabulation(data,
+                              groupingByConcurrent(classifier, ConcurrentSkipListMap::new, groupingByConcurrent(classifier2, ConcurrentSkipListMap::new, toList())),
+                              new GroupedMapAssertion<>(classifier, ConcurrentSkipListMap.class,
+                                                        new GroupedMapAssertion<>(classifier2, ConcurrentSkipListMap.class,
+                                                                                  new ListAssertion<>())));
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testGroupedReduce(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
+        Function<Integer, Integer> classifier = i -> i % 3;
+
+        // Single-level simple reduce
+        exerciseMapTabulation(data,
+                              groupingBy(classifier, reducing(0, Integer::sum)),
+                              new GroupedMapAssertion<>(classifier, HashMap.class,
+                                                        new ReduceAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
+        // with concurrent
+        exerciseMapTabulation(data,
+                              groupingByConcurrent(classifier, reducing(0, Integer::sum)),
+                              new GroupedMapAssertion<>(classifier, ConcurrentHashMap.class,
+                                                        new ReduceAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
+
+        // With explicit constructors
+        exerciseMapTabulation(data,
+                              groupingBy(classifier, TreeMap::new, reducing(0, Integer::sum)),
+                              new GroupedMapAssertion<>(classifier, TreeMap.class,
+                                                        new ReduceAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
+        // with concurrent
+        exerciseMapTabulation(data,
+                              groupingByConcurrent(classifier, ConcurrentSkipListMap::new, reducing(0, Integer::sum)),
+                              new GroupedMapAssertion<>(classifier, ConcurrentSkipListMap.class,
+                                                        new ReduceAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
+
+        // Single-level map-reduce
+        exerciseMapTabulation(data,
+                              groupingBy(classifier, reducing(0, mDoubler, Integer::sum)),
+                              new GroupedMapAssertion<>(classifier, HashMap.class,
+                                                        new ReduceAssertion<>(0, mDoubler, Integer::sum)));
+        // with concurrent
+        exerciseMapTabulation(data,
+                              groupingByConcurrent(classifier, reducing(0, mDoubler, Integer::sum)),
+                              new GroupedMapAssertion<>(classifier, ConcurrentHashMap.class,
+                                                        new ReduceAssertion<>(0, mDoubler, Integer::sum)));
+
+        // With explicit constructors
+        exerciseMapTabulation(data,
+                              groupingBy(classifier, TreeMap::new, reducing(0, mDoubler, Integer::sum)),
+                              new GroupedMapAssertion<>(classifier, TreeMap.class,
+                                                        new ReduceAssertion<>(0, mDoubler, Integer::sum)));
+        // with concurrent
+        exerciseMapTabulation(data,
+                              groupingByConcurrent(classifier, ConcurrentSkipListMap::new, reducing(0, mDoubler, Integer::sum)),
+                              new GroupedMapAssertion<>(classifier, ConcurrentSkipListMap.class,
+                                                        new ReduceAssertion<>(0, mDoubler, Integer::sum)));
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testSimplePartition(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
+        Predicate<Integer> classifier = i -> i % 3 == 0;
+
+        // Single-level partition to downstream List
+        exerciseMapTabulation(data,
+                              partitioningBy(classifier),
+                              new PartitionAssertion<>(classifier, new ListAssertion<>()));
+        exerciseMapTabulation(data,
+                              partitioningBy(classifier, toList()),
+                              new PartitionAssertion<>(classifier, new ListAssertion<>()));
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testTwoLevelPartition(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
+        Predicate<Integer> classifier = i -> i % 3 == 0;
+        Predicate<Integer> classifier2 = i -> i % 7 == 0;
+
+        // Two level partition
+        exerciseMapTabulation(data,
+                              partitioningBy(classifier, partitioningBy(classifier2)),
+                              new PartitionAssertion<>(classifier,
+                                                       new PartitionAssertion(classifier2, new ListAssertion<>())));
+
+        // Two level partition with reduce
+        exerciseMapTabulation(data,
+                              partitioningBy(classifier, reducing(0, Integer::sum)),
+                              new PartitionAssertion<>(classifier,
+                                                       new ReduceAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TeeOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TeeOpTest.java
new file mode 100644
index 0000000..777158f
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TeeOpTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import java.util.function.Consumer;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+import java.util.stream.*;
+
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static java.util.stream.LambdaTestHelpers.*;
+
+/**
+ * TeeOpTest
+ */
+@Test(groups = { "serialization-hostile" })
+public class TeeOpTest extends OpTestCase {
+
+    public void testTee() {
+        List<Integer> copy = new ArrayList<>();
+
+        assertCountSum(countTo(0).stream().peek(copy::add), 0, 0);
+        assertCountSum(copy.iterator(), 0, 0);
+
+        copy.clear();
+        assertCountSum(countTo(10).stream().peek(copy::add), 10, 55);
+        assertCountSum(copy.iterator(), 10, 55);
+
+        copy.clear();
+        assertCountSum(countTo(10).stream().map(mDoubler).peek(copy::add), 10, 110);
+        assertCountSum(copy.iterator(), 10, 110);
+    }
+
+    static class AbstractRecordingConsumer<T> {
+        List<T> list;
+
+        void before(TestData<T, ?> td) {
+            // Tee block can be called concurrently
+            list = Collections.synchronizedList(new ArrayList<>());
+        }
+
+        void after(TestData<T, ?> td) {
+            // No guarantees in parallel tests that calls to tee block will
+            // be in the encounter order, if defined, of the data
+            // @@@ Consider passing more meta-data about evaluation
+            assertContentsUnordered(list, td.into(new ArrayList<T>()));
+        }
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testOps(String name, final TestData.OfRef<Integer> data) {
+        class RecordingConsumer extends AbstractRecordingConsumer<Integer> implements Consumer<Integer> {
+            public void accept(Integer t) {
+                list.add(t);
+            }
+        }
+        final RecordingConsumer b = new RecordingConsumer();
+
+        withData(data)
+                .stream(s -> s.peek(b))
+                .before(b::before)
+                .after(b::after)
+                .exercise();
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntOps(String name, final TestData.OfInt data) {
+        class RecordingConsumer extends AbstractRecordingConsumer<Integer> implements IntConsumer {
+            public void accept(int t) {
+                list.add(t);
+            }
+        }
+        final RecordingConsumer b = new RecordingConsumer();
+
+        withData(data)
+                .stream(s -> s.peek(b))
+                .before(b::before)
+                .after(b::after)
+                .exercise();
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongOps(String name, final TestData.OfLong data) {
+        class RecordingConsumer extends AbstractRecordingConsumer<Long> implements LongConsumer {
+            public void accept(long t) {
+                list.add(t);
+            }
+        }
+        final RecordingConsumer b = new RecordingConsumer();
+
+        withData(data)
+                .stream(s -> s.peek(b))
+                .before(b::before)
+                .after(b::after)
+                .exercise();
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleOps(String name, final TestData.OfDouble data) {
+        class RecordingConsumer extends AbstractRecordingConsumer<Double> implements DoubleConsumer {
+            public void accept(double t) {
+                list.add(t);
+            }
+        }
+        final RecordingConsumer b = new RecordingConsumer();
+
+        withData(data)
+                .stream(s -> s.peek(b))
+                .before(b::before)
+                .after(b::after)
+                .exercise();
+    }
+}
diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ToArrayOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ToArrayOpTest.java
new file mode 100644
index 0000000..0971e89
--- /dev/null
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ToArrayOpTest.java
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.*;
+
+import static java.util.stream.LambdaTestHelpers.*;
+
+
+/**
+ * ToArrayOpTest
+ *
+ */
+@Test
+public class ToArrayOpTest extends OpTestCase {
+
+    public void testToArray() {
+        assertCountSum(Arrays.asList(countTo(0).stream().toArray()), 0, 0);
+        assertCountSum(Arrays.asList(countTo(10).stream().toArray()), 10, 55);
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfRef<Integer> data) {
+        exerciseTerminalOps(data, s -> s.toArray());
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testOpsWithMap(String name, TestData.OfRef<Integer> data) {
+        // Retain the size of the source
+        // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
+
+        Object[] objects = exerciseTerminalOps(data, s -> s.map(i -> (Integer) (i + i)), s -> s.toArray());
+        assertTrue(objects.length == data.size());
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testOpsWithSorted(String name, TestData.OfRef<Integer> data) {
+        // Retain the size of the source
+        // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
+
+        Object[] objects = exerciseTerminalOps(data, s -> s.sorted(), s -> s.toArray());
+        assertTrue(objects.length == data.size());
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testOpsWithFlatMap(String name, TestData.OfRef<Integer> data) {
+        // Double the size of the source
+        // Fixed size optimizations will not be used
+
+        Object[] objects = exerciseTerminalOps(data,
+                                               s -> s.flatMap(e -> Arrays.stream(new Object[] { e, e })),
+                                               s -> s.toArray());
+        assertTrue(objects.length == data.size() * 2);
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testOpsWithFilter(String name, TestData.OfRef<Integer> data) {
+        // Reduce the size of the source
+        // Fixed size optimizations will not be used
+
+        exerciseTerminalOps(data, s -> s.filter(LambdaTestHelpers.pEven), s -> s.toArray());
+    }
+
+    public void testAsArrayWithType() {
+        exerciseTerminalOps(
+                TestData.Factory.ofCollection("", Arrays.asList(1.1, 2.2, 3.4, 4.4)),
+                s -> // First pipeline slice using Object[] with Double elements
+                    s.sorted()
+                    // Second pipeline slice using Integer[] with Integer elements
+                    .map((Double d) -> Integer.valueOf(d.intValue())).sorted(),
+                s -> s.toArray(Integer[]::new));
+    }
+
+    private List<Function<Stream<Integer>, Stream<Integer>>> uniqueAndSortedPermutations =
+            LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
+                    s -> s.distinct(),
+                    s -> s.distinct(),
+                    s -> s.sorted(),
+                    s -> s.sorted()
+            ));
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testDistinctAndSortedPermutations(String name, TestData.OfRef<Integer> data) {
+        for (Function<Stream<Integer>, Stream<Integer>> f : uniqueAndSortedPermutations) {
+            exerciseTerminalOps(data, f, s -> s.toArray());
+
+            Integer[] is = exerciseTerminalOps(data, f, s -> s.toArray(Integer[]::new));
+            assertEquals(is.getClass(), Integer[].class);
+
+            Number[] ns = exerciseTerminalOps(data, f, s -> s.toArray(Number[]::new));
+            assertEquals(ns.getClass(), Number[].class);
+
+            if (data.size() > 0) {
+                Exception caught = null;
+                try {
+                    exerciseTerminalOps(data, f, s -> s.toArray(String[]::new));
+                } catch (Exception e) {
+                    caught = e;
+                }
+                assertTrue(caught != null);
+                assertEquals(caught.getClass(), ArrayStoreException.class);
+            }
+        }
+    }
+
+    private List<Function<Stream<Integer>, Stream<Integer>>> statefulOpPermutations =
+            LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
+                    s -> s.limit(10),
+                    s -> s.distinct(),
+                    s -> s.sorted()
+            ));
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testStatefulOpPermutations(String name, TestData.OfRef<Integer> data) {
+        for (Function<Stream<Integer>, Stream<Integer>> f : statefulOpPermutations) {
+            exerciseTerminalOps(data, f, s -> s.toArray());
+
+            Integer[] is = exerciseTerminalOps(data, f, s -> s.toArray(Integer[]::new));
+            assertEquals(is.getClass(), Integer[].class);
+
+            Number[] ns = exerciseTerminalOps(data, f, s -> s.toArray(Number[]::new));
+            assertEquals(ns.getClass(), Number[].class);
+
+            if (data.size() > 0) {
+                Exception caught = null;
+                try {
+                    exerciseTerminalOps(data, f, s -> s.toArray(String[]::new));
+                } catch (Exception e) {
+                    caught = e;
+                }
+                assertTrue(caught != null);
+                assertEquals(caught.getClass(), ArrayStoreException.class);
+            }
+        }
+    }
+
+    //
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntOps(String name, TestData.OfInt data) {
+        exerciseTerminalOps(data, s -> s.toArray());
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntOpsWithMap(String name, TestData.OfInt data) {
+        // Retain the size of the source
+        // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
+
+        int[] ints = exerciseTerminalOps(data, s -> s.map(i -> i + i), s -> s.toArray());
+        assertTrue(ints.length == data.size());
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntOpsWithSorted(String name, TestData.OfInt data) {
+        // Retain the size of the source
+        // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
+
+        int[] ints = exerciseTerminalOps(data, s -> s.sorted(), (IntStream s) -> s.toArray());
+        assertTrue(ints.length == data.size());
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntOpsWithFlatMap(String name, TestData.OfInt data) {
+        // Int the size of the source
+        // Fixed size optimizations will not be used
+
+        int[] objects = exerciseTerminalOps(data,
+                                               s -> s.flatMap(e -> Arrays.stream(new int[] { e, e })),
+                                               s -> s.toArray());
+        assertTrue(objects.length == data.size() * 2);
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntOpsWithFilter(String name, TestData.OfInt data) {
+        // Reduce the size of the source
+        // Fixed size optimizations will not be used
+
+        exerciseTerminalOps(data, s -> s.filter(LambdaTestHelpers.ipEven), s -> s.toArray());
+    }
+
+    private List<Function<IntStream, IntStream>> intUniqueAndSortedPermutations =
+            LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
+                    s -> s.distinct(),
+                    s -> s.distinct(),
+                    s -> s.sorted(),
+                    s -> s.sorted()
+            ));
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntDistinctAndSortedPermutations(String name, TestData.OfInt data) {
+        for (Function<IntStream, IntStream> f : intUniqueAndSortedPermutations) {
+            exerciseTerminalOps(data, f, s -> s.toArray());
+        }
+    }
+
+    private List<Function<IntStream, IntStream>> intStatefulOpPermutations =
+            LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
+                    s -> s.limit(10),
+                    s -> s.distinct(),
+                    s -> s.sorted()
+            ));
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntStatefulOpPermutations(String name, TestData.OfInt data) {
+        for (Function<IntStream, IntStream> f : intStatefulOpPermutations) {
+            exerciseTerminalOps(data, f, s -> s.toArray());
+        }
+    }
+
+    //
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongOps(String name, TestData.OfLong data) {
+        exerciseTerminalOps(data, s -> s.toArray());
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongOpsWithMap(String name, TestData.OfLong data) {
+        // Retain the size of the source
+        // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
+
+        long[] longs = exerciseTerminalOps(data, s -> s.map(i -> i + i), s -> s.toArray());
+        assertTrue(longs.length == data.size());
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongOpsWithSorted(String name, TestData.OfLong data) {
+        // Retain the size of the source
+        // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
+
+        long[] longs = exerciseTerminalOps(data, s -> s.sorted(), (LongStream s) -> s.toArray());
+        assertTrue(longs.length == data.size());
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongOpsWithFlatMap(String name, TestData.OfLong data) {
+        // Long the size of the source
+        // Fixed size optimizations will not be used
+
+        long[] objects = exerciseTerminalOps(data,
+                                               s -> s.flatMap(e -> Arrays.stream(new long[] { e, e })),
+                                               s -> s.toArray());
+        assertTrue(objects.length == data.size() * 2);
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongOpsWithFilter(String name, TestData.OfLong data) {
+        // Reduce the size of the source
+        // Fixed size optimizations will not be used
+
+        exerciseTerminalOps(data, s -> s.filter(LambdaTestHelpers.lpEven), s -> s.toArray());
+    }
+
+    private List<Function<LongStream, LongStream>> longUniqueAndSortedPermutations =
+            LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
+                    s -> s.distinct(),
+                    s -> s.distinct(),
+                    s -> s.sorted(),
+                    s -> s.sorted()
+            ));
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongDistinctAndSortedPermutations(String name, TestData.OfLong data) {
+        for (Function<LongStream, LongStream> f : longUniqueAndSortedPermutations) {
+            exerciseTerminalOps(data, f, s -> s.toArray());
+        }
+    }
+
+    private List<Function<LongStream, LongStream>> longStatefulOpPermutations =
+            LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
+                    s -> s.limit(10),
+                    s -> s.distinct(),
+                    s -> s.sorted()
+            ));
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongStatefulOpPermutations(String name, TestData.OfLong data) {
+        for (Function<LongStream, LongStream> f : longStatefulOpPermutations) {
+            exerciseTerminalOps(data, f, s -> s.toArray());
+        }
+    }
+
+    //
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleOps(String name, TestData.OfDouble data) {
+        exerciseTerminalOps(data, s -> s.toArray());
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleOpsWithMap(String name, TestData.OfDouble data) {
+        // Retain the size of the source
+        // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
+
+        double[] doubles = exerciseTerminalOps(data, s -> s.map(i -> i + i), s -> s.toArray());
+        assertTrue(doubles.length == data.size());
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleOpsWithSorted(String name, TestData.OfDouble data) {
+        // Retain the size of the source
+        // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
+
+        double[] doubles = exerciseTerminalOps(data, s -> s.sorted(), (DoubleStream s) -> s.toArray());
+        assertTrue(doubles.length == data.size());
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleOpsWithFlatMap(String name, TestData.OfDouble data) {
+        // Double the size of the source
+        // Fixed size optimizations will not be used
+
+        double[] objects = exerciseTerminalOps(data,
+                                               s -> s.flatMap(e -> Arrays.stream(new double[] { e, e })),
+                                               s -> s.toArray());
+        assertTrue(objects.length == data.size() * 2);
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleOpsWithFilter(String name, TestData.OfDouble data) {
+        // Reduce the size of the source
+        // Fixed size optimizations will not be used
+
+        exerciseTerminalOps(data, s -> s.filter(LambdaTestHelpers.dpEven), s -> s.toArray());
+    }
+
+    private List<Function<DoubleStream, DoubleStream>> doubleUniqueAndSortedPermutations =
+            LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
+                    s -> s.distinct(),
+                    s -> s.distinct(),
+                    s -> s.sorted(),
+                    s -> s.sorted()
+            ));
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleDistinctAndSortedPermutations(String name, TestData.OfDouble data) {
+        for (Function<DoubleStream, DoubleStream> f : doubleUniqueAndSortedPermutations) {
+            exerciseTerminalOps(data, f, s -> s.toArray());
+        }
+    }
+
+    private List<Function<DoubleStream, DoubleStream>> doubleStatefulOpPermutations =
+            LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
+                    s -> s.limit(10),
+                    s -> s.distinct(),
+                    s -> s.sorted()
+            ));
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleStatefulOpPermutations(String name, TestData.OfDouble data) {
+        for (Function<DoubleStream, DoubleStream> f : doubleStatefulOpPermutations) {
+            exerciseTerminalOps(data, f, s -> s.toArray());
+        }
+    }
+}
diff --git a/jdk/test/java/util/zip/GZIP/GZIPInZip.java b/jdk/test/java/util/zip/GZIP/GZIPInZip.java
new file mode 100644
index 0000000..558ad96
--- /dev/null
+++ b/jdk/test/java/util/zip/GZIP/GZIPInZip.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 7021870
+ * @summary Reading last gzip chain member must not close the input stream
+ */
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+
+public class GZIPInZip {
+
+    private static volatile Throwable trouble;
+
+    public static void main(String[] args) throws Throwable {
+
+        final PipedOutputStream pos = new PipedOutputStream();
+        final PipedInputStream pis = new PipedInputStream(pos);
+
+        Thread compressor = new Thread() {
+            public void run() {
+                final byte[] xbuf = { 'x' };
+                try {
+                    ZipOutputStream zos = new ZipOutputStream(pos);
+
+                    zos.putNextEntry(new ZipEntry("a.gz"));
+                    GZIPOutputStream gos1 = new GZIPOutputStream(zos);
+                    gos1.write(xbuf); gos1.finish();
+                    zos.closeEntry();
+
+                    zos.putNextEntry(new ZipEntry("b.gz"));
+                    GZIPOutputStream gos2 = new GZIPOutputStream(zos);
+                    gos2.write(xbuf); gos2.finish();
+                    zos.closeEntry();
+
+                } catch (Throwable t) {
+                    trouble = t;
+                }
+            }
+        };
+
+        Thread uncompressor = new Thread() {
+            public void run() {
+                try {
+                    ZipInputStream zis = new ZipInputStream(pis);
+                    zis.getNextEntry();
+                    InputStream gis = new GZIPInputStream(zis);
+                    // try to read more than the entry has
+                    gis.skip(2);
+
+                    try {
+                        zis.getNextEntry();
+                    } catch (IOException e) {
+                        throw new AssertionError("ZIP stream was prematurely closed");
+                    }
+
+                } catch (Throwable t) {
+                    trouble = t;
+                }
+            }
+        };
+
+        compressor.start(); uncompressor.start();
+        compressor.join();  uncompressor.join();
+
+        if (trouble != null)
+            throw trouble;
+    }
+}
diff --git a/jdk/test/java/util/zip/ZipFile/StreamZipEntriesTest.java b/jdk/test/java/util/zip/ZipFile/StreamZipEntriesTest.java
new file mode 100644
index 0000000..38199e4
--- /dev/null
+++ b/jdk/test/java/util/zip/ZipFile/StreamZipEntriesTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @run testng StreamZipEntriesTest
+ * @summary Make sure we can stream entries of a zip file.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.Object;
+import java.lang.System;
+import java.util.jar.JarFile;
+import java.util.jar.JarEntry;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+public class StreamZipEntriesTest {
+
+    @Test
+    public void testStreamZip() throws IOException {
+        try (ZipFile zf = new ZipFile(new File(System.getProperty("test.src", "."), "input.zip"))) {
+            zf.stream().forEach(e -> assertTrue(e instanceof ZipEntry));
+            zf.stream().forEach(e -> assertEquals(e.toString(), "ReadZip.java"));
+
+            Object elements[] = zf.stream().toArray();
+            assertEquals(1, elements.length);
+            assertEquals(elements[0].toString(), "ReadZip.java");
+        }
+    }
+
+    @Test
+    public void testStreamJar() throws IOException {
+        try (JarFile jf = new JarFile(new File(System.getProperty("test.src", "."), "input.jar"))) {
+            jf.stream().forEach(e -> assertTrue(e instanceof JarEntry));
+
+            Object elements[] = jf.stream().toArray();
+            assertEquals(3, elements.length);
+            assertEquals(elements[0].toString(), "META-INF/");
+            assertEquals(elements[1].toString(), "META-INF/MANIFEST.MF");
+            assertEquals(elements[2].toString(), "ReleaseInflater.java");
+        }
+    }
+
+    @Test
+    public void testClosedZipFile() throws IOException {
+        ZipFile zf = new ZipFile(new File(System.getProperty("test.src", "."), "input.zip"));
+        zf.close();
+        try {
+            Stream s = zf.stream();
+            fail("Should have thrown IllegalStateException");
+        } catch (IllegalStateException e) {
+            // expected;
+        }
+    }
+
+    @Test
+    public void testClosedJarFile() throws IOException {
+        JarFile jf = new JarFile(new File(System.getProperty("test.src", "."), "input.jar"));
+        jf.close();
+        try {
+            Stream s = jf.stream();
+            fail("Should have thrown IllegalStateException");
+        } catch (IllegalStateException e) {
+            // expected;
+        }
+    }
+}
diff --git a/jdk/test/javax/imageio/plugins/gif/GIFPassListenerTest.java b/jdk/test/javax/imageio/plugins/gif/GIFPassListenerTest.java
new file mode 100644
index 0000000..fac84d8
--- /dev/null
+++ b/jdk/test/javax/imageio/plugins/gif/GIFPassListenerTest.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4892259
+ *
+ * @summary Verify that calls to IIOReadUpdateListener passStarted and
+ * passComplete are consistent.
+ *
+ * @run main GIFPassListenerTest
+ */
+
+import java.awt.image.*;
+import java.io.*;
+import java.util.*;
+import javax.imageio.*;
+import javax.imageio.event.*;
+import javax.imageio.stream.*;
+
+public class GIFPassListenerTest {
+
+    private static ImageInputStream createTestImageStream(boolean progressive) throws IOException {
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
+        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("gif");
+        if (!writers.hasNext()) {
+            return null;
+        }
+        ImageWriter writer = writers.next();
+        ImageWriteParam param = writer.getDefaultWriteParam();
+        param.setProgressiveMode(progressive ?
+                ImageWriteParam.MODE_DEFAULT : ImageWriteParam.MODE_DISABLED);
+        ImageOutputStream imageOutput = ImageIO.createImageOutputStream(output);
+        writer.setOutput(imageOutput);
+        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
+        writer.write(null, new IIOImage(image, null, null), param);
+        imageOutput.flush();
+        ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
+        return ImageIO.createImageInputStream(input);
+    }
+
+    private static void checkImage(boolean progressive) throws Exception {
+        ImageInputStream iis = createTestImageStream(progressive);
+        ImageReader reader = ImageIO.getImageReaders(iis).next();
+        reader.setInput(iis);
+        ReadUpdateHandler handler = new ReadUpdateHandler();
+        reader.addIIOReadUpdateListener(handler);
+        reader.readAll(null);
+        if (handler.isPassStarted) {
+            throw new RuntimeException("passStarted without passComplete.");
+        }
+        if (progressive && (handler.numPasses == 0)) {
+            throw new RuntimeException("passStarted wasn't called for progressive image");
+        }
+        if (!progressive && (handler.numPasses != 0)) {
+            throw new RuntimeException("passStarted was called for non-progressive image");
+        }
+        iis.close();
+    }
+
+    public static void main(String args[]) throws Exception {
+        checkImage(true);
+        checkImage(false);
+    }
+
+    private static class ReadUpdateHandler implements IIOReadUpdateListener {
+        public boolean isPassStarted = false;
+        public int numPasses = 0;
+
+        @Override
+        public void imageUpdate(ImageReader source, BufferedImage theImage, int minX, int minY,
+                int width, int height, int periodX, int periodY, int[] bands) {
+        }
+
+        @Override
+        public void passStarted(ImageReader source, BufferedImage theImage, int pass, int minPass,
+                int maxPass, int minX, int minY, int periodX, int periodY, int[] bands) {
+            if (isPassStarted) {
+                throw new RuntimeException("reentered passStarted!");
+            }
+            isPassStarted = true;
+            numPasses++;
+        }
+
+        @Override
+        public void passComplete(ImageReader source, BufferedImage theImage) {
+            if (!isPassStarted) {
+                throw new RuntimeException("passComplete without passStarted!");
+            }
+            isPassStarted = false;
+        }
+
+        @Override
+        public void thumbnailPassStarted(ImageReader source, BufferedImage theThumbnail, int pass,
+                int minPass, int maxPass, int minX, int minY, int periodX, int periodY, int[] bands) {
+        }
+
+        @Override
+        public void thumbnailPassComplete(ImageReader source, BufferedImage theThumbnail) {
+        }
+
+        @Override
+        public void thumbnailUpdate(ImageReader source, BufferedImage theThumbnail, int minX, int minY,
+                int width, int height, int periodX, int periodY, int[] bands) {
+        }
+    }
+}
diff --git a/jdk/test/javax/management/remote/mandatory/connection/ConnectionTest.java b/jdk/test/javax/management/remote/mandatory/connection/ConnectionTest.java
index c375ca1..d26be3b 100644
--- a/jdk/test/javax/management/remote/mandatory/connection/ConnectionTest.java
+++ b/jdk/test/javax/management/remote/mandatory/connection/ConnectionTest.java
@@ -44,6 +44,7 @@
 import java.util.StringTokenizer;
 
 import java.security.Principal;
+import java.util.regex.Pattern;
 import javax.security.auth.Subject;
 
 import javax.management.MBeanServer;
@@ -239,6 +240,18 @@
         return true;
     }
 
+    private static final String IPV4_PTN = "^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}(\\:[1-9][0-9]{3})?$";
+
+    /**
+     * Checks the connection id for validity.
+     * The {@link
+     * javax.management.remote package description} describes the
+     * conventions for connection IDs.
+     * @param proto Connection protocol
+     * @param clientConnId The connection ID
+     * @return Returns {@code true} if the connection id conforms to the specification; {@code false} otherwise.
+     * @throws Exception
+     */
     private static boolean checkConnectionId(String proto, String clientConnId)
             throws Exception {
         StringTokenizer tok = new StringTokenizer(clientConnId, " ", true);
@@ -249,6 +262,17 @@
                                "\"");
             return false;
         }
+
+        int hostAddrInd = s.indexOf("//");
+        if (hostAddrInd > -1) {
+            s = s.substring(hostAddrInd + 2);
+            if (!Pattern.matches(IPV4_PTN, s)) {
+                if (!s.startsWith("[") || !s.endsWith("]")) {
+                    System.out.println("IPv6 address must be enclosed in \"[]\"");
+                    return false;
+                }
+            }
+        }
         s = tok.nextToken();
         if (!s.equals(" ")) {
             System.out.println("Expected \" \", found \"" + s + "\"");
diff --git a/jdk/test/javax/xml/jaxp/Encodings/CheckEncodingPropertiesFile.java b/jdk/test/javax/xml/jaxp/Encodings/CheckEncodingPropertiesFile.java
new file mode 100644
index 0000000..e8f0302
--- /dev/null
+++ b/jdk/test/javax/xml/jaxp/Encodings/CheckEncodingPropertiesFile.java
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8008738
+ * @summary checks that the mapping implemented by
+ *      com.sun.org.apache.xml.internal.serializer.Encodings
+ *      correctly identifies valid Charset names and
+ *      correctly maps them to their preferred mime names.
+ *      Also checks that the Encodings.properties resource file
+ *      is consistent.
+ * @compile -XDignore.symbol.file CheckEncodingPropertiesFile.java
+ * @run main CheckEncodingPropertiesFile
+ * @author Daniel Fuchs
+ */
+
+import com.sun.org.apache.xml.internal.serializer.EncodingInfo;
+import com.sun.org.apache.xml.internal.serializer.Encodings;
+import java.io.InputStreamReader;
+import java.lang.reflect.Method;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+public class CheckEncodingPropertiesFile {
+
+    private static final String ENCODINGS_FILE = "com/sun/org/apache/xml/internal/serializer/Encodings.properties";
+
+    public static void main(String[] args) throws Exception {
+        Properties props = new Properties();
+        try (InputStreamReader is = new InputStreamReader(ClassLoader.getSystemResourceAsStream(ENCODINGS_FILE))) {
+            props.load(is);
+        }
+
+        //printAllCharsets();
+
+        test(props);
+    }
+
+
+    private static final class CheckCharsetMapping {
+
+        /**
+         * A map that maps Java or XML name to canonical charset names.
+         * key:    upper cased value of Java or XML name.
+         * value:  case-sensitive canonical name of charset.
+         */
+        private final Map<String, String> charsetMap = new HashMap<>();
+
+        private final Map<String, String> preferredMime = new HashMap<>();
+
+        /**
+         * Unresolved alias names.
+         * For a given set of names pointing to the same unresolved charset,
+         * this map will contain, for each alias in the set, a mapping
+         * with the alias.toUpperValue() as key and the set of known aliases
+         * as value.
+         */
+        private final Map<String, Collection<String>> unresolved = new HashMap<>();
+
+        public final static class ConflictingCharsetError extends Error {
+            ConflictingCharsetError(String a, String cs1, String cs2) {
+                super("Conflicting charset mapping for '"+a+"': '"+cs1+"' and '"+cs2+"'");
+            }
+        }
+
+        public final static class MissingValidCharsetNameError extends Error {
+            MissingValidCharsetNameError(String name, Collection<String> aliases) {
+                super(name+": Line "+aliases+" has no recognized charset alias");
+            }
+        }
+
+        public final static class ConflictingPreferredMimeNameError extends Error {
+            ConflictingPreferredMimeNameError(String a, String cs1, String cs2) {
+                super("Conflicting preferred mime name for '"+a+"': '"+cs1+"' and '"+cs2+"'");
+            }
+        }
+
+        /**
+         * For each alias in aliases, attempt to find the canonical
+         * charset name.
+         * All names in aliases are supposed to point to the same charset.
+         * Names in aliases can be java names or XML names, indifferently.
+         * @param aliases list of names (aliases) for a given charset.
+         * @return The canonical name of the charset, if found, null otherwise.
+         */
+        private String findCharsetNameFor(String[] aliases) {
+            String cs = null;
+            String res = null;
+            for (String a : aliases) {
+                final String k = a.toUpperCase();
+                String cachedCs = charsetMap.get(k);
+                if (cs == null) {
+                    cs = cachedCs;
+                }
+                if (cachedCs != null && cs != null
+                        && !Charset.forName(cachedCs).name().equals(Charset.forName(cs).name())) {
+                    throw new ConflictingCharsetError(a,cs,cachedCs);
+                }
+                try {
+                    final String rcs = Charset.forName(a).name();
+                    if (cs != null && !Charset.forName(cs).name().equals(rcs)) {
+                        throw new ConflictingCharsetError(a,cs,rcs);
+                    }
+                    if (res == null) {
+                        if (a.equals(aliases[0])) {
+                            res = a;
+                        } else {
+                            res = cs;
+                        }
+                    }
+                    cs = rcs;
+                    charsetMap.put(k, res == null ? cs : res);
+                } catch (Exception x) {
+                    continue;
+                }
+            }
+            return res == null ? cs : res;
+        }
+
+        /**
+         * Register a canonical charset name for a given set of aliases.
+         *
+         * @param charsetName the canonical charset name.
+         * @param aliases a list of aliases for the given charset.
+         */
+        private void registerCharsetNameFor(String charsetName, String[] aliases) {
+            if (charsetName == null) throw new NullPointerException();
+
+            for (String a : aliases) {
+                String k = a.toUpperCase();
+                String csv = charsetMap.get(k);
+                if (csv == null) {
+                    charsetMap.put(k, charsetName);
+                    csv = charsetName;
+                } else if (!csv.equals(charsetName)) {
+                    throw new ConflictingCharsetError(a,charsetName,csv);
+                }
+
+                final Collection<String> c = unresolved.get(k);
+                if (c != null) {
+                    for (String aa : c) {
+                        k = aa.toUpperCase();
+                        String csvv = charsetMap.get(k);
+                        if (csvv == null) charsetMap.put(k, csv);
+                        unresolved.remove(k);
+                    }
+                    throw new MissingValidCharsetNameError(charsetName,c);
+                }
+            }
+        }
+
+        /**
+         * Register a set of aliases as being unresolved.
+         * @param names    the list of names - this should be what is returned by
+         *                 nameSet.toArray(new String[nameSet.size()])
+         * @param nameSet  the set of unresolved aliases.
+         */
+        private void registerUnresolvedNamesFor(String[] names, Collection<String> nameSet) {
+            // This is not necessarily an error: it could happen that some
+            //    charsets are simply not supported on some OS/Arch
+            System.err.println("Warning: unresolved charset names: '"+ nameSet
+                    + "' This is not necessarily an error "
+                    + "- this charset may not be supported on this platform.");
+            for (String a : names) {
+                final String k = a.toUpperCase();
+                final Collection<String> c = unresolved.get(k);
+                if (c != null) {
+                    //System.out.println("Found: "+a+" -> "+c);
+                    //System.out.println("\t merging "+ c + " with " + nameSet);
+                    nameSet.addAll(c);
+                    for (String aa : c) {
+                        unresolved.put(aa.toUpperCase(), nameSet);
+                    }
+                }
+                unresolved.put(k, nameSet);
+            }
+        }
+
+
+        /**
+         * Add a new charset name mapping
+         * @param javaName the (supposedly) java name of the charset.
+         * @param xmlNames a list of corresponding XML names for that charset.
+         */
+        void addMapping(String javaName, Collection<String> xmlNames) {
+            final LinkedHashSet<String> aliasNames = new LinkedHashSet<>();
+            aliasNames.add(javaName);
+            aliasNames.addAll(xmlNames);
+            final String[] aliases = aliasNames.toArray(new String[aliasNames.size()]);
+            final String cs = findCharsetNameFor(aliases);
+            if (cs != null) {
+                registerCharsetNameFor(cs, aliases);
+                if (xmlNames.size() > 0) {
+                    String preferred = xmlNames.iterator().next();
+                    String cachedPreferred = preferredMime.get(cs.toUpperCase());
+                    if (cachedPreferred != null && !cachedPreferred.equals(preferred)) {
+                        throw new ConflictingPreferredMimeNameError(cs, cachedPreferred, preferred);
+                    }
+                    preferredMime.put(cs.toUpperCase(), preferred);
+                }
+            } else {
+                registerUnresolvedNamesFor(aliases, aliasNames);
+            }
+        }
+
+        /**
+         * Returns the canonical name of the charset for the given Java or XML
+         * alias name.
+         * @param alias the alias name
+         * @return the canonical charset name - or null if unknown.
+         */
+        public String getCharsetNameFor(String alias) {
+            return charsetMap.get(alias.toUpperCase());
+        }
+
+    }
+
+    public static void test(Properties props) throws Exception {
+
+        // First, build a mapping from the properties read from the resource
+        // file.
+        // We're going to check the consistency of the resource file
+        // while building this mapping, and throw errors if the file
+        // does not meet our assumptions.
+        //
+        Map<String, Collection<String>> lines = new HashMap<>();
+        final CheckCharsetMapping mapping = new CheckCharsetMapping();
+
+        for (String key : props.stringPropertyNames()) {
+            Collection<String> values = getValues(props.getProperty(key));
+            lines.put(key, values);
+            mapping.addMapping(key, values);
+        }
+
+        // Then build maps of EncodingInfos, and print along debugging
+        // information that should help understand the content of the
+        // resource file and the mapping it defines.
+        //
+        Map<String, EncodingInfo> javaInfos = new HashMap<>(); // Map indexed by java names
+        Map<String, EncodingInfo> xmlMap = new HashMap<>();    // Map indexed by XML names
+        Map<String, String> preferred =
+                new HashMap<>(mapping.preferredMime);          // Java Name -> Preferred Mime Name
+        List<EncodingInfo> all = new ArrayList<>();            // unused...
+        for (Entry<String, Collection<String>> e : lines.entrySet()) {
+            final String charsetName = mapping.getCharsetNameFor(e.getKey());
+            if (charsetName == null) {
+                System.out.println("!! No charset for: "+e.getKey()+ " "+ e.getValue());
+                continue;
+            }
+            Charset c = Charset.forName(charsetName);
+            EncodingInfo info;
+            final String k = e.getKey().toUpperCase();
+            final String kc = charsetName.toUpperCase();
+            StringBuilder sb = new StringBuilder();
+            for (String xml : e.getValue()) {
+                final String kx = xml.toUpperCase();
+                info = xmlMap.get(kx);
+                if (info == null) {
+                    info = new EncodingInfo(xml, charsetName);
+                    System.out.println("** XML: "+xml+" -> "+charsetName);
+                    xmlMap.put(kx, info);
+                    all.add(info);
+                }
+                if (!javaInfos.containsKey(k)) {
+                    javaInfos.put(k, info);
+                    if (!preferred.containsKey(k)) {
+                        preferred.put(k, xml);
+                    }
+                    sb.append("** Java: ").append(k).append(" -> ")
+                            .append(xml).append(" (charset: ")
+                            .append(charsetName).append(")\n");
+                }
+                if (!javaInfos.containsKey(kc)) {
+                    if (!preferred.containsKey(kc)) {
+                        preferred.put(kc, xml);
+                    }
+                    javaInfos.put(kc, info);
+                    sb.append("** Java: ").append(kc).append(" -> ")
+                            .append(xml).append(" (charset: ")
+                            .append(charsetName).append(")\n");
+                }
+                if (!javaInfos.containsKey(c.name().toUpperCase())) {
+                    if (!preferred.containsKey(c.name().toUpperCase())) {
+                        preferred.put(c.name().toUpperCase(), xml);
+                    }
+                    javaInfos.put(c.name().toUpperCase(), info);
+                    sb.append("** Java: ").append(c.name().toUpperCase()).append(" -> ")
+                            .append(xml).append(" (charset: ")
+                            .append(charsetName).append(")\n");
+                }
+            }
+            if (sb.length() == 0) {
+                System.out.println("Nothing new for "+charsetName+": "+e.getKey()+" -> "+e.getValue());
+            } else {
+                System.out.print(sb);
+            }
+
+        }
+
+        // Now we're going to verify that Encodings.java has done its job
+        // correctly. We're going to ask Encodings to convert java names to mime
+        // names and mime names to java names - and verify that the returned
+        // java names do map to recognized charsets.
+        //
+        // We're also going to verify that Encodings has recorded the preferred
+        // mime name correctly.
+
+        Method m = Encodings.class.getDeclaredMethod("getMimeEncoding", String.class);
+        m.setAccessible(true);
+
+        Set<String> xNames = new HashSet<>();
+        Set<String> jNames = new HashSet<>();
+        for (String name: xmlMap.keySet()) {
+            final String javaName = checkConvertMime2Java(name);
+            checkPreferredMime(m, javaName, preferred);
+            jNames.add(javaName);
+            xNames.add(name);
+        }
+
+
+        for (String javaName : lines.keySet()) {
+            final String javaCharsetName = mapping.getCharsetNameFor(javaName.toUpperCase());
+            if (javaCharsetName == null) continue;
+            if (!jNames.contains(javaName)) {
+                checkPreferredMime(m, javaName, preferred);
+                jNames.add(javaName);
+            }
+            for (String xml : lines.get(javaName)) {
+                if (xNames.contains(xml)) continue;
+                final String jName = checkConvertMime2Java(xml);
+                xNames.add(xml);
+                if (jNames.contains(jName)) continue;
+                checkPreferredMime(m, jName, preferred);
+            }
+        }
+    }
+
+    private static String checkConvertMime2Java(String xml) {
+        final String jName = Encodings.convertMime2JavaEncoding(xml);
+        final String jCharsetName;
+        try {
+            jCharsetName = Charset.forName(jName).name();
+        } catch (Exception x) {
+            throw new Error("Unrecognized charset returned by Encodings.convertMime2JavaEncoding(\""+xml+"\")", x);
+        }
+        System.out.println("Encodings.convertMime2JavaEncoding(\""+xml+"\") = \""+jName+"\" ("+jCharsetName+")");
+        return jName;
+    }
+
+    private static void checkPreferredMime(Method m, String javaName, Map<String,String> preferred)
+            throws Exception {
+        final String mime = (String) m.invoke(null, javaName);
+        final String expected = preferred.get(javaName.toUpperCase());
+        if (Arrays.deepEquals(new String[] {mime}, new String[] {expected})) {
+            System.out.println("Encodings.getMimeEncoding(\""+javaName+"\") = \""+mime+"\"");
+        } else {
+            throw new Error("Bad preferred mime type for: '"+javaName+"': expected '"+
+                expected+"' but got '"+mime+"'");
+        }
+    }
+
+    private static Collection<String> getValues(String val) {
+        int pos = val.indexOf(' ');
+        if (pos < 0) {
+            return Collections.singletonList(val);
+        }
+        //lastPrintable =
+        //    Integer.decode(val.substring(pos).trim()).intValue();
+        StringTokenizer st =
+            new StringTokenizer(val.substring(0, pos), ",");
+        final List<String> values = new ArrayList<>(st.countTokens());
+        while (st.hasMoreTokens()) {
+            values.add(st.nextToken());
+        }
+        return values;
+    }
+
+    // can be called in main() to help debugging.
+    // Prints out all available charsets and their recognized aliases
+    // as returned by the Charset API.
+    private static void printAllCharsets() {
+        Map<String, Charset> all = Charset.availableCharsets();
+        System.out.println("\n=========================================\n");
+        for (String can : all.keySet()) {
+            System.out.println(can + ": " + all.get(can).aliases());
+        }
+    }
+}
diff --git a/jdk/test/javax/xml/jaxp/PrecisionDecimalDV/XPrecisionDecimalToString.java b/jdk/test/javax/xml/jaxp/PrecisionDecimalDV/XPrecisionDecimalToString.java
new file mode 100644
index 0000000..07f1e16
--- /dev/null
+++ b/jdk/test/javax/xml/jaxp/PrecisionDecimalDV/XPrecisionDecimalToString.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.reflect.Method;
+
+/**
+ * @test
+ * @bug 8013900
+ * @summary More warning compiling jaxp.
+ *   This test only test one of the methods used to implement hashCode()
+ *   in com.sun.org.apache.xerces.internal.impl.dv.xs.PrecisionDecimalDV$XPrecisionDecimal.
+ *   Since that method is private the test unfortunately needs to use reflection
+ *   to invoke the method.
+ * @run main XPrecisionDecimalToString
+ * @author Daniel Fuchs
+ */
+public class XPrecisionDecimalToString {
+
+    private static final String className =
+            "com.sun.org.apache.xerces.internal.impl.dv.xs.PrecisionDecimalDV$XPrecisionDecimal";
+    private static final String methodName = "canonicalToStringForHashCode";
+    private static final Class<?>[] signature = { String.class, String.class, int.class, int.class };
+    private static Method method;
+
+    // Invokes XPrecisionDecimal.canonicalToStringForHashCode through reflection,
+    // because the method is private...
+    //
+    // Construct a canonical String representation of this number
+    // for the purpose of deriving a hashCode value compliant with
+    // equals.
+    // The toString representation will be:
+    // NaN for NaN, INF for +infinity, -INF for -infinity, 0 for zero,
+    // and [1-9]\.[0-9]*[1-9]?(E[1-9][0-9]*)? for other numbers.
+    private static String canonicalToStringForHashCode(String ivalue, String fvalue, int sign, int pvalue) {
+        try {
+            if (method == null) {
+                Class<?> type = Class.forName(className);
+                method = type.getDeclaredMethod(methodName, signature);
+                method.setAccessible(true);
+            }
+        } catch (Exception x) {
+            throw new Error("Impossible to find '"+className+"."+methodName+"': "+ x, x);
+        }
+        try {
+            return (String) method.invoke(null, new Object[] {ivalue, fvalue, sign, pvalue} );
+        } catch(Exception x) {
+            throw new Error("Failed to invoke "+className+"."+methodName+"(\""+
+                    ivalue+"\", \""+fvalue+"\", "+sign+", "+pvalue+"): " +x, x);
+        }
+    }
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        test("123","7890",-1,0,"-1.23789E2");
+        test("0","007890",-1,0,"-7.89E-3");
+        test("123","7890",1,0,"1.23789E2");
+        test("0","007890",1,0,"7.89E-3");
+        test("123","7890",1,10,"1.23789E12");
+        test("0","007890",1,33,"7.89E30");
+        test("INF","",1,0,"INF");
+        test("INF","",-1,0,"-INF");
+        test("NaN","",0,0,"NaN");
+        test("0","",1,0,"0");
+        test("00000","00000",1,10,"0");
+        test("00000","00000",-1,10,"0");
+        test("00000","000001",-1,-10,"-1E-16");
+    }
+
+    private static void test(String ival, String fval, int sign, int pvalue, String expected) {
+        final String canonical = canonicalToStringForHashCode(ival, fval, sign, pvalue);
+        System.out.println((sign == -1 ? "-" : "") + ival +
+                ("INF".equals(ival) || "NaN".equals(ival) ? ""
+                 : ( "." + fval + "E" + pvalue))
+                + " => "+ canonical);
+        if (!expected.equals(canonical)) {
+            throw new Error("expected: "+expected+" got: "+ canonical);
+        }
+    }
+
+
+}
diff --git a/jdk/test/jdk/lambda/ArrayCtorRefTest.java b/jdk/test/jdk/lambda/ArrayCtorRefTest.java
new file mode 100644
index 0000000..7189fc4
--- /dev/null
+++ b/jdk/test/jdk/lambda/ArrayCtorRefTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+
+import java.util.function.IntFunction;
+import java.util.function.Supplier;
+
+import static org.testng.Assert.assertTrue;
+
+/**
+ * ArrayCtorRefTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class ArrayCtorRefTest {
+    interface ArrayMaker<T> {
+        public T[] make(int size);
+    }
+
+    private static<T> Supplier<T[]> emptyArrayFactory(ArrayMaker<T> maker) {
+        return () -> maker.make(0);
+    }
+
+    public void testLambda() {
+        ArrayMaker<String> am = i -> new String[i];
+        String[] arr = am.make(3);
+        arr[0] = "Foo";
+        assertTrue(arr instanceof String[]);
+        assertTrue(arr.length == 3);
+    }
+
+    public void testIntCtorRef() {
+        IntFunction<int[]> factory = int[]::new;
+        int[] arr = factory.apply(6);
+        assertTrue(arr.length == 6);
+    }
+
+    public void testLambdaInference() {
+        Supplier<Object[]> oF = emptyArrayFactory(i -> new Object[i]);
+        Supplier<String[]> sF = emptyArrayFactory(i -> new String[i]);
+        assertTrue(oF.get() instanceof Object[]);
+        assertTrue(sF.get() instanceof String[]);
+    }
+
+    public void testCtorRef() {
+        ArrayMaker<String> am = String[]::new;
+        String[] arr = am.make(3);
+        arr[0] = "Foo";
+        assertTrue(arr instanceof String[]);
+        assertTrue(arr.length == 3);
+    }
+}
diff --git a/jdk/test/jdk/lambda/FDTest.java b/jdk/test/jdk/lambda/FDTest.java
new file mode 100644
index 0000000..adda12a
--- /dev/null
+++ b/jdk/test/jdk/lambda/FDTest.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+import shapegen.*;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.util.Pair;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.DataProvider;
+import static org.testng.Assert.*;
+
+public class FDTest {
+
+    public enum TestKind {
+        POSITIVE,
+        NEGATIVE;
+
+        Collection<Hierarchy> getHierarchy(HierarchyGenerator hg) {
+            return this == POSITIVE ?
+                    hg.getOK() : hg.getErr();
+        }
+    }
+
+    public static JavaCompiler comp;
+    public static StandardJavaFileManager fm;
+
+    @BeforeSuite
+    static void init() {
+        // create default shared JavaCompiler - reused across multiple
+        // compilations
+
+        comp = ToolProvider.getSystemJavaCompiler();
+        fm = comp.getStandardFileManager(null, null, null);
+    }
+
+    public static void main(String[] args) throws Exception {
+        init();
+
+        for (Pair<TestKind,Hierarchy> fdtest : generateCases()) {
+            runTest(fdtest.fst, fdtest.snd, comp, fm);
+        }
+    }
+
+    @Test(dataProvider = "fdCases")
+    public void testOneCase(TestKind tk, Hierarchy hs)
+            throws Exception {
+        FDTest.runTest(tk, hs, comp, fm);
+    }
+
+    @DataProvider(name = "fdCases")
+    public Object[][] caseGenerator() {
+        List<Pair<TestKind, Hierarchy>> cases = generateCases();
+        Object[][] fdCases = new Object[cases.size()][];
+        for (int i = 0; i < cases.size(); ++i) {
+            fdCases[i] = new Object[2];
+            fdCases[i][0] = cases.get(i).fst;
+            fdCases[i][1] = cases.get(i).snd;
+        }
+        return fdCases;
+    }
+
+    public static List<Pair<TestKind, Hierarchy>> generateCases() {
+        ArrayList<Pair<TestKind,Hierarchy>> list = new ArrayList<>();
+        HierarchyGenerator hg = new HierarchyGenerator();
+        for (TestKind tk : TestKind.values()) {
+            for (Hierarchy hs : tk.getHierarchy(hg)) {
+                list.add(new Pair<>(tk, hs));
+            }
+        }
+        return list;
+    }
+
+    public static void runTest(TestKind tk, Hierarchy hs,
+            JavaCompiler comp, StandardJavaFileManager fm) throws Exception {
+        new FDTest(tk, hs).run(comp, fm);
+    }
+
+    TestKind tk;
+    Hierarchy hs;
+    DefenderTestSource source;
+    DiagnosticChecker diagChecker;
+
+    public FDTest() {}
+
+    FDTest(TestKind tk, Hierarchy hs) {
+        this.tk = tk;
+        this.hs = hs;
+        this.source = new DefenderTestSource();
+        this.diagChecker = new DiagnosticChecker();
+    }
+
+    void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
+        JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+                null, null, Arrays.asList(source));
+        try {
+            ct.analyze();
+        } catch (Throwable ex) {
+            fail("Error thrown when analyzing the following source:\n" + source.getCharContent(true));
+        }
+        check();
+    }
+
+    void check() {
+        boolean errorExpected = tk == TestKind.NEGATIVE;
+        if (errorExpected != diagChecker.errorFound) {
+            fail("problem in source: \n" +
+                 "\nerror found = " + diagChecker.errorFound +
+                 "\nerror expected = " + errorExpected +
+                 "\n" + dumpHierarchy() +
+                 "\n" + source.getCharContent(true));
+        }
+    }
+
+    String dumpHierarchy() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("root = " + hs.root + "\n");
+        for (ClassCase cc : hs.all) {
+            buf.append("  class name = " + cc.getName() + "\n");
+            buf.append("    class OK = " + cc.get_OK() + "\n");
+            buf.append("    prov = " + cc.get_mprov() + "\n");
+
+        }
+        return buf.toString();
+    }
+
+    class DefenderTestSource extends SimpleJavaFileObject {
+
+        String source;
+
+        public DefenderTestSource() {
+            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+            StringBuilder buf = new StringBuilder();
+            List<ClassCase> defaultRef = new ArrayList<>();
+            for (ClassCase cc : hs.all) {
+                Hierarchy.genClassDef(buf, cc, null, defaultRef);
+            }
+            source = buf.toString();
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return source;
+        }
+    }
+
+    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+        boolean errorFound;
+
+        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+            if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+                errorFound = true;
+            }
+        }
+    }
+}
diff --git a/jdk/test/jdk/lambda/LambdaTranslationCompoundSamTest.java b/jdk/test/jdk/lambda/LambdaTranslationCompoundSamTest.java
new file mode 100644
index 0000000..a8006b4
--- /dev/null
+++ b/jdk/test/jdk/lambda/LambdaTranslationCompoundSamTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * LambdaTranslationCompoundSamTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class LambdaTranslationCompoundSamTest {
+    interface Accepts<T> {
+        void accept(T t);
+    }
+
+    interface AcceptsInt {
+        void accept(int i);
+    }
+
+    interface A<T> extends Accepts<T> {
+
+        default void accept(int value) {
+            throw new IllegalStateException();
+        }
+
+        interface OfInt extends A<Integer>, AcceptsInt {
+            @Override
+            void accept(int value);
+
+            @Override
+            default void accept(Integer i) {
+                accept(i.intValue());
+            }
+        }
+    }
+
+    protected interface Target<T> extends A<T> {
+        public interface OfInt extends Target<Integer>, A.OfInt { }
+    }
+
+    public void testConversion() {
+        int[] result = new int[4];
+
+        Target<Integer> tb = (Integer i) -> { result[0] = i+1; };
+        tb.accept((Integer) 3);
+        assertEquals(4, result[0]);
+
+        Target.OfInt ti = (int i) -> { result[1] = i+1; };
+        ti.accept(7);
+        assertEquals(8, result[1]);
+    }
+}
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass3.java b/jdk/test/jdk/lambda/LambdaTranslationInInterface.java
similarity index 60%
copy from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass3.java
copy to jdk/test/jdk/lambda/LambdaTranslationInInterface.java
index fe2be5a..20505a4 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass3.java
+++ b/jdk/test/jdk/lambda/LambdaTranslationInInterface.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,34 +21,39 @@
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
 
-@GenerateNativeHeader
-public class TestClass3 {
-    public int tc3;
+/**
+ * @author Robert Field
+ */
 
-    public class Inner1 {
-        public int tc3i1;
+interface LTII {
 
-        public class Inner1A {
-            public int tc3i1i1a;
-        }
-
-        public class Inner1B {
-            public int tc3i1i1b;
-        }
+    interface ILsp1 {
+        String m();
     }
 
-    public class Inner2 {
-        public int tc321;
-
-        public class Inner2A {
-            public int tc3i2i2a;
-        }
-
-        public class Inner2B {
-            public int tc3i2i2b;
-        }
+    interface ILsp2 {
+        String m(String x);
     }
+
+    default ILsp1 t1() {
+        return () -> { return "yo"; };
+    }
+
+    default ILsp2 t2() {
+        return (x) -> { return "snur" + x; };
+    }
+
 }
 
+@Test
+public class LambdaTranslationInInterface implements LTII {
+
+    public void testLambdaInDefaultMethod() {
+        assertEquals(t1().m(), "yo");
+        assertEquals(t2().m("p"), "snurp");
+    }
+
+}
diff --git a/jdk/test/jdk/lambda/LambdaTranslationInnerConstructor.java b/jdk/test/jdk/lambda/LambdaTranslationInnerConstructor.java
new file mode 100644
index 0000000..17e6ad1
--- /dev/null
+++ b/jdk/test/jdk/lambda/LambdaTranslationInnerConstructor.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class LambdaTranslationInnerConstructor  {
+
+    public void testLambdaWithInnerConstructor() {
+        assertEquals(seq1().m().toString(), "Cbl:nada");
+        assertEquals(seq2().m("rats").toString(), "Cbl:rats");
+    }
+
+    Ib1 seq1() {
+        return () -> { return new Cbl(); };
+    }
+
+    Ib2 seq2() {
+        return (x) -> { return new Cbl(x); };
+    }
+
+    class Cbl {
+        String val;
+
+        Cbl() {
+            this.val = "nada";
+        }
+
+        Cbl(String z) {
+            this.val = z;
+        }
+
+        public String toString() {
+            return "Cbl:" + val;
+        }
+    }
+
+    interface Ib1 {
+        Object m();
+    }
+
+    interface Ib2 {
+        Object m(String x);
+    }
+}
\ No newline at end of file
diff --git a/jdk/test/jdk/lambda/LambdaTranslationTest1.java b/jdk/test/jdk/lambda/LambdaTranslationTest1.java
new file mode 100644
index 0000000..acfc904
--- /dev/null
+++ b/jdk/test/jdk/lambda/LambdaTranslationTest1.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.function.Consumer;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class LambdaTranslationTest1 extends LT1Sub {
+
+    String cntxt = "blah";
+
+    private static final ThreadLocal<Object> result = new ThreadLocal<>();
+
+    private static void setResult(Object s) { result.set(s); }
+    private static void appendResult(Object s) { result.set(result.get().toString() + s); }
+
+    private static void assertResult(String expected) {
+        assertEquals(result.get().toString(), expected);
+    }
+
+    static Integer count(String s) {
+        return s.length();
+    }
+
+    static int icount(String s) {
+        return s.length();
+    }
+
+    static void eye(Integer i) {
+        setResult(String.format("I:%d", i));
+    }
+
+    static void ieye(int i) {
+        setResult(String.format("i:%d", i));
+    }
+
+    static void deye(double d) {
+        setResult(String.format("d:%f", d));
+    }
+
+    public void testLambdas() {
+        Consumer<Object> b = t -> {setResult("Sink0::" + t);};
+        b.accept("Howdy");
+        assertResult("Sink0::Howdy");
+
+        Consumer<String> b1 = t -> {setResult("Sink1::" + t);};
+        b1.accept("Rowdy");
+        assertResult("Sink1::Rowdy");
+
+        for (int i = 5; i < 10; ++i) {
+            Consumer<Integer> b2 = t -> {setResult("Sink2::" + t);};
+            b2.accept(i);
+            assertResult("Sink2::" + i);
+        }
+
+        Consumer<Integer> b3 = t -> {setResult("Sink3::" + t);};
+        for (int i = 900; i > 0; i -= 100) {
+            b3.accept(i);
+            assertResult("Sink3::" + i);
+        }
+
+        cntxt = "blah";
+        Consumer<String> b4 = t -> {setResult(String.format("b4: %s .. %s", cntxt, t));};
+        b4.accept("Yor");
+        assertResult("b4: blah .. Yor");
+
+        String flaw = "flaw";
+        Consumer<String> b5 = t -> {setResult(String.format("b5: %s .. %s", flaw, t));};
+        b5.accept("BB");
+        assertResult("b5: flaw .. BB");
+
+        cntxt = "flew";
+        Consumer<String> b6 = t -> {setResult(String.format("b6: %s .. %s .. %s", t, cntxt, flaw));};
+        b6.accept("flee");
+        assertResult("b6: flee .. flew .. flaw");
+
+        Consumer<String> b7 = t -> {setResult(String.format("b7: %s %s", t, this.protectedSuperclassMethod()));};
+        b7.accept("this:");
+        assertResult("b7: this: instance:flew");
+
+        Consumer<String> b8 = t -> {setResult(String.format("b8: %s %s", t, super.protectedSuperclassMethod()));};
+        b8.accept("super:");
+        assertResult("b8: super: I'm the sub");
+
+        Consumer<String> b7b = t -> {setResult(String.format("b9: %s %s", t, protectedSuperclassMethod()));};
+        b7b.accept("implicit this:");
+        assertResult("b9: implicit this: instance:flew");
+
+        Consumer<Object> b10 = t -> {setResult(String.format("b10: new LT1Thing: %s", (new LT1Thing(t)).str));};
+        b10.accept("thing");
+        assertResult("b10: new LT1Thing: thing");
+
+        Consumer<Object> b11 = t -> {setResult(String.format("b11: %s", (new LT1Thing(t) {
+            String get() {
+                return "*" + str.toString() + "*";
+            }
+        }).get()));};
+        b11.accept(999);
+        assertResult("b11: *999*");
+    }
+
+    public void testMethodRefs() {
+        LT1IA ia = LambdaTranslationTest1::eye;
+        ia.doit(1234);
+        assertResult("I:1234");
+
+        LT1IIA iia = LambdaTranslationTest1::ieye;
+        iia.doit(1234);
+        assertResult("i:1234");
+
+        LT1IA da = LambdaTranslationTest1::deye;
+        da.doit(1234);
+        assertResult("d:1234.000000");
+
+        LT1SA a = LambdaTranslationTest1::count;
+        assertEquals((Integer) 5, a.doit("howdy"));
+
+        a = LambdaTranslationTest1::icount;
+        assertEquals((Integer) 6, a.doit("shower"));
+    }
+
+    public void testInner() throws Exception {
+        (new In()).doInner();
+    }
+
+    protected String protectedSuperclassMethod() {
+        return "instance:" + cntxt;
+    }
+
+    private class In {
+
+        private int that = 1234;
+
+        void doInner() {
+            Consumer<String> i4 = t -> {setResult(String.format("i4: %d .. %s", that, t));};
+            i4.accept("=1234");
+            assertResult("i4: 1234 .. =1234");
+
+            Consumer<String> i5 = t -> {setResult(""); appendResult(t); appendResult(t);};
+            i5.accept("fruit");
+            assertResult("fruitfruit");
+
+            cntxt = "human";
+            Consumer<String> b4 = t -> {setResult(String.format("b4: %s .. %s", cntxt, t));};
+            b4.accept("bin");
+            assertResult("b4: human .. bin");
+
+            final String flaw = "flaw";
+
+/**
+ Callable<String> c5 = () ->  "["+flaw+"]" ;
+ System.out.printf("c5: %s\n", c5.call() );
+ **/
+
+            Consumer<String> b5 = t -> {setResult(String.format("b5: %s .. %s", flaw, t));};
+            b5.accept("BB");
+            assertResult("b5: flaw .. BB");
+
+            cntxt = "borg";
+            Consumer<String> b6 = t -> {setResult(String.format("b6: %s .. %s .. %s", t, cntxt, flaw));};
+            b6.accept("flee");
+            assertResult("b6: flee .. borg .. flaw");
+
+            Consumer<String> b7b = t -> {setResult(String.format("b7b: %s %s", t, protectedSuperclassMethod()));};
+            b7b.accept("implicit outer this");
+            assertResult("b7b: implicit outer this instance:borg");
+
+            /**
+             Block<Object> b9 = t -> { System.out.printf("New: %s\n", (new LT1Thing(t)).str); };
+             b9.apply("thing");
+
+             Block<Object> ba = t -> { System.out.printf("Def: %s\n", (new LT1Thing(t) { String get() { return "*" + str.toString() +"*";}}).get() ); };
+             ba.apply(999);
+
+             */
+        }
+    }
+}
+
+class LT1Sub {
+    protected String protectedSuperclassMethod() {
+        return "I'm the sub";
+    }
+}
+
+class LT1Thing {
+    final Object str;
+
+    LT1Thing(Object s) {
+        str = s;
+    }
+}
+
+interface LT1SA {
+    Integer doit(String s);
+}
+
+interface LT1IA {
+    void doit(int i);
+}
+
+interface LT1IIA {
+    void doit(Integer i);
+}
+
diff --git a/jdk/test/jdk/lambda/LambdaTranslationTest2.java b/jdk/test/jdk/lambda/LambdaTranslationTest2.java
new file mode 100644
index 0000000..59263e5
--- /dev/null
+++ b/jdk/test/jdk/lambda/LambdaTranslationTest2.java
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * LambdaTranslationTest2 -- end-to-end smoke tests for lambda evaluation
+ */
+@Test
+public class LambdaTranslationTest2 {
+
+    final String dummy = "dummy";
+
+    public void testLambdas() {
+        Predicate<String> isEmpty = s -> s.isEmpty();
+        assertTrue(isEmpty.test(""));
+        assertTrue(!isEmpty.test("foo"));
+
+        Predicate<Object> oIsEmpty = s -> ((String) s).isEmpty();
+        assertTrue(oIsEmpty.test(""));
+        assertTrue(!oIsEmpty.test("foo"));
+
+        Predicate<Object> alwaysTrue = o -> true;
+        assertTrue(alwaysTrue.test(""));
+        assertTrue(alwaysTrue.test(null));
+
+        Predicate<Object> alwaysFalse = o -> false;
+        assertTrue(!alwaysFalse.test(""));
+        assertTrue(!alwaysFalse.test(null));
+
+        // tests local capture
+        String foo = "foo";
+        Predicate<String> equalsFoo = s -> s.equals(foo);
+        assertTrue(!equalsFoo.test(""));
+        assertTrue(equalsFoo.test("foo"));
+
+        // tests instance capture
+        Predicate<String> equalsDummy = s -> s.equals(dummy);
+        assertTrue(!equalsDummy.test(""));
+        assertTrue(equalsDummy.test("dummy"));
+
+        Function<Object, Object> ident = s -> s;
+
+        assertEquals("blarf", ident.apply("blarf"));
+        assertEquals("wooga", ident.apply("wooga"));
+        assertTrue("wooga" == ident.apply("wooga"));
+
+        // constant capture
+        Function<Object, Object> prefixer = s -> "p" + s;
+        assertEquals("pblarf", prefixer.apply("blarf"));
+        assertEquals("pwooga", prefixer.apply("wooga"));
+
+        // instance capture
+        Function<Object, Object> prefixer2 = s -> dummy + s;
+        assertEquals("dummyblarf", prefixer2.apply("blarf"));
+        assertEquals("dummywooga", prefixer2.apply("wooga"));
+    }
+
+    interface Supplier<T> {
+        T make();
+    }
+
+    interface StringFactory extends Supplier<String> { }
+
+    interface StringFactory2 extends Supplier<String> {
+        String make();
+    }
+
+    public void testBridges() {
+        Supplier<String> of = () -> "y";
+        Supplier<?> ef = () -> "z";
+
+        assertEquals("y", of.make());
+        assertEquals("y", ((Supplier<?>) of).make());
+        assertEquals("y", ((Supplier) of).make());
+
+        assertEquals("z", ef.make());
+        assertEquals("z", ((Supplier) ef).make());
+    }
+
+    public void testBridgesImplicitSpecialization() {
+        StringFactory sf = () -> "x";
+
+        assertEquals("x", sf.make());
+        assertEquals("x", ((Supplier<String>) sf).make());
+        assertEquals("x", ((Supplier<?>) sf).make());
+        assertEquals("x", ((Supplier) sf).make());
+    }
+
+    public void testBridgesExplicitSpecialization() {
+        StringFactory2 sf = () -> "x";
+
+        assertEquals("x", sf.make());
+        assertEquals("x", ((Supplier<String>) sf).make());
+        assertEquals("x", ((Supplier<?>) sf).make());
+        assertEquals("x", ((Supplier) sf).make());
+    }
+
+    public void testSuperCapture() {
+        class A {
+            String make() { return "x"; }
+        }
+
+        class B extends A {
+            void testSuperCapture() {
+                StringFactory sf = () -> super.make();
+                assertEquals("x", sf.make());
+            }
+        }
+
+        new B().testSuperCapture();
+    }
+
+    interface WidenD {
+        public String m(float a0, double a1);
+    }
+
+    interface WidenS {
+        public String m(byte a0, short a1);
+    }
+
+    interface WidenI {
+        public String m(byte a0, short a1, char a2, int a3);
+    }
+
+    interface WidenL {
+        public String m(byte a0, short a1, char a2, int a3, long a4);
+    }
+
+    interface Box {
+        public String m(byte a0, short a1, char a2, int a3, long a4, boolean a5, float a6, double a7);
+    }
+
+    static String pb(Byte a0, Short a1, Character a2, Integer a3, Long a4, Boolean a5, Float a6, Double a7) {
+        return String.format("b%d s%d c%c i%d j%d z%b f%f d%f", a0, a1, a2, a3, a4, a5, a6, a7);
+    }
+
+    static String pwI1(int a0, int a1, int a2, int a3) {
+        return String.format("b%d s%d c%d i%d", a0, a1, a2, a3);
+    }
+
+    static String pwI2(Integer a0, Integer a1, Integer a2, Integer a3) {
+        return String.format("b%d s%d c%d i%d", a0, a1, a2, a3);
+    }
+
+    static String pwL1(long a0, long a1, long a2, long a3, long a4) {
+        return String.format("b%d s%d c%d i%d j%d", a0, a1, a2, a3, a4);
+    }
+
+    static String pwL2(Long a0, Long a1, Long a2, Long a3, Long a4) {
+        return String.format("b%d s%d c%d i%d j%d", a0, a1, a2, a3, a4);
+    }
+
+    static String pwS1(short a0, short a1) {
+        return String.format("b%d s%d", a0, a1);
+    }
+
+    static String pwS2(Short a0, Short a1) {
+        return String.format("b%d s%d", a0, a1);
+    }
+
+    static String pwD1(double a0, double a1) {
+        return String.format("f%f d%f", a0, a1);
+    }
+
+    static String pwD2(Double a0, Double a1) {
+        return String.format("f%f d%f", a0, a1);
+    }
+
+    public void testPrimitiveWidening() {
+        WidenS ws1 = LambdaTranslationTest2::pwS1;
+        assertEquals("b1 s2", ws1.m((byte) 1, (short) 2));
+
+        WidenD wd1 = LambdaTranslationTest2::pwD1;
+        assertEquals("f1.000000 d2.000000", wd1.m(1.0f, 2.0));
+
+        WidenI wi1 = LambdaTranslationTest2::pwI1;
+        assertEquals("b1 s2 c3 i4", wi1.m((byte) 1, (short) 2, (char) 3, 4));
+
+        WidenL wl1 = LambdaTranslationTest2::pwL1;
+        assertEquals("b1 s2 c3 i4 j5", wl1.m((byte) 1, (short) 2, (char) 3, 4, 5L));
+
+        // @@@ TODO: clarify spec on widen+box conversion
+    }
+
+    interface Unbox {
+        public String m(Byte a0, Short a1, Character a2, Integer a3, Long a4, Boolean a5, Float a6, Double a7);
+    }
+
+    static String pu(byte a0, short a1, char a2, int a3, long a4, boolean a5, float a6, double a7) {
+        return String.format("b%d s%d c%c i%d j%d z%b f%f d%f", a0, a1, a2, a3, a4, a5, a6, a7);
+    }
+
+    public void testUnboxing() {
+        Unbox u = LambdaTranslationTest2::pu;
+        assertEquals("b1 s2 cA i4 j5 ztrue f6.000000 d7.000000", u.m((byte)1, (short) 2, 'A', 4, 5L, true, 6.0f, 7.0));
+    }
+
+    public void testBoxing() {
+        Box b = LambdaTranslationTest2::pb;
+        assertEquals("b1 s2 cA i4 j5 ztrue f6.000000 d7.000000", b.m((byte) 1, (short) 2, 'A', 4, 5L, true, 6.0f, 7.0));
+    }
+
+    static boolean cc(Object o) {
+        return ((String) o).equals("foo");
+    }
+
+    public void testArgCastingAdaptation() {
+        Predicate<String> p = LambdaTranslationTest2::cc;
+        assertTrue(p.test("foo"));
+        assertTrue(!p.test("bar"));
+    }
+
+    interface SonOfPredicate<T> extends Predicate<T> { }
+
+    public void testExtendsSAM() {
+        SonOfPredicate<String> p = s -> s.isEmpty();
+        assertTrue(p.test(""));
+        assertTrue(!p.test("foo"));
+    }
+
+    public void testConstructorRef() {
+        Supplier<List<String>> lf = ArrayList<String>::new;
+        List<String> list = lf.make();
+        assertTrue(list instanceof ArrayList);
+        assertTrue(list != lf.make());
+        list.add("a");
+        assertEquals("[a]", list.toString());
+    }
+
+    private static String privateMethod() {
+        return "private";
+    }
+
+    public void testPrivateMethodRef() {
+        Supplier<String> sf = LambdaTranslationTest2::privateMethod;
+        assertEquals("private", sf.make());
+    }
+
+    private interface PrivateIntf {
+        String make();
+    }
+
+    public void testPrivateIntf() {
+        PrivateIntf p = () -> "foo";
+        assertEquals("foo", p.make());
+    }
+
+    interface Op<T> {
+        public T op(T a, T b);
+    }
+
+    public void testBoxToObject() {
+        Op<Integer> maxer = Math::max;
+        for (int i=-100000; i < 100000; i += 100)
+            for (int j=-100000; j < 100000; j += 99) {
+                assertEquals((int) maxer.op(i,j), Math.max(i,j));
+            }
+    }
+
+    protected static String protectedMethod() {
+        return "protected";
+    }
+
+    public void testProtectedMethodRef() {
+        Supplier<String> sf = LambdaTranslationTest2::protectedMethod;
+        assertEquals("protected", sf.make());
+    }
+
+    class Inner1 {
+        String m1() {
+            return "Inner1.m1()";
+        }
+
+        class Inner2 {
+            public String m1() {
+                return "Inner1.Inner2.m1()";
+            }
+
+            protected String m2() {
+                return "Inner1.Inner2.m2()";
+            }
+
+            String m3() {
+                return "Inner1.Inner2.m3()";
+            }
+
+            class Inner3<T> {
+                T t = null;
+                Inner3(T t) {
+                    this.t = t;
+                }
+                T m1() {
+                    return t;
+                }
+            }
+        }
+    }
+
+    public void testInnerClassMethodRef() {
+        Supplier<String> fs = new Inner1()::m1;
+        assertEquals("Inner1.m1()", fs.make());
+
+        fs = new Inner1().new Inner2()::m1;
+        assertEquals("Inner1.Inner2.m1()", fs.make());
+
+        fs = new Inner1().new Inner2()::m2;
+        assertEquals("Inner1.Inner2.m2()", fs.make());
+
+        fs = new Inner1().new Inner2()::m3;
+        assertEquals("Inner1.Inner2.m3()", fs.make());
+
+        fs = new Inner1().new Inner2().new Inner3<String>("Inner1.Inner2.Inner3")::m1;
+        assertEquals("Inner1.Inner2.Inner3", fs.make());
+
+        Supplier<Integer> fsi = new Inner1().new Inner2().new Inner3<Integer>(100)::m1;
+        assertEquals(100, (int)fsi.make());
+    }
+}
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestFDCCE.java b/jdk/test/jdk/lambda/MethodReferenceTestFDCCE.java
new file mode 100644
index 0000000..dd5b2c8
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestFDCCE.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+import java.lang.reflect.Array;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+/**
+ * Method references and raw types.
+ * @author Robert Field
+ */
+
+@Test
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class MethodReferenceTestFDCCE {
+
+    static void assertCCE(Throwable t) {
+        assertEquals(t.getClass().getName(), "java.lang.ClassCastException");
+    }
+
+    interface Pred<T> { boolean accept(T x); }
+
+    interface Ps { boolean accept(short x); }
+
+    interface Oo { Object too(int x); }
+
+    interface Reto<T> { T m(); }
+
+    class A {}
+    class B extends A {}
+
+    static boolean isMinor(int x) {
+        return x < 18;
+    }
+
+    static boolean tst(A x) {
+        return true;
+    }
+
+    static Object otst(Object x) {
+        return x;
+    }
+
+    static boolean stst(Short x) {
+        return x < 18;
+    }
+
+    static short ritst() {
+        return 123;
+    }
+
+    public void testMethodReferenceFDPrim1() {
+        Pred<Byte> p = MethodReferenceTestFDCCE::isMinor;
+        Pred p2 = p;
+        assertTrue(p2.accept((Byte)(byte)15));
+    }
+
+    public void testMethodReferenceFDPrim2() {
+        Pred<Byte> p = MethodReferenceTestFDCCE::isMinor;
+        Pred p2 = p;
+        assertTrue(p2.accept((byte)15));
+    }
+
+    public void testMethodReferenceFDPrimICCE() {
+        Pred<Byte> p = MethodReferenceTestFDCCE::isMinor;
+        Pred p2 = p;
+        try {
+            p2.accept(15); // should throw CCE
+            fail("Exception should have been thrown");
+        } catch (Throwable t) {
+            assertCCE(t);
+        }
+    }
+
+    public void testMethodReferenceFDPrimOCCE() {
+        Pred<Byte> p = MethodReferenceTestFDCCE::isMinor;
+        Pred p2 = p;
+        try {
+            p2.accept(new Object()); // should throw CCE
+            fail("Exception should have been thrown");
+        } catch (Throwable t) {
+            assertCCE(t);
+        }
+    }
+
+    public void testMethodReferenceFDRef() {
+        Pred<B> p = MethodReferenceTestFDCCE::tst;
+        Pred p2 = p;
+        assertTrue(p2.accept(new B()));
+    }
+
+    public void testMethodReferenceFDRefCCE() {
+        Pred<B> p = MethodReferenceTestFDCCE::tst;
+        Pred p2 = p;
+        try {
+            p2.accept(new A()); // should throw CCE
+            fail("Exception should have been thrown");
+        } catch (Throwable t) {
+            assertCCE(t);
+        }
+    }
+
+    public void testMethodReferenceFDPrimPrim() {
+        Ps p = MethodReferenceTestFDCCE::isMinor;
+        assertTrue(p.accept((byte)15));
+    }
+
+    public void testMethodReferenceFDPrimBoxed() {
+        Ps p = MethodReferenceTestFDCCE::stst;
+        assertTrue(p.accept((byte)15));
+    }
+
+    public void testMethodReferenceFDPrimRef() {
+        Oo p = MethodReferenceTestFDCCE::otst;
+        assertEquals(p.too(15).getClass().getName(), "java.lang.Integer");
+    }
+
+    public void testMethodReferenceFDRet1() {
+        Reto<Short> p = MethodReferenceTestFDCCE::ritst;
+        assertEquals(p.m(), (Short)(short)123);
+    }
+
+}
\ No newline at end of file
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestInnerDefault.java b/jdk/test/jdk/lambda/MethodReferenceTestInnerDefault.java
new file mode 100644
index 0000000..ea9a76d
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestInnerDefault.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+interface IDSs { String m(String a); }
+
+interface InDefA {
+    default String xsA__(String s) {
+        return "A__xsA:" + s;
+    }
+
+    default String xsAB_(String s) {
+        return "AB_xsA:" + s;
+    }
+
+}
+
+interface InDefB extends InDefA {
+
+    default String xsAB_(String s) {
+        return "AB_xsB:" + s;
+    }
+
+    default String xs_B_(String s) {
+        return "_B_xsB:" + s;
+    }
+}
+
+@Test
+public class MethodReferenceTestInnerDefault implements InDefB {
+
+    public void testMethodReferenceInnerDefault() {
+        (new In()).testMethodReferenceInnerDefault();
+    }
+
+    class In {
+
+        public void testMethodReferenceInnerDefault() {
+            IDSs q;
+
+            q = MethodReferenceTestInnerDefault.this::xsA__;
+            assertEquals(q.m("*"), "A__xsA:*");
+
+            q = MethodReferenceTestInnerDefault.this::xsAB_;
+            assertEquals(q.m("*"), "AB_xsB:*");
+
+            q = MethodReferenceTestInnerDefault.this::xs_B_;
+            assertEquals(q.m("*"), "_B_xsB:*");
+        }
+    }
+
+}
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestInnerInstance.java b/jdk/test/jdk/lambda/MethodReferenceTestInnerInstance.java
new file mode 100644
index 0000000..2aa1526
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestInnerInstance.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class MethodReferenceTestInnerInstance {
+
+    public void testMethodReferenceInnerInstance() {
+        cia().cib().testMethodReferenceInstance();
+    }
+
+    public void testMethodReferenceInnerExternal() {
+        cia().cib().testMethodReferenceExternal();
+    }
+
+    interface SI {
+        String m(Integer a);
+    }
+
+    class CIA {
+
+        String xI(Integer i) {
+            return "xI:" + i;
+        }
+
+        public class CIB {
+
+            public void testMethodReferenceInstance() {
+                SI q;
+
+                q = CIA.this::xI;
+                assertEquals(q.m(55), "xI:55");
+            }
+
+            public void testMethodReferenceExternal() {
+                SI q;
+
+                q = (new E())::xI;
+                assertEquals(q.m(77), "ExI:77");
+            }
+        }
+
+        CIB cib() {
+            return new CIB();
+        }
+
+        class E {
+
+            String xI(Integer i) {
+                return "ExI:" + i;
+            }
+        }
+
+    }
+
+    CIA cia() {
+        return new CIA();
+    }
+}
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestInnerVarArgsThis.java b/jdk/test/jdk/lambda/MethodReferenceTestInnerVarArgsThis.java
new file mode 100644
index 0000000..06c58dc
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestInnerVarArgsThis.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+import java.lang.reflect.Array;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class MethodReferenceTestInnerVarArgsThis {
+
+    interface NsII {
+
+        String m(Integer a, Integer b);
+    }
+
+    interface Nsiii {
+
+        String m(int a, int b, int c);
+    }
+
+    interface Nsi {
+
+        String m(int a);
+    }
+
+    interface NsaO {
+
+        String m(Object[] a);
+    }
+
+    interface Nsai {
+
+        String m(int[] a);
+    }
+
+    interface Nsvi {
+
+        String m(int... va);
+    }
+
+    class CIA {
+
+        String xvI(Integer... vi) {
+            StringBuilder sb = new StringBuilder("xvI:");
+            for (Integer i : vi) {
+                sb.append(i);
+                sb.append("-");
+            }
+            return sb.toString();
+        }
+
+        String xIvI(Integer f, Integer... vi) {
+            StringBuilder sb = new StringBuilder("xIvI:");
+            sb.append(f);
+            for (Integer i : vi) {
+                sb.append(i);
+                sb.append("-");
+            }
+            return sb.toString();
+        }
+
+        String xvi(int... vi) {
+            int sum = 0;
+            for (int i : vi) {
+                sum += i;
+            }
+            return "xvi:" + sum;
+        }
+
+        String xIvi(Integer f, int... vi) {
+            int sum = 0;
+            for (int i : vi) {
+                sum += i;
+            }
+            return "xIvi:(" + f + ")" + sum;
+        }
+
+        String xvO(Object... vi) {
+            StringBuilder sb = new StringBuilder("xvO:");
+            for (Object i : vi) {
+                if (i.getClass().isArray()) {
+                    sb.append("[");
+                    int len = Array.getLength(i);
+                    for (int x = 0; x < len; ++x) {
+                        sb.append(Array.get(i, x));
+                        sb.append(",");
+                    }
+                    sb.append("]");
+
+                } else {
+                    sb.append(i);
+                }
+                sb.append("*");
+            }
+            return sb.toString();
+        }
+
+        public class CIB {
+
+            // These should be processed as var args
+            public void testVarArgsNsSuperclass() {
+                NsII q;
+
+                q = CIA.this::xvO;
+                assertEquals(q.m(55, 66), "xvO:55*66*");
+            }
+
+            public void testVarArgsNsArray() {
+                Nsai q;
+
+                q = CIA.this::xvO;
+                assertEquals(q.m(new int[]{55, 66}), "xvO:[55,66,]*");
+            }
+
+            public void testVarArgsNsII() {
+                NsII q;
+
+                q = CIA.this::xvI;
+                assertEquals(q.m(33, 7), "xvI:33-7-");
+
+                q = CIA.this::xIvI;
+                assertEquals(q.m(50, 40), "xIvI:5040-");
+
+                q = CIA.this::xvi;
+                assertEquals(q.m(100, 23), "xvi:123");
+
+                q = CIA.this::xIvi;
+                assertEquals(q.m(9, 21), "xIvi:(9)21");
+            }
+
+            public void testVarArgsNsiii() {
+                Nsiii q;
+
+                q = CIA.this::xvI;
+                assertEquals(q.m(3, 2, 1), "xvI:3-2-1-");
+
+                q = CIA.this::xIvI;
+                assertEquals(q.m(888, 99, 2), "xIvI:88899-2-");
+
+                q = CIA.this::xvi;
+                assertEquals(q.m(900, 80, 7), "xvi:987");
+
+                q = CIA.this::xIvi;
+                assertEquals(q.m(333, 27, 72), "xIvi:(333)99");
+            }
+
+            public void testVarArgsNsi() {
+                Nsi q;
+
+                q = CIA.this::xvI;
+                assertEquals(q.m(3), "xvI:3-");
+
+                q = CIA.this::xIvI;
+                assertEquals(q.m(888), "xIvI:888");
+
+                q = CIA.this::xvi;
+                assertEquals(q.m(900), "xvi:900");
+
+                q = CIA.this::xIvi;
+                assertEquals(q.m(333), "xIvi:(333)0");
+            }
+
+            // These should NOT be processed as var args
+            public void testVarArgsNsaO() {
+                NsaO q;
+
+                q = CIA.this::xvO;
+                assertEquals(q.m(new String[]{"yo", "there", "dude"}), "xvO:yo*there*dude*");
+            }
+        }
+
+        CIB cib() {
+            return new CIB();
+        }
+
+        class E {
+
+            String xI(Integer i) {
+                return "ExI:" + i;
+            }
+        }
+    }
+
+    CIA cia() {
+        return new CIA();
+    }
+
+    // These should be processed as var args
+    public void testVarArgsNsSuperclass() {
+        cia().cib().testVarArgsNsSuperclass();
+    }
+
+    public void testVarArgsNsArray() {
+        cia().cib().testVarArgsNsArray();
+    }
+
+    public void testVarArgsNsII() {
+        cia().cib().testVarArgsNsII();
+    }
+
+    public void testVarArgsNsiii() {
+        cia().cib().testVarArgsNsiii();
+    }
+
+    public void testVarArgsNsi() {
+        cia().cib().testVarArgsNsi();
+    }
+
+    // These should NOT be processed as var args
+
+    public void testVarArgsNsaO() {
+        cia().cib().testVarArgsNsaO();
+    }
+
+
+}
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestInstance.java b/jdk/test/jdk/lambda/MethodReferenceTestInstance.java
new file mode 100644
index 0000000..2e06347
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestInstance.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+class MethodReferenceTestInstance_E {
+    String xI(Integer i) {
+        return "ExI:" + i;
+    }
+}
+
+@Test
+public class MethodReferenceTestInstance {
+
+    interface SI { String m(Integer a); }
+
+    String xI(Integer i) {
+        return "xI:" + i;
+    }
+
+    public void testMethodReferenceInstance() {
+        SI q;
+
+        q = this::xI;
+        assertEquals(q.m(55), "xI:55");
+    }
+
+    public void testMethodReferenceExternal() {
+        SI q;
+
+        q = (new MethodReferenceTestInstance_E())::xI;
+        assertEquals(q.m(77), "ExI:77");
+    }
+
+}
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestInstanceMethod.java b/jdk/test/jdk/lambda/MethodReferenceTestInstanceMethod.java
new file mode 100644
index 0000000..b000d64
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestInstanceMethod.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+import java.util.Arrays;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+@Test(groups = "lib")
+public class MethodReferenceTestInstanceMethod {
+    public Stream<String> generate() {
+        return Arrays.asList("one", "two", "three", "four", "five", "six")
+            .stream()
+            .filter(s->s.length() > 3)
+            .map(s -> s.toUpperCase());
+    }
+
+    class Thingy<T,U> {
+        U blah(Function<T, U> m, T val) {
+            return m.apply(val);
+        }
+    }
+
+    public void testStringBuffer() {
+        String s = generate().collect(Collectors.toStringBuilder()).toString();
+        assertEquals(s, "THREEFOURFIVE");
+    }
+
+    public void testMRInstance() {
+        Thingy<String,String> t = new Thingy<>();
+        assertEquals(t.blah(String::toUpperCase, "frogs"), "FROGS");
+    }
+
+}
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestKinds.java b/jdk/test/jdk/lambda/MethodReferenceTestKinds.java
new file mode 100644
index 0000000..356b3d6
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestKinds.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class MethodReferenceTestKinds extends MethodReferenceTestKindsSup {
+
+    interface S0 { String get(); }
+    interface S1 { String get(MethodReferenceTestKinds x); }
+    interface S2 { String get(MethodReferenceTestKinds x, MethodReferenceTestKinds y); }
+
+    interface SXN0 { MethodReferenceTestKindsBase make(MethodReferenceTestKinds x); }
+    interface SXN1 { MethodReferenceTestKindsBase make(MethodReferenceTestKinds x, String str); }
+
+    interface SN0 { MethodReferenceTestKindsBase make(); }
+    interface SN1 { MethodReferenceTestKindsBase make(String x); }
+
+    class In extends MethodReferenceTestKindsBase {
+        In(String val) {
+            this.val = val;
+        }
+
+        In() {
+            this("blank");
+        }
+    }
+
+    String instanceMethod0() { return "IM:0-" + this; }
+    String instanceMethod1(MethodReferenceTestKinds x) { return "IM:1-" + this + x; }
+
+    static String staticMethod0() { return "SM:0"; }
+    static String staticMethod1(MethodReferenceTestKinds x) { return "SM:1-" + x; }
+
+    MethodReferenceTestKinds(String val) {
+        super(val);
+    }
+
+    MethodReferenceTestKinds() {
+        super("blank");
+    }
+
+    MethodReferenceTestKinds inst(String val) {
+        return new MethodReferenceTestKinds(val);
+    }
+
+    public void testMRBound() {
+        S0 var = this::instanceMethod0;
+        assertEquals(var.get(), "IM:0-MethodReferenceTestKinds(blank)");
+    }
+
+    public void testMRBoundArg() {
+        S1 var = this::instanceMethod1;
+        assertEquals(var.get(inst("arg")), "IM:1-MethodReferenceTestKinds(blank)MethodReferenceTestKinds(arg)");
+    }
+
+    public void testMRUnbound() {
+        S1 var = MethodReferenceTestKinds::instanceMethod0;
+        assertEquals(var.get(inst("rcvr")), "IM:0-MethodReferenceTestKinds(rcvr)");
+    }
+
+    public void testMRUnboundArg() {
+        S2 var = MethodReferenceTestKinds::instanceMethod1;
+        assertEquals(var.get(inst("rcvr"), inst("arg")), "IM:1-MethodReferenceTestKinds(rcvr)MethodReferenceTestKinds(arg)");
+    }
+
+    public void testMRSuper() {
+        S0 var = super::instanceMethod0;
+        assertEquals(var.get(), "SIM:0-MethodReferenceTestKinds(blank)");
+    }
+
+    public void testMRSuperArg() {
+        S1 var = super::instanceMethod1;
+        assertEquals(var.get(inst("arg")), "SIM:1-MethodReferenceTestKinds(blank)MethodReferenceTestKinds(arg)");
+    }
+
+    public void testMRStatic() {
+        S0 var = MethodReferenceTestKinds::staticMethod0;
+        assertEquals(var.get(), "SM:0");
+    }
+
+    public void testMRStaticArg() {
+        S1 var = MethodReferenceTestKinds::staticMethod1;
+        assertEquals(var.get(inst("arg")), "SM:1-MethodReferenceTestKinds(arg)");
+    }
+
+    public void testMRTopLevel() {
+        SN0 var = MethodReferenceTestKindsBase::new;
+        assertEquals(var.make().toString(), "MethodReferenceTestKindsBase(blank)");
+    }
+
+    public void testMRTopLevelArg() {
+        SN1 var = MethodReferenceTestKindsBase::new;
+        assertEquals(var.make("name").toString(), "MethodReferenceTestKindsBase(name)");
+    }
+/* unbound inner case not supported anymore (dropped by EG)
+    public void testMRUnboundInner() {
+        SXN0 var = MethodReferenceTestKinds.In::new;
+        assertEquals(var.make(inst("out")).toString(), "In(blank)");
+    }
+
+   public void testMRUnboundInnerArg() {
+        SXN1 var = MethodReferenceTestKinds.In::new;
+        assertEquals(var.make(inst("out"), "name").toString(), "In(name)");
+    }
+*/
+    public void testMRImplicitInner() {
+        SN0 var = MethodReferenceTestKinds.In::new;
+        assertEquals(var.make().toString(), "In(blank)");
+    }
+
+    public void testMRImplicitInnerArg() {
+        SN1 var = MethodReferenceTestKinds.In::new;
+        assertEquals(var.make("name").toString(), "In(name)");
+    }
+
+}
+
+
+class MethodReferenceTestKindsBase {
+    String val = "unset";
+
+    public String toString() {
+        return getClass().getSimpleName() + "(" + val + ")";
+    }
+
+    MethodReferenceTestKindsBase(String val) {
+        this.val = val;
+    }
+
+    MethodReferenceTestKindsBase() {
+        this("blank");
+    }
+
+}
+
+class MethodReferenceTestKindsSup extends MethodReferenceTestKindsBase {
+    String instanceMethod0() { return "SIM:0-" + this; }
+    String instanceMethod1(MethodReferenceTestKinds x) { return "SIM:1-" + this + x; }
+
+    MethodReferenceTestKindsSup(String val) {
+        super(val);
+    }
+
+}
+
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestNew.java b/jdk/test/jdk/lambda/MethodReferenceTestNew.java
new file mode 100644
index 0000000..b556296
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestNew.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class MethodReferenceTestNew {
+
+    interface M0<T> {
+
+        T m();
+    }
+
+    static class N0 {
+
+        N0() {
+        }
+    }
+
+    interface M1<T> {
+
+        T m(Integer a);
+    }
+
+    static class N1 {
+
+        int i;
+
+        N1(int i) {
+            this.i = i;
+        }
+    }
+
+    interface M2<T> {
+
+        T m(Integer n, String o);
+    }
+
+    static class N2 {
+
+        Number n;
+        Object o;
+
+        N2(Number n, Object o) {
+            this.n = n;
+            this.o = o;
+        }
+
+        public String toString() {
+            return "N2(" + n + "," + o + ")";
+        }
+    }
+
+    interface MV {
+
+        NV m(Integer ai, int i);
+    }
+
+    static class NV {
+
+        int i;
+
+        NV(int... v) {
+            i = 0;
+            for (int x : v) {
+                i += x;
+            }
+        }
+
+        public String toString() {
+            return "NV(" + i + ")";
+        }
+    }
+
+    public void testConstructorReference0() {
+        M0<N0> q;
+
+        q = N0::new;
+        assertEquals(q.m().getClass().getSimpleName(), "N0");
+    }
+
+    public void testConstructorReference1() {
+        M1<N1> q;
+
+        q = N1::new;
+        assertEquals(q.m(14).getClass().getSimpleName(), "N1");
+    }
+
+    public void testConstructorReference2() {
+        M2<N2> q;
+
+        q = N2::new;
+        assertEquals(q.m(7, "hi").toString(), "N2(7,hi)");
+    }
+
+    public void testConstructorReferenceVarArgs() {
+        MV q;
+
+        q = NV::new;
+        assertEquals(q.m(5, 45).toString(), "NV(50)");
+    }
+
+}
+
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestNewInner.java b/jdk/test/jdk/lambda/MethodReferenceTestNewInner.java
new file mode 100644
index 0000000..084eec3
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestNewInner.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class MethodReferenceTestNewInner {
+
+    String note = "NO NOTE";
+
+    interface M0<T> {
+
+        T m();
+    }
+
+    interface MP<T> {
+
+        T m(MethodReferenceTestNewInner m);
+    }
+
+    class N0 {
+
+        N0() {
+        }
+    }
+
+    interface M1<T> {
+
+        T m(Integer a);
+    }
+
+    class N1 {
+
+        int i;
+
+        N1(int i) {
+            this.i = i;
+        }
+    }
+
+    interface M2<T> {
+
+        T m(Integer n, String o);
+    }
+
+    class N2 {
+
+        Number n;
+        Object o;
+
+        N2(Number n, Object o) {
+            this.n = n;
+            this.o = o;
+        }
+
+        public String toString() {
+            return note + ":N2(" + n + "," + o + ")";
+        }
+    }
+
+    interface MV {
+
+        NV m(Integer ai, int i);
+    }
+
+    class NV {
+
+        int i;
+
+        NV(int... v) {
+            i = 0;
+            for (int x : v) {
+                i += x;
+            }
+        }
+
+        public String toString() {
+            return note + ":NV(" + i + ")";
+        }
+    }
+
+/* unbound constructor case not supported anymore (dropped by EG)
+    public static void testConstructorReferenceP() {
+        MP<N0> q;
+
+        q = N0::new;
+        assertEquals(q.m(new MethodReferenceTestNewInner()).getClass().getSimpleName(), "N0");
+    }
+*/
+    public void testConstructorReference0() {
+        M0<N0> q;
+
+        q = N0::new;
+        assertEquals(q.m().getClass().getSimpleName(), "N0");
+    }
+
+    public void testConstructorReference1() {
+        M1<N1> q;
+
+        q = N1::new;
+        assertEquals(q.m(14).getClass().getSimpleName(), "N1");
+    }
+
+    public void testConstructorReference2() {
+        M2<N2> q;
+
+        note = "T2";
+        q = N2::new;
+        assertEquals(q.m(7, "hi").toString(), "T2:N2(7,hi)");
+    }
+
+    /***
+    public void testConstructorReferenceVarArgs() {
+        MV q;
+
+        note = "TVA";
+        q = NV::new;
+        assertEquals(q.m(5, 45).toString(), "TNV:NV(50)");
+    }
+    ***/
+
+}
+
+
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass3.java b/jdk/test/jdk/lambda/MethodReferenceTestSueCase1.java
similarity index 61%
copy from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass3.java
copy to jdk/test/jdk/lambda/MethodReferenceTestSueCase1.java
index fe2be5a..89bb988 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass3.java
+++ b/jdk/test/jdk/lambda/MethodReferenceTestSueCase1.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,34 +21,26 @@
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
 
-@GenerateNativeHeader
-public class TestClass3 {
-    public int tc3;
+import org.testng.annotations.Test;
 
-    public class Inner1 {
-        public int tc3i1;
+import static org.testng.Assert.assertEquals;
 
-        public class Inner1A {
-            public int tc3i1i1a;
-        }
+/**
+ * @author Robert Field
+ */
 
-        public class Inner1B {
-            public int tc3i1i1b;
-        }
+@Test
+public class MethodReferenceTestSueCase1 {
+
+    public interface Sam2<T> { public String get(T target, String s); }
+
+    String instanceMethod(String s) { return "2"; }
+    Sam2<MethodReferenceTestSueCase1> var = MethodReferenceTestSueCase1::instanceMethod;
+
+    String m() {  return var.get(new MethodReferenceTestSueCase1(), ""); }
+
+    public void testSueCase1() {
+        assertEquals(m(), "2");
     }
-
-    public class Inner2 {
-        public int tc321;
-
-        public class Inner2A {
-            public int tc3i2i2a;
-        }
-
-        public class Inner2B {
-            public int tc3i2i2b;
-        }
-    }
-}
-
+}
\ No newline at end of file
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass3.java b/jdk/test/jdk/lambda/MethodReferenceTestSueCase2.java
similarity index 61%
rename from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass3.java
rename to jdk/test/jdk/lambda/MethodReferenceTestSueCase2.java
index fe2be5a..f967f9d 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass3.java
+++ b/jdk/test/jdk/lambda/MethodReferenceTestSueCase2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,34 +21,27 @@
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
 
-@GenerateNativeHeader
-public class TestClass3 {
-    public int tc3;
+import org.testng.annotations.Test;
 
-    public class Inner1 {
-        public int tc3i1;
+import static org.testng.Assert.assertEquals;
 
-        public class Inner1A {
-            public int tc3i1i1a;
-        }
+/**
+ * @author Robert Field
+ */
 
-        public class Inner1B {
-            public int tc3i1i1b;
-        }
+@Test
+public class MethodReferenceTestSueCase2 {
+
+    public interface Sam2<T> { public String get(T target, String s); }
+
+    String instanceMethod(String s) { return "2"; }
+    static Sam2<MethodReferenceTestSueCase2> var = MethodReferenceTestSueCase2::instanceMethod;
+
+    String m() {  return var.get(new MethodReferenceTestSueCase2(), ""); }
+
+    public void testSueCase2() {
+        assertEquals(m(), "2");
     }
 
-    public class Inner2 {
-        public int tc321;
-
-        public class Inner2A {
-            public int tc3i2i2a;
-        }
-
-        public class Inner2B {
-            public int tc3i2i2b;
-        }
-    }
-}
-
+}
\ No newline at end of file
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass3.java b/jdk/test/jdk/lambda/MethodReferenceTestSueCase4.java
similarity index 60%
copy from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass3.java
copy to jdk/test/jdk/lambda/MethodReferenceTestSueCase4.java
index fe2be5a..c14b31f 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass3.java
+++ b/jdk/test/jdk/lambda/MethodReferenceTestSueCase4.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,34 +21,32 @@
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
 
-@GenerateNativeHeader
-public class TestClass3 {
-    public int tc3;
+import org.testng.annotations.Test;
 
-    public class Inner1 {
-        public int tc3i1;
+import static org.testng.Assert.assertEquals;
 
-        public class Inner1A {
-            public int tc3i1i1a;
-        }
+/**
+ * @author Robert Field
+ */
 
-        public class Inner1B {
-            public int tc3i1i1b;
-        }
+@Test
+public class MethodReferenceTestSueCase4 {
+
+    public interface Sam2<T> { public String get(T target, String s); }
+
+    Sam2<Target> var = new Object().equals(new Object()) ? Target::instanceMethod : Target::instanceMethod;
+
+    String m() {
+        return var.get(new Target(), "");
     }
 
-    public class Inner2 {
-        public int tc321;
-
-        public class Inner2A {
-            public int tc3i2i2a;
-        }
-
-        public class Inner2B {
-            public int tc3i2i2b;
-        }
+    static class Target {
+        String instanceMethod(String s) { return "2"; }
     }
-}
 
+    public void testSueCase4() {
+        assertEquals(m(), "2");
+    }
+
+}
\ No newline at end of file
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestSuper.java b/jdk/test/jdk/lambda/MethodReferenceTestSuper.java
new file mode 100644
index 0000000..1fee7e1
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestSuper.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+
+
+/**
+ * @author Robert Field
+ */
+
+interface SPRI { String m(String a); }
+
+class SPRA {
+    String xsA__(String s) {
+        return "A__xsA:" + s;
+    }
+
+    String xsA_M(String s) {
+        return "A_MxsA:" + s;
+    }
+
+    String xsAB_(String s) {
+        return "AB_xsA:" + s;
+    }
+
+    String xsABM(String s) {
+        return "ABMxsA:" + s;
+    }
+
+}
+
+class SPRB extends SPRA {
+
+    String xsAB_(String s) {
+        return "AB_xsB:" + s;
+    }
+
+    String xsABM(String s) {
+        return "ABMxsB:" + s;
+    }
+
+    String xs_B_(String s) {
+        return "_B_xsB:" + s;
+    }
+
+    String xs_BM(String s) {
+        return "_BMxsB:" + s;
+    }
+
+}
+
+@Test
+public class MethodReferenceTestSuper extends SPRB {
+
+    String xsA_M(String s) {
+        return "A_MxsM:" + s;
+    }
+
+
+    String xsABM(String s) {
+        return "ABMxsM:" + s;
+    }
+
+    String xs_BM(String s) {
+        return "_BMxsM:" + s;
+    }
+
+    public void testMethodReferenceSuper() {
+        SPRI q;
+
+        q = super::xsA__;
+        assertEquals(q.m("*"), "A__xsA:*");
+
+        q = super::xsA_M;
+        assertEquals(q.m("*"), "A_MxsA:*");
+
+        q = super::xsAB_;
+        assertEquals(q.m("*"), "AB_xsB:*");
+
+        q = super::xsABM;
+        assertEquals(q.m("*"), "ABMxsB:*");
+
+        q = super::xs_B_;
+        assertEquals(q.m("*"), "_B_xsB:*");
+
+        q = super::xs_BM;
+        assertEquals(q.m("*"), "_BMxsB:*");
+    }
+
+}
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestSuperDefault.java b/jdk/test/jdk/lambda/MethodReferenceTestSuperDefault.java
new file mode 100644
index 0000000..103961e
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestSuperDefault.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+
+/**
+ * @author Robert Field
+ */
+
+interface DSPRI { String m(String a); }
+
+interface DSPRA {
+    default String xsA__(String s) {
+        return "A__xsA:" + s;
+    }
+
+    default String xsAB_(String s) {
+        return "AB_xsA:" + s;
+    }
+
+}
+
+interface DSPRB extends DSPRA {
+
+    default String xsAB_(String s) {
+        return "AB_xsB:" + s;
+    }
+
+    default String xs_B_(String s) {
+        return "_B_xsB:" + s;
+    }
+
+}
+
+@Test
+public class MethodReferenceTestSuperDefault implements DSPRB {
+
+    public void testMethodReferenceSuper() {
+        DSPRI q;
+
+        q = DSPRB.super::xsA__;
+        assertEquals(q.m("*"), "A__xsA:*");
+
+        q = DSPRB.super::xsAB_;
+        assertEquals(q.m("*"), "AB_xsB:*");
+
+        q = DSPRB.super::xs_B_;
+        assertEquals(q.m("*"), "_B_xsB:*");
+    }
+
+}
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestTypeConversion.java b/jdk/test/jdk/lambda/MethodReferenceTestTypeConversion.java
new file mode 100644
index 0000000..e690a9f
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestTypeConversion.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+class MethodReferenceTestTypeConversion_E<T> {
+    T xI(T t) { return t; }
+}
+
+@Test
+public class MethodReferenceTestTypeConversion {
+
+    interface ISi { int m(Short a); }
+
+    interface ICc { char m(Character a); }
+
+    public void testUnboxObjectToNumberWiden() {
+        ISi q = (new MethodReferenceTestTypeConversion_E<Short>())::xI;
+        assertEquals(q.m((short)77), (short)77);
+    }
+
+    public void testUnboxObjectToChar() {
+        ICc q = (new MethodReferenceTestTypeConversion_E<Character>())::xI;
+        assertEquals(q.m('@'), '@');
+    }
+
+}
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestVarArgs.java b/jdk/test/jdk/lambda/MethodReferenceTestVarArgs.java
new file mode 100644
index 0000000..0e58edb
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestVarArgs.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+import java.lang.reflect.Array;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class MethodReferenceTestVarArgs {
+
+    interface SII {
+
+        String m(Integer a, Integer b);
+    }
+
+    interface Siii {
+
+        String m(int a, int b, int c);
+    }
+
+    interface Si {
+
+        String m(int a);
+    }
+
+    interface SaO {
+
+        String m(Object[] a);
+    }
+
+    interface Sai {
+
+        String m(int[] a);
+    }
+
+    interface Svi {
+
+        String m(int... va);
+    }
+
+    // These should be processed as var args
+
+    static String xvI(Integer... vi) {
+        StringBuilder sb = new StringBuilder("xvI:");
+        for (Integer i : vi) {
+            sb.append(i);
+            sb.append("-");
+        }
+        return sb.toString();
+    }
+
+    static String xIvI(Integer f, Integer... vi) {
+        StringBuilder sb = new StringBuilder("xIvI:");
+        sb.append(f);
+        for (Integer i : vi) {
+            sb.append(i);
+            sb.append("-");
+        }
+        return sb.toString();
+    }
+
+    static String xvi(int... vi) {
+        int sum = 0;
+        for (int i : vi) {
+            sum += i;
+        }
+        return "xvi:" + sum;
+    }
+
+    static String xIvi(Integer f, int... vi) {
+        int sum = 0;
+        for (int i : vi) {
+            sum += i;
+        }
+        return "xIvi:(" + f + ")" + sum;
+    }
+
+    static String xvO(Object... vi) {
+        StringBuilder sb = new StringBuilder("xvO:");
+        for (Object i : vi) {
+            if (i.getClass().isArray()) {
+                sb.append("[");
+                int len = Array.getLength(i);
+                for (int x = 0; x < len; ++x)  {
+                    sb.append(Array.get(i, x));
+                    sb.append(",");
+                }
+                sb.append("]");
+
+            } else {
+                sb.append(i);
+            }
+            sb.append("*");
+        }
+        return sb.toString();
+    }
+
+    public void testVarArgsSuperclass() {
+        SII q;
+
+        q = MethodReferenceTestVarArgs::xvO;
+        assertEquals(q.m(55,66), "xvO:55*66*");
+    }
+
+    public void testVarArgsArray() {
+        Sai q;
+
+        q = MethodReferenceTestVarArgs::xvO;
+        assertEquals(q.m(new int[] { 55,66 } ), "xvO:[55,66,]*");
+    }
+
+    public void testVarArgsII() {
+        SII q;
+
+        q = MethodReferenceTestVarArgs::xvI;
+        assertEquals(q.m(33,7), "xvI:33-7-");
+
+        q = MethodReferenceTestVarArgs::xIvI;
+        assertEquals(q.m(50,40), "xIvI:5040-");
+
+        q = MethodReferenceTestVarArgs::xvi;
+        assertEquals(q.m(100,23), "xvi:123");
+
+        q = MethodReferenceTestVarArgs::xIvi;
+        assertEquals(q.m(9,21), "xIvi:(9)21");
+    }
+
+    public void testVarArgsiii() {
+        Siii q;
+
+        q = MethodReferenceTestVarArgs::xvI;
+        assertEquals(q.m(3, 2, 1), "xvI:3-2-1-");
+
+        q = MethodReferenceTestVarArgs::xIvI;
+        assertEquals(q.m(888, 99, 2), "xIvI:88899-2-");
+
+        q = MethodReferenceTestVarArgs::xvi;
+        assertEquals(q.m(900,80,7), "xvi:987");
+
+        q = MethodReferenceTestVarArgs::xIvi;
+        assertEquals(q.m(333,27, 72), "xIvi:(333)99");
+    }
+
+    public void testVarArgsi() {
+        Si q;
+
+        q = MethodReferenceTestVarArgs::xvI;
+        assertEquals(q.m(3), "xvI:3-");
+
+        q = MethodReferenceTestVarArgs::xIvI;
+        assertEquals(q.m(888), "xIvI:888");
+
+        q = MethodReferenceTestVarArgs::xvi;
+        assertEquals(q.m(900), "xvi:900");
+
+        q = MethodReferenceTestVarArgs::xIvi;
+        assertEquals(q.m(333), "xIvi:(333)0");
+    }
+
+    // These should NOT be processed as var args
+
+    public void testVarArgsaO() {
+        SaO q;
+
+        q = MethodReferenceTestVarArgs::xvO;
+        assertEquals(q.m(new String[] { "yo", "there", "dude" }), "xvO:yo*there*dude*");
+    }
+
+
+}
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestVarArgsExt.java b/jdk/test/jdk/lambda/MethodReferenceTestVarArgsExt.java
new file mode 100644
index 0000000..8101722
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestVarArgsExt.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+import java.lang.reflect.Array;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+interface NXII { String m(Integer a, Integer b); }
+
+interface NXiii { String m(int a, int b, int c); }
+
+interface NXi { String m(int a); }
+
+interface NXaO { String m(Object[] a); }
+
+interface NXai { String m(int[] a); }
+
+interface NXvi { String m(int... va); }
+
+@Test
+public class MethodReferenceTestVarArgsExt {
+
+    // These should be processed as var args
+
+    public void testVarArgsNXSuperclass() {
+        NXII q;
+
+        q = (new Ext())::xvO;
+        assertEquals(q.m(55,66), "xvO:55*66*");
+    }
+
+    public void testVarArgsNXArray() {
+        NXai q;
+
+        q = (new Ext())::xvO;
+        assertEquals(q.m(new int[] { 55,66 } ), "xvO:[55,66,]*");
+    }
+
+    public void testVarArgsNXII() {
+        NXII q;
+
+        q = (new Ext())::xvI;
+        assertEquals(q.m(33,7), "xvI:33-7-");
+
+        q = (new Ext())::xIvI;
+        assertEquals(q.m(50,40), "xIvI:5040-");
+
+        q = (new Ext())::xvi;
+        assertEquals(q.m(100,23), "xvi:123");
+
+        q = (new Ext())::xIvi;
+        assertEquals(q.m(9,21), "xIvi:(9)21");
+    }
+
+    public void testVarArgsNXiii() {
+        NXiii q;
+
+        q = (new Ext())::xvI;
+        assertEquals(q.m(3, 2, 1), "xvI:3-2-1-");
+
+        q = (new Ext())::xIvI;
+        assertEquals(q.m(888, 99, 2), "xIvI:88899-2-");
+
+        q = (new Ext())::xvi;
+        assertEquals(q.m(900,80,7), "xvi:987");
+
+        q = (new Ext())::xIvi;
+        assertEquals(q.m(333,27, 72), "xIvi:(333)99");
+    }
+
+    public void testVarArgsNXi() {
+        NXi q;
+
+        q = (new Ext())::xvI;
+        assertEquals(q.m(3), "xvI:3-");
+
+        q = (new Ext())::xIvI;
+        assertEquals(q.m(888), "xIvI:888");
+
+        q = (new Ext())::xvi;
+        assertEquals(q.m(900), "xvi:900");
+
+        q = (new Ext())::xIvi;
+        assertEquals(q.m(333), "xIvi:(333)0");
+    }
+
+    // These should NOT be processed as var args
+
+    public void testVarArgsNXaO() {
+        NXaO q;
+
+        q = (new Ext())::xvO;
+        assertEquals(q.m(new String[] { "yo", "there", "dude" }), "xvO:yo*there*dude*");
+    }
+
+
+}
+
+class Ext {
+
+    String xvI(Integer... vi) {
+        StringBuilder sb = new StringBuilder("xvI:");
+        for (Integer i : vi) {
+            sb.append(i);
+            sb.append("-");
+        }
+        return sb.toString();
+    }
+
+    String xIvI(Integer f, Integer... vi) {
+        StringBuilder sb = new StringBuilder("xIvI:");
+        sb.append(f);
+        for (Integer i : vi) {
+            sb.append(i);
+            sb.append("-");
+        }
+        return sb.toString();
+    }
+
+    String xvi(int... vi) {
+        int sum = 0;
+        for (int i : vi) {
+            sum += i;
+        }
+        return "xvi:" + sum;
+    }
+
+    String xIvi(Integer f, int... vi) {
+        int sum = 0;
+        for (int i : vi) {
+            sum += i;
+        }
+        return "xIvi:(" + f + ")" + sum;
+    }
+
+    String xvO(Object... vi) {
+        StringBuilder sb = new StringBuilder("xvO:");
+        for (Object i : vi) {
+            if (i.getClass().isArray()) {
+                sb.append("[");
+                int len = Array.getLength(i);
+                for (int x = 0; x < len; ++x)  {
+                    sb.append(Array.get(i, x));
+                    sb.append(",");
+                }
+                sb.append("]");
+
+            } else {
+                sb.append(i);
+            }
+            sb.append("*");
+        }
+        return sb.toString();
+    }
+
+
+}
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestVarArgsSuper.java b/jdk/test/jdk/lambda/MethodReferenceTestVarArgsSuper.java
new file mode 100644
index 0000000..2c37099
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestVarArgsSuper.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+import java.lang.reflect.Array;
+
+import static org.testng.Assert.assertEquals;
+
+
+/**
+ * @author Robert Field
+ */
+
+class MethodReferenceTestVarArgsSuper_Sub {
+
+    String xvI(Integer... vi) {
+        StringBuilder sb = new StringBuilder("xvI:");
+        for (Integer i : vi) {
+            sb.append(i);
+            sb.append("-");
+        }
+        return sb.toString();
+    }
+
+    String xIvI(Integer f, Integer... vi) {
+        StringBuilder sb = new StringBuilder("xIvI:");
+        sb.append(f);
+        for (Integer i : vi) {
+            sb.append(i);
+            sb.append("-");
+        }
+        return sb.toString();
+    }
+
+    String xvi(int... vi) {
+        int sum = 0;
+        for (int i : vi) {
+            sum += i;
+        }
+        return "xvi:" + sum;
+    }
+
+    String xIvi(Integer f, int... vi) {
+        int sum = 0;
+        for (int i : vi) {
+            sum += i;
+        }
+        return "xIvi:(" + f + ")" + sum;
+    }
+
+    String xvO(Object... vi) {
+        StringBuilder sb = new StringBuilder("xvO:");
+        for (Object i : vi) {
+            if (i.getClass().isArray()) {
+                sb.append("[");
+                int len = Array.getLength(i);
+                for (int x = 0; x < len; ++x)  {
+                    sb.append(Array.get(i, x));
+                    sb.append(",");
+                }
+                sb.append("]");
+
+            } else {
+                sb.append(i);
+            }
+            sb.append("*");
+        }
+        return sb.toString();
+    }
+}
+
+@Test
+public class MethodReferenceTestVarArgsSuper extends MethodReferenceTestVarArgsSuper_Sub {
+
+    interface SPRII { String m(Integer a, Integer b); }
+
+    interface SPRiii { String m(int a, int b, int c); }
+
+    interface SPRi { String m(int a); }
+
+    interface SPRaO { String m(Object[] a); }
+
+    interface SPRai { String m(int[] a); }
+
+    interface SPRvi { String m(int... va); }
+
+    String xvI(Integer... vi) {
+        return "ERROR";
+    }
+
+    String xIvI(Integer f, Integer... vi) {
+        return "ERROR";
+    }
+
+    String xvi(int... vi) {
+        return "ERROR";
+    }
+
+    String xIvi(Integer f, int... vi) {
+        return "ERROR";
+   }
+
+    String xvO(Object... vi) {
+        return "ERROR";
+    }
+
+    // These should be processed as var args
+
+    public void testVarArgsSPRSuperclass() {
+        SPRII q;
+
+        q = super::xvO;
+        assertEquals(q.m(55,66), "xvO:55*66*");
+    }
+
+    public void testVarArgsSPRArray() {
+        SPRai q;
+
+        q = super::xvO;
+        assertEquals(q.m(new int[] { 55,66 } ), "xvO:[55,66,]*");
+    }
+
+    public void testVarArgsSPRII() {
+        SPRII q;
+
+        q = super::xvI;
+        assertEquals(q.m(33,7), "xvI:33-7-");
+
+        q = super::xIvI;
+        assertEquals(q.m(50,40), "xIvI:5040-");
+
+        q = super::xvi;
+        assertEquals(q.m(100,23), "xvi:123");
+
+        q = super::xIvi;
+        assertEquals(q.m(9,21), "xIvi:(9)21");
+    }
+
+    public void testVarArgsSPRiii() {
+        SPRiii q;
+
+        q = super::xvI;
+        assertEquals(q.m(3, 2, 1), "xvI:3-2-1-");
+
+        q = super::xIvI;
+        assertEquals(q.m(888, 99, 2), "xIvI:88899-2-");
+
+        q = super::xvi;
+        assertEquals(q.m(900,80,7), "xvi:987");
+
+        q = super::xIvi;
+        assertEquals(q.m(333,27, 72), "xIvi:(333)99");
+    }
+
+    public void testVarArgsSPRi() {
+        SPRi q;
+
+        q = super::xvI;
+        assertEquals(q.m(3), "xvI:3-");
+
+        q = super::xIvI;
+        assertEquals(q.m(888), "xIvI:888");
+
+        q = super::xvi;
+        assertEquals(q.m(900), "xvi:900");
+
+        q = super::xIvi;
+        assertEquals(q.m(333), "xIvi:(333)0");
+    }
+
+    // These should NOT be processed as var args
+
+    public void testVarArgsSPRaO() {
+        SPRaO q;
+
+        q = super::xvO;
+        assertEquals(q.m(new String[] { "yo", "there", "dude" }), "xvO:yo*there*dude*");
+    }
+}
+
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestVarArgsSuperDefault.java b/jdk/test/jdk/lambda/MethodReferenceTestVarArgsSuperDefault.java
new file mode 100644
index 0000000..8f3bd87
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestVarArgsSuperDefault.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+import java.lang.reflect.Array;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+interface MethodReferenceTestVarArgsSuperDefault_I {
+
+    default String xvI(Integer... vi) {
+        StringBuilder sb = new StringBuilder("xvI:");
+        for (Integer i : vi) {
+            sb.append(i);
+            sb.append("-");
+        }
+        return sb.toString();
+    }
+
+    default String xIvI(Integer f, Integer... vi) {
+        StringBuilder sb = new StringBuilder("xIvI:");
+        sb.append(f);
+        for (Integer i : vi) {
+            sb.append(i);
+            sb.append("-");
+        }
+        return sb.toString();
+    }
+
+    default String xvi(int... vi) {
+        int sum = 0;
+        for (int i : vi) {
+            sum += i;
+        }
+        return "xvi:" + sum;
+    }
+
+    default String xIvi(Integer f, int... vi) {
+        int sum = 0;
+        for (int i : vi) {
+            sum += i;
+        }
+        return "xIvi:(" + f + ")" + sum;
+    }
+
+    default String xvO(Object... vi) {
+        StringBuilder sb = new StringBuilder("xvO:");
+        for (Object i : vi) {
+            if (i.getClass().isArray()) {
+                sb.append("[");
+                int len = Array.getLength(i);
+                for (int x = 0; x < len; ++x)  {
+                    sb.append(Array.get(i, x));
+                    sb.append(",");
+                }
+                sb.append("]");
+
+            } else {
+                sb.append(i);
+            }
+            sb.append("*");
+        }
+        return sb.toString();
+    }
+}
+
+@Test
+public class MethodReferenceTestVarArgsSuperDefault implements MethodReferenceTestVarArgsSuperDefault_I {
+
+    interface DSPRII { String m(Integer a, Integer b); }
+
+    interface DSPRiii { String m(int a, int b, int c); }
+
+    interface DSPRi { String m(int a); }
+
+    interface DSPRaO { String m(Object[] a); }
+
+    interface DSPRai { String m(int[] a); }
+
+    interface DSPRvi { String m(int... va); }
+
+    // These should be processed as var args
+
+    public void testVarArgsSPRSuperclass() {
+        DSPRII q;
+
+        q = MethodReferenceTestVarArgsSuperDefault_I.super::xvO;
+        assertEquals(q.m(55,66), "xvO:55*66*");
+    }
+
+    public void testVarArgsSPRArray() {
+        DSPRai q;
+
+        q = MethodReferenceTestVarArgsSuperDefault_I.super::xvO;
+        assertEquals(q.m(new int[] { 55,66 } ), "xvO:[55,66,]*");
+    }
+
+    public void testVarArgsSPRII() {
+        DSPRII q;
+
+        q = MethodReferenceTestVarArgsSuperDefault_I.super::xvI;
+        assertEquals(q.m(33,7), "xvI:33-7-");
+
+        q = MethodReferenceTestVarArgsSuperDefault_I.super::xIvI;
+        assertEquals(q.m(50,40), "xIvI:5040-");
+
+        q = MethodReferenceTestVarArgsSuperDefault_I.super::xvi;
+        assertEquals(q.m(100,23), "xvi:123");
+
+        q = MethodReferenceTestVarArgsSuperDefault_I.super::xIvi;
+        assertEquals(q.m(9,21), "xIvi:(9)21");
+    }
+
+    public void testVarArgsSPRiii() {
+        DSPRiii q;
+
+        q = MethodReferenceTestVarArgsSuperDefault_I.super::xvI;
+        assertEquals(q.m(3, 2, 1), "xvI:3-2-1-");
+
+        q = MethodReferenceTestVarArgsSuperDefault_I.super::xIvI;
+        assertEquals(q.m(888, 99, 2), "xIvI:88899-2-");
+
+        q = MethodReferenceTestVarArgsSuperDefault_I.super::xvi;
+        assertEquals(q.m(900,80,7), "xvi:987");
+
+        q = MethodReferenceTestVarArgsSuperDefault_I.super::xIvi;
+        assertEquals(q.m(333,27, 72), "xIvi:(333)99");
+    }
+
+    public void testVarArgsSPRi() {
+        DSPRi q;
+
+        q = MethodReferenceTestVarArgsSuperDefault_I.super::xvI;
+        assertEquals(q.m(3), "xvI:3-");
+
+        q = MethodReferenceTestVarArgsSuperDefault_I.super::xIvI;
+        assertEquals(q.m(888), "xIvI:888");
+
+        q = MethodReferenceTestVarArgsSuperDefault_I.super::xvi;
+        assertEquals(q.m(900), "xvi:900");
+
+        q = MethodReferenceTestVarArgsSuperDefault_I.super::xIvi;
+        assertEquals(q.m(333), "xIvi:(333)0");
+    }
+
+    // These should NOT be processed as var args
+
+    public void testVarArgsSPRaO() {
+        DSPRaO q;
+
+        q = MethodReferenceTestVarArgsSuperDefault_I.super::xvO;
+        assertEquals(q.m(new String[] { "yo", "there", "dude" }), "xvO:yo*there*dude*");
+    }
+
+
+}
+
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestVarArgsThis.java b/jdk/test/jdk/lambda/MethodReferenceTestVarArgsThis.java
new file mode 100644
index 0000000..eb5dfca
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestVarArgsThis.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+import java.lang.reflect.Array;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+interface NsII { String m(Integer a, Integer b); }
+
+interface Nsiii { String m(int a, int b, int c); }
+
+interface Nsi { String m(int a); }
+
+interface NsaO { String m(Object[] a); }
+
+interface Nsai { String m(int[] a); }
+
+interface Nsvi { String m(int... va); }
+
+@Test
+public class MethodReferenceTestVarArgsThis {
+
+    // These should be processed as var args
+
+    String xvI(Integer... vi) {
+        StringBuilder sb = new StringBuilder("xvI:");
+        for (Integer i : vi) {
+            sb.append(i);
+            sb.append("-");
+        }
+        return sb.toString();
+    }
+
+    String xIvI(Integer f, Integer... vi) {
+        StringBuilder sb = new StringBuilder("xIvI:");
+        sb.append(f);
+        for (Integer i : vi) {
+            sb.append(i);
+            sb.append("-");
+        }
+        return sb.toString();
+    }
+
+    String xvi(int... vi) {
+        int sum = 0;
+        for (int i : vi) {
+            sum += i;
+        }
+        return "xvi:" + sum;
+    }
+
+    String xIvi(Integer f, int... vi) {
+        int sum = 0;
+        for (int i : vi) {
+            sum += i;
+        }
+        return "xIvi:(" + f + ")" + sum;
+    }
+
+    String xvO(Object... vi) {
+        StringBuilder sb = new StringBuilder("xvO:");
+        for (Object i : vi) {
+            if (i.getClass().isArray()) {
+                sb.append("[");
+                int len = Array.getLength(i);
+                for (int x = 0; x < len; ++x)  {
+                    sb.append(Array.get(i, x));
+                    sb.append(",");
+                }
+                sb.append("]");
+
+            } else {
+                sb.append(i);
+            }
+            sb.append("*");
+        }
+        return sb.toString();
+    }
+
+    public void testVarArgsNsSuperclass() {
+        NsII q;
+
+        q = this::xvO;
+        assertEquals(q.m(55,66), "xvO:55*66*");
+    }
+
+    public void testVarArgsNsArray() {
+        Nsai q;
+
+        q = this::xvO;
+        assertEquals(q.m(new int[] { 55,66 } ), "xvO:[55,66,]*");
+    }
+
+    public void testVarArgsNsII() {
+        NsII q;
+
+        q = this::xvI;
+        assertEquals(q.m(33,7), "xvI:33-7-");
+
+        q = this::xIvI;
+        assertEquals(q.m(50,40), "xIvI:5040-");
+
+        q = this::xvi;
+        assertEquals(q.m(100,23), "xvi:123");
+
+        q = this::xIvi;
+        assertEquals(q.m(9,21), "xIvi:(9)21");
+    }
+
+    public void testVarArgsNsiii() {
+        Nsiii q;
+
+        q = this::xvI;
+        assertEquals(q.m(3, 2, 1), "xvI:3-2-1-");
+
+        q = this::xIvI;
+        assertEquals(q.m(888, 99, 2), "xIvI:88899-2-");
+
+        q = this::xvi;
+        assertEquals(q.m(900,80,7), "xvi:987");
+
+        q = this::xIvi;
+        assertEquals(q.m(333,27, 72), "xIvi:(333)99");
+    }
+
+    public void testVarArgsNsi() {
+        Nsi q;
+
+        q = this::xvI;
+        assertEquals(q.m(3), "xvI:3-");
+
+        q = this::xIvI;
+        assertEquals(q.m(888), "xIvI:888");
+
+        q = this::xvi;
+        assertEquals(q.m(900), "xvi:900");
+
+        q = this::xIvi;
+        assertEquals(q.m(333), "xIvi:(333)0");
+    }
+
+    // These should NOT be processed as var args
+
+    public void testVarArgsNsaO() {
+        NsaO q;
+
+        q = this::xvO;
+        assertEquals(q.m(new String[] { "yo", "there", "dude" }), "xvO:yo*there*dude*");
+    }
+
+
+}
diff --git a/jdk/test/jdk/lambda/TEST.properties b/jdk/test/jdk/lambda/TEST.properties
new file mode 100644
index 0000000..318077c
--- /dev/null
+++ b/jdk/test/jdk/lambda/TEST.properties
@@ -0,0 +1,5 @@
+# This file identifies root(s) of the test-ng hierarchy.
+
+TestNG.dirs = .
+
+javatest.maxOutputSize = 250000
diff --git a/jdk/test/jdk/lambda/TestInnerCtorRef.java b/jdk/test/jdk/lambda/TestInnerCtorRef.java
new file mode 100644
index 0000000..7b9ac1d
--- /dev/null
+++ b/jdk/test/jdk/lambda/TestInnerCtorRef.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+
+import java.util.function.Supplier;
+
+/**
+ * TestInnerCtorRef
+ */
+// @Test
+public class TestInnerCtorRef {
+
+    public void testCtorRef() {
+        A<String> a = A.make(() -> "");
+    }
+}
+
+abstract class A<T> {
+    abstract T make();
+
+    private A() {
+    }
+
+    public interface Foo<T> { }
+    public static<T> A<T> make(Supplier<T> factory) {
+        class Local implements Foo<T> {
+            Supplier<T> f = factory;
+        }
+        return new Helper<T>(Local::new);
+    }
+
+    private static class Helper<T> extends A<T> {
+
+        private Helper(Supplier<Foo<T>> factory) {
+        }
+
+        @Override
+        T make() {
+            return null;
+        }
+    }
+}
diff --git a/jdk/test/jdk/lambda/TestPrivateCtorRef.java b/jdk/test/jdk/lambda/TestPrivateCtorRef.java
new file mode 100644
index 0000000..a358a04
--- /dev/null
+++ b/jdk/test/jdk/lambda/TestPrivateCtorRef.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.function.Supplier;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+/**
+ * TestPrivateCtorRef
+ */
+@Test
+public class TestPrivateCtorRef {
+    // @@@ Really, this needs to be a combo test:
+    //     target class = nested static, nested instance, auxilliary
+    //     class protection = PPPP
+    //     ctor protection = PPPP
+    //     ctor = explicit, explicit
+    //     ref = lambda, method ref
+    static<T> T makeOne(Supplier<T> supp) {
+        T t = supp.get();
+        assertNotNull(t != null);
+        return t;
+    }
+
+    public void testPrivateStatic() {
+        makeOne(PS::new);
+    }
+
+    private static class PS {
+    }
+
+    public void testPrivateInstance() {
+        makeOne(PI::new);
+    }
+
+    private class PI {
+    }
+}
+
diff --git a/jdk/test/jdk/lambda/separate/AttributeInjector.java b/jdk/test/jdk/lambda/separate/AttributeInjector.java
new file mode 100644
index 0000000..6ea1115
--- /dev/null
+++ b/jdk/test/jdk/lambda/separate/AttributeInjector.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package separate;
+
+import java.io.*;
+
+public class AttributeInjector implements ClassFilePreprocessor {
+
+    private String attributeName;
+    private byte[] attributeData;
+
+    public AttributeInjector(String attributeName, byte[] attributeData) {
+        this.attributeName = attributeName;
+        this.attributeData = attributeData;
+    }
+
+    public byte[] preprocess(String name, byte[] cf) {
+        ClassFile classfile = new ClassFile(cf);
+
+        short cpIndex = (short)classfile.constant_pool.size();
+
+        ClassFile.CpUtf8 entry = new ClassFile.CpUtf8();
+        entry.bytes = new byte[attributeName.length()];
+        for (int i = 0; i < attributeName.length(); ++i) {
+            entry.bytes[i] = (byte)attributeName.charAt(i);
+        }
+
+        classfile.constant_pool.add(entry);
+
+        ClassFile.Attribute attr = new ClassFile.Attribute();
+        attr.attribute_name_index = cpIndex;
+        attr.info = attributeData;
+
+        classfile.attributes.add(attr);
+        return classfile.toByteArray();
+    }
+
+/*
+    public static void main(String argv[]) throws Exception {
+        File input = new File(argv[0]);
+        byte[] buffer = new byte[(int)input.length()];
+        new FileInputStream(input).read(buffer);
+
+        ClassFilePreprocessor cfp =
+            new AttributeInjector("RequiresBridges", new byte[0]);
+        byte[] cf = cfp.preprocess(argv[0], buffer);
+        new FileOutputStream(argv[0] + ".mod").write(cf);
+    }
+*/
+}
diff --git a/jdk/test/jdk/lambda/separate/ClassFile.java b/jdk/test/jdk/lambda/separate/ClassFile.java
new file mode 100644
index 0000000..7da140b
--- /dev/null
+++ b/jdk/test/jdk/lambda/separate/ClassFile.java
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package separate;
+
+import java.io.*;
+import java.util.*;
+
+class CfInputStream extends ByteArrayInputStream {
+    private int ct;
+    public CfInputStream(byte[] input) {
+        super(input);
+    }
+
+    byte u1() { return (byte)read(); }
+    short u2() {
+        int b0 = read() << 8;
+        int b1 = read();
+        return (short)(b0 | b1);
+    }
+    int u4() {
+        int b0 = read() << 24;
+        int b1 = read() << 16;
+        int b2 = read() << 8;
+        int b3 = read();
+        return b0 | b1 | b2 | b3;
+    }
+    byte[] array(int count) {
+        byte[] ret = new byte[count];
+        read(ret, 0, count);
+        return ret;
+    }
+};
+
+class CfOutputStream extends ByteArrayOutputStream {
+    void u1(byte b) { write((int)b); }
+    void u2(short s) {
+        write((s >> 8) & 0xff);
+        write(s & 0xff);
+    }
+    void u4(int i) {
+        write((i >> 24) & 0xff);
+        write((i >> 16) & 0xff);
+        write((i >> 8) & 0xff);
+        write(i & 0xff);
+    }
+    void array(byte[] a) {
+        write(a, 0, a.length);
+    }
+
+    public byte[] toByteArray() { return super.toByteArray(); }
+};
+
+// A quick and dirty class file parser and representation
+public class ClassFile {
+
+    int magic;
+    short minor_version;
+    short major_version;
+    ArrayList<CpEntry> constant_pool;
+    short access_flags;
+    short this_class;
+    short super_class;
+    ArrayList<Interface> interfaces;
+    ArrayList<Field> fields;
+    ArrayList<Method> methods;
+    ArrayList<Attribute> attributes;
+
+    ClassFile(byte[] cf) {
+        CfInputStream in = new CfInputStream(cf);
+
+        magic = in.u4();
+        minor_version = in.u2();
+        major_version = in.u2();
+
+        short cpCount = in.u2();
+        constant_pool = new ArrayList<>();
+        constant_pool.add(new CpNull());
+        for (int i = 1; i < cpCount; ++i) {
+            constant_pool.add(CpEntry.newCpEntry(in));
+        }
+
+        access_flags = in.u2();
+        this_class = in.u2();
+        super_class = in.u2();
+
+        short ifaceCount = in.u2();
+        interfaces = new ArrayList<>();
+        for (int i = 0; i < ifaceCount; ++i) {
+            interfaces.add(new Interface(in));
+        }
+
+        short fieldCount = in.u2();
+        fields = new ArrayList<>();
+        for (int i = 0; i < fieldCount; ++i) {
+            fields.add(new Field(in));
+        }
+
+        short methodCount = in.u2();
+        methods = new ArrayList<>();
+        for (int i = 0; i < methodCount; ++i) {
+            methods.add(new Method(in));
+        }
+
+        short attributeCount = in.u2();
+        attributes = new ArrayList<>();
+        for (int i = 0; i < attributeCount; ++i) {
+            attributes.add(new Attribute(in));
+        }
+    }
+
+    byte[] toByteArray() {
+        CfOutputStream out = new CfOutputStream();
+
+        out.u4(magic);
+        out.u2(minor_version);
+        out.u2(major_version);
+
+        out.u2((short)(constant_pool.size()));
+        for (CpEntry cp : constant_pool) {
+            cp.write(out);
+        }
+
+        out.u2(access_flags);
+        out.u2(this_class);
+        out.u2(super_class);
+
+        out.u2((short)interfaces.size());
+        for (Interface iface : interfaces) {
+            iface.write(out);
+        }
+
+        out.u2((short)fields.size());
+        for (Field field : fields) {
+            field.write(out);
+        }
+
+        out.u2((short)methods.size());
+        for (Method method : methods) {
+            method.write(out);
+        }
+
+        out.u2((short)attributes.size());
+        for (Attribute attribute : attributes) {
+            attribute.write(out);
+        }
+
+        return out.toByteArray();
+    }
+
+    static abstract class CpEntry {
+        byte tag;
+
+        CpEntry(byte t) { tag = t; }
+        void write(CfOutputStream out) {
+            out.u1(tag);
+        }
+
+        static CpEntry newCpEntry(CfInputStream in) {
+            byte tag = in.u1();
+            switch (tag) {
+                case CpUtf8.TAG: return new CpUtf8(in);
+                case CpInteger.TAG: return new CpInteger(in);
+                case CpFloat.TAG: return new CpFloat(in);
+                case CpLong.TAG: return new CpLong(in);
+                case CpDouble.TAG: return new CpDouble(in);
+                case CpClass.TAG: return new CpClass(in);
+                case CpString.TAG: return new CpString(in);
+                case CpFieldRef.TAG: return new CpFieldRef(in);
+                case CpMethodRef.TAG: return new CpMethodRef(in);
+                case CpInterfaceMethodRef.TAG:
+                    return new CpInterfaceMethodRef(in);
+                case CpNameAndType.TAG: return new CpNameAndType(in);
+                case CpMethodHandle.TAG: return new CpMethodHandle(in);
+                case CpMethodType.TAG: return new CpMethodType(in);
+                case CpInvokeDynamic.TAG: return new CpInvokeDynamic(in);
+                default: throw new RuntimeException("Bad cp entry tag: " + tag);
+            }
+        }
+    }
+
+    static class CpNull extends CpEntry {
+        CpNull() { super((byte)0); }
+        CpNull(CfInputStream in) { super((byte)0); }
+        void write(CfOutputStream out) {}
+    }
+
+    static class CpUtf8 extends CpEntry {
+        static final byte TAG = 1;
+        byte[] bytes;
+
+        CpUtf8() { super(TAG); }
+        CpUtf8(CfInputStream in) {
+            this();
+            short length = in.u2();
+            bytes = in.array(length);
+        }
+        void write(CfOutputStream out) {
+            super.write(out);
+            out.u2((short)bytes.length);
+            out.array(bytes);
+        }
+    }
+
+    static class CpU4Constant extends CpEntry {
+        byte[] bytes;
+
+        CpU4Constant(byte tag) { super(tag); }
+        CpU4Constant(byte tag, CfInputStream in) {
+            this(tag);
+            bytes = in.array(4);
+        }
+        void write(CfOutputStream out) { super.write(out); out.array(bytes); }
+    }
+    static class CpInteger extends CpU4Constant {
+        static final byte TAG = 3;
+        CpInteger() { super(TAG); }
+        CpInteger(CfInputStream in) { super(TAG, in); }
+    }
+    static class CpFloat extends CpU4Constant {
+        static final byte TAG = 4;
+        CpFloat() { super(TAG); }
+        CpFloat(CfInputStream in) { super(TAG, in); }
+    }
+
+    static class CpU8Constant extends CpEntry {
+        byte[] bytes;
+
+        CpU8Constant(byte tag) { super(tag); }
+        CpU8Constant(byte tag, CfInputStream in) {
+            this(tag);
+            bytes = in.array(8);
+        }
+        void write(CfOutputStream out) { super.write(out); out.array(bytes); }
+    }
+    static class CpLong extends CpU8Constant {
+        static final byte TAG = 5;
+        CpLong() { super(TAG); }
+        CpLong(CfInputStream in) { super(TAG, in); }
+    }
+    static class CpDouble extends CpU8Constant {
+        static final byte TAG = 6;
+        CpDouble() { super(TAG); }
+        CpDouble(CfInputStream in) { super(TAG, in); }
+    }
+
+    static class CpClass extends CpEntry {
+        static final byte TAG = 7;
+        short name_index;
+
+        CpClass() { super(TAG); }
+        CpClass(CfInputStream in) { super(TAG); name_index = in.u2(); }
+        void write(CfOutputStream out) {
+            super.write(out);
+            out.u2(name_index);
+        }
+    }
+
+    static class CpString extends CpEntry {
+        static final byte TAG = 8;
+        short string_index;
+
+        CpString() { super(TAG); }
+        CpString(CfInputStream in) { super(TAG); string_index = in.u2(); }
+        void write(CfOutputStream out) {
+            super.write(out);
+            out.u2(string_index);
+        }
+    }
+
+    static class CpRef extends CpEntry {
+        short class_index;
+        short name_and_type_index;
+
+        CpRef(byte tag) { super(tag); }
+        CpRef(byte tag, CfInputStream in) {
+            this(tag);
+            class_index = in.u2();
+            name_and_type_index = in.u2();
+        }
+        void write(CfOutputStream out) {
+            super.write(out);
+            out.u2(class_index);
+            out.u2(name_and_type_index);
+        }
+    }
+    static class CpFieldRef extends CpRef {
+        static final byte TAG = 9;
+        CpFieldRef() { super(TAG); }
+        CpFieldRef(CfInputStream in) { super(TAG, in); }
+    }
+    static class CpMethodRef extends CpRef {
+        static final byte TAG = 10;
+        CpMethodRef() { super(TAG); }
+        CpMethodRef(CfInputStream in) { super(TAG, in); }
+    }
+    static class CpInterfaceMethodRef extends CpRef {
+        static final byte TAG = 11;
+        CpInterfaceMethodRef() { super(TAG); }
+        CpInterfaceMethodRef(CfInputStream in) { super(TAG, in); }
+    }
+
+    static class CpNameAndType extends CpEntry {
+        static final byte TAG = 12;
+        short name_index;
+        short descriptor_index;
+
+        CpNameAndType() { super(TAG); }
+        CpNameAndType(CfInputStream in) {
+            this();
+            name_index = in.u2();
+            descriptor_index = in.u2();
+        }
+        void write(CfOutputStream out) {
+            super.write(out);
+            out.u2(name_index);
+            out.u2(descriptor_index);
+        }
+    }
+
+    static class CpMethodHandle extends CpEntry {
+        static final byte TAG = 15;
+        byte reference_kind;
+        short reference_index;
+
+        CpMethodHandle() { super(TAG); }
+        CpMethodHandle(CfInputStream in) {
+            this();
+            reference_kind = in.u1();
+            reference_index = in.u2();
+        }
+        void write(CfOutputStream out) {
+            super.write(out);
+            out.u1(reference_kind);
+            out.u2(reference_index);
+        }
+    }
+
+    static class CpMethodType extends CpEntry {
+        static final byte TAG = 16;
+        short descriptor_index;
+
+        CpMethodType() { super(TAG); }
+        CpMethodType(CfInputStream in) {
+            this();
+            descriptor_index = in.u2();
+        }
+        void write(CfOutputStream out) {
+            super.write(out);
+            out.u2(descriptor_index);
+        }
+    }
+
+    static class CpInvokeDynamic extends CpEntry {
+        static final byte TAG = 18;
+        short bootstrap_index;
+        short name_and_type_index;
+
+        CpInvokeDynamic() { super(TAG); }
+        CpInvokeDynamic(CfInputStream in) {
+            this();
+            bootstrap_index = in.u2();
+            name_and_type_index = in.u2();
+        }
+        void write(CfOutputStream out) {
+            super.write(out);
+            out.u2(bootstrap_index);
+            out.u2(name_and_type_index);
+        }
+    }
+
+    static class Interface {
+        short index;
+
+        Interface() {}
+        Interface(CfInputStream in) { index = in.u2(); }
+        void write(CfOutputStream out) { out.u2(index); }
+    }
+
+    static class FieldOrMethod {
+        short access_flags;
+        short name_index;
+        short descriptor_index;
+        ArrayList<Attribute> attributes;
+
+        FieldOrMethod() { attributes = new ArrayList<>(); }
+        FieldOrMethod(CfInputStream in) {
+            access_flags = in.u2();
+            name_index = in.u2();
+            descriptor_index = in.u2();
+
+            short attrCount = in.u2();
+            attributes = new ArrayList<>();
+            for (int i = 0; i < attrCount; ++i) {
+                attributes.add(new Attribute(in));
+            }
+        }
+        void write(CfOutputStream out) {
+            out.u2(access_flags);
+            out.u2(name_index);
+            out.u2(descriptor_index);
+            out.u2((short)attributes.size());
+            for (Attribute attribute : attributes) { attribute.write(out); }
+        }
+    }
+
+    static class Field extends FieldOrMethod {
+        Field() {}
+        Field(CfInputStream in) { super(in); }
+    }
+    static class Method extends FieldOrMethod {
+        Method() {}
+        Method(CfInputStream in) { super(in); }
+    }
+
+    static class Attribute {
+        short attribute_name_index;
+        byte[] info;
+
+        Attribute() { info = new byte[0]; }
+        Attribute(CfInputStream in) {
+            attribute_name_index = in.u2();
+            int length = in.u4();
+            info = in.array(length);
+        }
+        void write(CfOutputStream out) {
+            out.u2(attribute_name_index);
+            out.u4(info.length);
+            out.array(info);
+        }
+    }
+}
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java b/jdk/test/jdk/lambda/separate/ClassFilePreprocessor.java
similarity index 76%
copy from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
copy to jdk/test/jdk/lambda/separate/ClassFilePreprocessor.java
index 06196c2..e40434c 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
+++ b/jdk/test/jdk/lambda/separate/ClassFilePreprocessor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,16 +21,8 @@
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
+package separate;
 
-@GenerateNativeHeader
-public class TestClass2 {
-    byte b;
-    short s;
-    int i;
-    long l;
-    float f;
-    double d;
-    Object o;
-    String t;
-}
+public interface ClassFilePreprocessor {
+    public byte[] preprocess(String name, byte[] classfile);
+};
diff --git a/jdk/test/jdk/lambda/separate/ClassToInterfaceConverter.java b/jdk/test/jdk/lambda/separate/ClassToInterfaceConverter.java
new file mode 100644
index 0000000..48c0e8d
--- /dev/null
+++ b/jdk/test/jdk/lambda/separate/ClassToInterfaceConverter.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package separate;
+
+import java.io.*;
+import java.util.*;
+
+public class ClassToInterfaceConverter implements ClassFilePreprocessor {
+
+    private String whichClass;
+
+    public ClassToInterfaceConverter(String className) {
+        this.whichClass = className;
+    }
+
+    private boolean utf8Matches(ClassFile.CpEntry entry, String v) {
+        if (!(entry instanceof ClassFile.CpUtf8)) {
+            return false;
+        }
+        ClassFile.CpUtf8 utf8 = (ClassFile.CpUtf8)entry;
+        if (v.length() != utf8.bytes.length) {
+            return false;
+        }
+        for (int i = 0; i < v.length(); ++i) {
+            if (v.charAt(i) != utf8.bytes[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private void convertToInterface(ClassFile cf) {
+        cf.access_flags = 0x0601; // ACC_INTERFACE | ACC_ABSTRACT | ACC_PUBLIC
+        ArrayList<ClassFile.Method> new_methods = new ArrayList<>();
+        // Find <init> method and delete it
+        for (int i = 0; i < cf.methods.size(); ++i) {
+            ClassFile.Method method = cf.methods.get(i);
+            ClassFile.CpEntry name = cf.constant_pool.get(method.name_index);
+            if (!utf8Matches(name, "<init>")) {
+                new_methods.add(method);
+            }
+        }
+        cf.methods = new_methods;
+    }
+
+    public byte[] preprocess(String classname, byte[] bytes) {
+        ClassFile cf = new ClassFile(bytes);
+
+        ClassFile.CpEntry entry = cf.constant_pool.get(cf.this_class);
+        ClassFile.CpEntry name = cf.constant_pool.get(
+            ((ClassFile.CpClass)entry).name_index);
+        if (utf8Matches(name, whichClass)) {
+            convertToInterface(cf);
+            return cf.toByteArray();
+        } else {
+            return bytes; // unmodified
+        }
+    }
+
+/*
+    public static void main(String argv[]) throws Exception {
+        File input = new File(argv[0]);
+        byte[] buffer = new byte[(int)input.length()];
+        new FileInputStream(input).read(buffer);
+
+        ClassFilePreprocessor cfp = new ClassToInterfaceConverter("Hello");
+        byte[] cf = cfp.preprocess(argv[0], buffer);
+        new FileOutputStream(argv[0] + ".mod").write(cf);
+    }
+*/
+}
diff --git a/jdk/test/jdk/lambda/separate/Compiler.java b/jdk/test/jdk/lambda/separate/Compiler.java
new file mode 100644
index 0000000..9ba81d6
--- /dev/null
+++ b/jdk/test/jdk/lambda/separate/Compiler.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package separate;
+
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.ConcurrentHashMap;
+import java.io.*;
+import java.net.URI;
+import javax.tools.*;
+
+import com.sun.source.util.JavacTask;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+
+import static separate.SourceModel.Type;
+import static separate.SourceModel.Class;
+import static separate.SourceModel.Extends;
+import static separate.SourceModel.SourceProcessor;
+
+public class Compiler {
+
+    public enum Flags {
+        VERBOSE, // Prints out files as they are compiled
+        USECACHE // Keeps results around for reuse.  Only use this is
+                 // you're sure that each compilation name maps to the
+                 // same source code
+    };
+
+    private static final AtomicInteger counter = new AtomicInteger();
+    private static final String targetDir =
+        System.getProperty("lambda.separate.targetDirectory",
+            System.getProperty("java.io.tmpdir") + File.separator + "gen-separate");
+    private static final File root = new File(targetDir);
+    private static ConcurrentHashMap<String,File> cache =
+            new ConcurrentHashMap<>();
+
+    Set<Flags> flags;
+
+    private JavaCompiler systemJavaCompiler;
+    private StandardJavaFileManager fm;
+    private List<File> tempDirs;
+    private List<ClassFilePreprocessor> postprocessors;
+
+    private static class SourceFile extends SimpleJavaFileObject {
+        private final String content;
+
+        public SourceFile(String name, String content) {
+            super(URI.create("myfo:/" + name + ".java"), Kind.SOURCE);
+            this.content = content;
+        }
+
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return toString();
+        }
+
+        public String toString() { return this.content; }
+    }
+
+    public Compiler(Flags ... flags) {
+        setFlags(flags);
+        this.tempDirs = new ArrayList<>();
+        this.postprocessors = new ArrayList<>();
+        this.systemJavaCompiler = ToolProvider.getSystemJavaCompiler();
+        this.fm = systemJavaCompiler.getStandardFileManager(null, null, null);
+    }
+
+    public void setFlags(Flags ... flags) {
+        this.flags = new HashSet<Flags>(Arrays.asList(flags));
+    }
+
+    public void addPostprocessor(ClassFilePreprocessor cfp) {
+        this.postprocessors.add(cfp);
+    }
+
+    /**
+     * Compile hierarchies starting with each of the 'types' and return
+     * a ClassLoader that can be used to load the compiled classes.
+     */
+    public ClassLoader compile(Type ... types) {
+        ClassFilePreprocessor[] cfps = this.postprocessors.toArray(
+            new ClassFilePreprocessor[0]);
+
+        DirectedClassLoader dcl = new DirectedClassLoader(cfps);
+
+        for (Type t : types) {
+            for (Map.Entry<String,File> each : compileHierarchy(t).entrySet()) {
+                dcl.setLocationFor(each.getKey(), each.getValue());
+            }
+        }
+        return dcl;
+    }
+
+    /**
+     * Compiles and loads a hierarchy, starting at 'type'
+     */
+    public java.lang.Class<?> compileAndLoad(Type type)
+            throws ClassNotFoundException {
+
+        ClassLoader loader = compile(type);
+        return java.lang.Class.forName(type.getName(), false, loader);
+    }
+
+    /**
+     * Compiles a hierarchy, starting at 'type' and return a mapping of the
+     * name to the location where the classfile for that type resides.
+     */
+    private Map<String,File> compileHierarchy(Type type) {
+        HashMap<String,File> outputDirs = new HashMap<>();
+
+        File outDir = compileOne(type);
+        outputDirs.put(type.getName(), outDir);
+
+        Class superClass = type.getSuperclass();
+        if (superClass != null) {
+            for( Map.Entry<String,File> each : compileHierarchy(superClass).entrySet()) {
+                outputDirs.put(each.getKey(), each.getValue());
+            }
+        }
+        for (Extends ext : type.getSupertypes()) {
+            Type iface = ext.getType();
+            for( Map.Entry<String,File> each : compileHierarchy(iface).entrySet()) {
+                outputDirs.put(each.getKey(), each.getValue());
+            }
+        }
+
+        return outputDirs;
+    }
+
+    private File compileOne(Type type) {
+        if (this.flags.contains(Flags.USECACHE)) {
+            File dir = cache.get(type.getName());
+            if (dir != null) {
+                return dir;
+            }
+        }
+        List<JavaFileObject> files = new ArrayList<>();
+        SourceProcessor accum = (name, src) -> files.add(new SourceFile(name, src));
+
+        for (Type dep : type.typeDependencies()) {
+            dep.generateAsDependency(accum, type.methodDependencies());
+        }
+
+        type.generate(accum);
+
+        JavacTask ct = (JavacTask)this.systemJavaCompiler.getTask(
+            null, this.fm, null, null, null, files);
+        File destDir = null;
+        do {
+            int value = counter.incrementAndGet();
+            destDir = new File(root, Integer.toString(value));
+        } while (destDir.exists());
+
+        if (this.flags.contains(Flags.VERBOSE)) {
+            System.out.println("Compilation unit for " + type.getName() +
+                " : compiled into " + destDir);
+            for (JavaFileObject jfo : files) {
+                System.out.println(jfo.toString());
+            }
+        }
+
+        try {
+            destDir.mkdirs();
+            this.fm.setLocation(
+                StandardLocation.CLASS_OUTPUT, Arrays.asList(destDir));
+        } catch (IOException e) {
+            throw new RuntimeException(
+                "IOException encountered during compilation");
+        }
+        Boolean result = ct.call();
+        if (result == Boolean.FALSE) {
+            throw new RuntimeException(
+                "Compilation failure in " + type.getName() + " unit");
+        }
+        if (this.flags.contains(Flags.USECACHE)) {
+            File existing = cache.putIfAbsent(type.getName(), destDir);
+            if (existing != null) {
+                deleteDir(destDir);
+                return existing;
+            }
+        } else {
+        this.tempDirs.add(destDir);
+        }
+        return destDir;
+    }
+
+    private static void deleteDir(File dir) {
+        if(!dir.exists()) {
+            return;
+        }
+        try {
+            Files.walkFileTree(dir.toPath(), new SimpleFileVisitor<Path>() {
+                @Override
+                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                    throws IOException {
+                    Files.deleteIfExists(file);
+                    return FileVisitResult.CONTINUE;
+                }
+
+                @Override
+                public FileVisitResult postVisitDirectory(Path dir, IOException e)
+                    throws IOException {
+                    if (e == null) {
+                        Files.deleteIfExists(dir);
+                        return FileVisitResult.CONTINUE;
+                    } else {
+                        // directory iteration failed
+                        throw e;
+                    }
+                }
+            });
+        } catch (IOException failed) {
+            throw new RuntimeException(failed);
+        }
+    }
+
+    public void cleanup() {
+        if (!this.flags.contains(Flags.USECACHE)) {
+            tempDirs.forEach(dir -> { deleteDir(dir); });
+            tempDirs.clear();
+        }
+    }
+
+    // Removes all of the elements in the cache and deletes the associated
+    // output directories.  This may not actually empty the cache if there
+    // are concurrent users of it.
+    public static void purgeCache() {
+        for (Map.Entry<String,File> entry : cache.entrySet()) {
+            cache.remove(entry.getKey());
+            deleteDir(entry.getValue());
+        }
+    }
+}
diff --git a/jdk/test/jdk/lambda/separate/DirectedClassLoader.java b/jdk/test/jdk/lambda/separate/DirectedClassLoader.java
new file mode 100644
index 0000000..6da3866
--- /dev/null
+++ b/jdk/test/jdk/lambda/separate/DirectedClassLoader.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package separate;
+
+import java.util.HashMap;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+class DirectedClassLoader extends ClassLoader {
+
+    private HashMap<String,File> loadLocations;
+    private File defaultLocation;
+    private ClassFilePreprocessor[] preprocessors;
+
+    public DirectedClassLoader(
+            HashMap<String,File> locations, File fallback,
+            ClassFilePreprocessor ... preprocessors) {
+        loadLocations = new HashMap<>(locations);
+        defaultLocation = fallback;
+        this.preprocessors = preprocessors;
+    }
+
+    public DirectedClassLoader(
+            File fallback, ClassFilePreprocessor ... preprocessors) {
+        loadLocations = new HashMap<>();
+        defaultLocation = fallback;
+        this.preprocessors = preprocessors;
+    }
+
+    public DirectedClassLoader(ClassFilePreprocessor ... preprocessors) {
+        this((File)null, preprocessors);
+    }
+
+    public void setDefaultLocation(File dir) { this.defaultLocation = dir; }
+    public void setLocationFor(String name, File dir) {
+        loadLocations.put(name, dir);
+    }
+
+    @Override
+    protected Class<?> findClass(String name) {
+        String path = name.replace(".", File.separator) + ".class";
+
+        File location = loadLocations.get(name);
+        if (location == null || !(new File(location, path)).exists()) {
+            File def = new File(defaultLocation, path);
+            if (def.exists()) {
+                return defineFrom(name, new File(location, path));
+            }
+        } else {
+            return defineFrom(name, new File(location, path));
+        }
+        return null;
+    }
+
+    private Class<?> defineFrom(String name, File file) {
+        FileInputStream fis = null;
+        try {
+            try {
+                fis = new FileInputStream(file);
+                byte[] bytes = new byte[fis.available()];
+                int read = fis.read(bytes);
+                if (read != bytes.length) {
+                    return null;
+                }
+                if (preprocessors != null) {
+                    for (ClassFilePreprocessor cfp : preprocessors) {
+                        bytes = cfp.preprocess(name, bytes);
+                    }
+                 }
+                return defineClass(name, bytes, 0, bytes.length);
+            } finally {
+                fis.close();
+            }
+        } catch (IOException e) {}
+        return null;
+    }
+}
diff --git a/jdk/test/jdk/lambda/separate/SourceModel.java b/jdk/test/jdk/lambda/separate/SourceModel.java
new file mode 100644
index 0000000..6cef02f
--- /dev/null
+++ b/jdk/test/jdk/lambda/separate/SourceModel.java
@@ -0,0 +1,560 @@
+/*
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package separate;
+
+import java.util.*;
+import java.io.StringWriter;
+import java.io.PrintWriter;
+
+public class SourceModel {
+
+    public static final String stdMethodName = "m";
+
+    public static interface SourceProcessor {
+        // Called with a generated source file
+        void process(String name, String content);
+    }
+
+    public static abstract class Element {
+
+        protected abstract void generate(PrintWriter pw);
+
+        public String toString() {
+            StringWriter sw = new StringWriter();
+            PrintWriter pw = new PrintWriter(sw);
+            generate(pw);
+            return sw.toString();
+        }
+    };
+
+    public static class AccessFlag extends Element {
+        private String flag;
+
+        public AccessFlag(String name) { flag = name; }
+
+        protected void generate(PrintWriter pw) {
+            pw.print(flag);
+        }
+
+        public String toString() { return flag; }
+
+        public static final AccessFlag PUBLIC = new AccessFlag("public");
+        public static final AccessFlag PRIVATE = new AccessFlag("private");
+        public static final AccessFlag PROTECTED = new AccessFlag("protected");
+        public static final AccessFlag STATIC = new AccessFlag("static");
+        public static final AccessFlag FINAL = new AccessFlag("final");
+        public static final AccessFlag SYNCHRONIZED = new AccessFlag("synchronized");
+        public static final AccessFlag VOLATILE = new AccessFlag("volatile");
+        public static final AccessFlag NATIVE = new AccessFlag("native");
+        public static final AccessFlag ABSTRACT = new AccessFlag("abstract");
+        public static final AccessFlag STRICTFP = new AccessFlag("strictfp");
+        public static final AccessFlag DEFAULT = new AccessFlag("default");
+    }
+
+    public static class TypeParameter extends Element {
+        private String parameter;
+
+        public TypeParameter(String str) {
+            this.parameter = str;
+        }
+
+        protected void generate(PrintWriter pw) {
+            pw.print(parameter);
+        }
+    }
+
+    public static class TypeArgument extends Element {
+        private String argument;
+
+        public TypeArgument(String str) {
+            this.argument = str;
+        }
+
+        protected void generate(PrintWriter pw) {
+            pw.print(argument);
+        }
+    }
+
+    public static class MethodParameter extends Element {
+        private String type;
+        private String name;
+
+        public MethodParameter(String type, String name) {
+            this.type = type;
+            this.name = name;
+        }
+
+        protected void generate(PrintWriter pw) {
+            pw.printf("%s %s", this.type, this.name);
+        }
+
+        public String toString() { return type + " " + name; }
+    }
+
+    public static abstract class Type extends Element {
+        private String name;
+        private List<AccessFlag> accessFlags;
+        private List<TypeParameter> parameters;
+        private List<Extends> supertypes;
+        private List<Method> methods;
+
+        // methods from superclasses that are required for compilation
+        // (and thus will be present in stubs)
+        private Set<Method> methodDependencies;
+        private List<Type> typeDependencies;
+
+        protected Type(String name,
+                List<AccessFlag> flags, List<TypeParameter> params,
+                List<Extends> ifaces, List<Method> methods) {
+            this.name = name;
+            this.accessFlags = flags == null ? new ArrayList<>() : flags;
+            this.parameters = params == null ? new ArrayList<>() : params;
+            this.supertypes = ifaces == null ? new ArrayList<>() : ifaces;
+            this.methods = methods == null ? new ArrayList<>() : methods;
+            this.methodDependencies = new HashSet<>();
+            this.typeDependencies = new ArrayList<>();
+        }
+
+        public String getName() { return this.name; }
+        public List<AccessFlag> getAccessFlags() { return this.accessFlags; }
+        public List<TypeParameter> getParameters() { return this.parameters; }
+        public List<Extends> getSupertypes() { return this.supertypes; }
+        public List<Method> getMethods() { return this.methods; }
+        public Set<Method> methodDependencies() {
+            return this.methodDependencies;
+        }
+
+        public Class getSuperclass() { return null; }
+        protected abstract void setSuperClass(Extends supertype);
+
+        public void addSuperType(Extends sup) {
+            assert sup.getType() instanceof Interface : "Must be an interface";
+            this.supertypes.add(sup);
+        }
+        public void addSuperType(Interface iface) {
+            this.supertypes.add(new Extends(iface));
+        }
+
+        public void addMethod(Method m) {
+            this.methods.add(m);
+        }
+
+        public void addAccessFlag(AccessFlag f) {
+            this.accessFlags.add(f);
+        }
+
+        // Convenience method for creation.  Parameters are interpreted
+        // according to their type.  Class (or Extends with a Class type) is
+        // considered a superclass (only one allowed).  TypeParameters are
+        // generic parameter names.  Interface (or Extends with an Interface
+        // type) is an implemented supertype.  Methods are methods (duh!).
+        protected void addComponent(Element p) {
+            if (p instanceof Class) {
+                setSuperClass(new Extends((Class)p));
+            } else if (p instanceof Extends) {
+                Extends ext = (Extends)p;
+                if (ext.supertype instanceof Class) {
+                    setSuperClass(ext);
+                } else if (ext.supertype instanceof Interface) {
+                    addSuperType(ext);
+                } else {
+                    assert false : "What is this thing?";
+                }
+            } else if (p instanceof Interface) {
+                addSuperType((Interface)p);
+            } else if (p instanceof TypeParameter) {
+                this.parameters.add((TypeParameter)p);
+            } else if (p instanceof Method) {
+                addMethod((Method)p);
+            } else if (p instanceof AccessFlag) {
+                addAccessFlag((AccessFlag)p);
+            } else {
+                assert false : "What is this thing?";
+            }
+        }
+
+        // Find and return the first method that has name 'name'
+        public Method findMethod(String name) {
+            for (Method m : methods) {
+                if (m.name.equals(name)) {
+                    return m;
+                }
+            }
+            return null;
+        }
+
+        public void addCompilationDependency(Type t) {
+            typeDependencies.add(t);
+        }
+
+        public void addCompilationDependency(Method m) {
+            methodDependencies.add(m);
+        }
+
+        // Convenience method for creating an Extends object using this
+        // class and specified type arguments.
+        public Extends with(String ... args) {
+            return new Extends(this, args);
+        }
+
+        public abstract void generate(SourceProcessor sp);
+        public abstract void generateAsDependency(
+            SourceProcessor sp, Set<Method> neededMethods);
+
+        protected void generateName(PrintWriter pw) {
+            pw.print(this.name);
+            StringJoiner joiner = new StringJoiner(",", "<", ">").setEmptyValue("");
+            this.parameters.stream().map(Element::toString).forEach(joiner::add);
+            pw.print(joiner.toString());
+            pw.print(" ");
+        }
+
+        protected void generateBody(PrintWriter pw, String superSpec) {
+            StringJoiner joiner = new StringJoiner(",", superSpec + " ", " ")
+                    .setEmptyValue("");
+            supertypes.stream().map(Element::toString).forEach(joiner::add);
+            pw.print(joiner.toString());
+            pw.println("{ ");
+            joiner = new StringJoiner("\n    ", "\n    ", "\n").setEmptyValue("");
+            methods.stream().map(Element::toString).forEach(joiner::add);
+            pw.print(joiner.toString());
+            pw.println("}");
+        }
+
+        protected void generateAccessFlags(PrintWriter pw) {
+            StringJoiner joiner = new StringJoiner(" ", "", " ");
+            accessFlags.stream().map(AccessFlag::toString).forEach(joiner::add);
+            pw.print(joiner.toString());
+        }
+
+        protected void generateBodyAsDependency(
+            PrintWriter pw, Set<Method> neededMethods) {
+            pw.println(" {");
+            for (Method m : this.methods) {
+                if (neededMethods.contains(m)) {
+                    pw.print("    ");
+                    m.generate(pw);
+                    pw.println();
+                }
+            }
+            pw.println("}");
+        }
+
+        public Collection<Type> typeDependencies() {
+            HashMap<String,Type> dependencies = new HashMap<>();
+            Type superclass = getSuperclass();
+            if (superclass != null) {
+                dependencies.put(superclass.getName(), superclass);
+            }
+            for (Extends e : getSupertypes())
+                dependencies.put(e.getType().getName(), e.getType());
+            // Do these last so that they override
+            for (Type t : this.typeDependencies)
+                dependencies.put(t.getName(), t);
+            return dependencies.values();
+        }
+    }
+
+    public static class Class extends Type {
+        private Extends superClass;
+
+        public Class(String name, List<AccessFlag> flags,
+                List<TypeParameter> params, Extends sprClass,
+                List<Extends> interfaces, List<Method> methods) {
+            super(name, flags, params, interfaces, methods);
+            this.superClass = sprClass;
+            addAccessFlag(AccessFlag.PUBLIC); // should remove this
+        }
+
+        public Class(String name, Element ... components) {
+            super(name, null, null, null, null);
+            this.superClass = null;
+
+            for (Element p : components) {
+                addComponent(p);
+            }
+            addAccessFlag(AccessFlag.PUBLIC); // should remove this
+        }
+
+        public boolean isAbstract() {
+            for (AccessFlag flag : getAccessFlags()) {
+                if (flag == AccessFlag.ABSTRACT) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public void setSuperClass(Extends ext) {
+            assert this.superClass == null : "Multiple superclasses defined";
+            assert ext.getType() instanceof Class : "Must be a class";
+            this.superClass = ext;
+        }
+
+        public void setSuperClass(Class c) {
+            setSuperClass(new Extends(c));
+        }
+
+        @Override
+        public Class getSuperclass() {
+            return superClass == null ? null : (Class)superClass.supertype;
+        }
+
+        public void generate(SourceProcessor processor) {
+            StringWriter sw = new StringWriter();
+            PrintWriter pw = new PrintWriter(sw);
+            generate(pw);
+            processor.process(getName(), sw.toString());
+        }
+
+        public void generate(PrintWriter pw) {
+            generateAccessFlags(pw);
+            pw.print("class ");
+            generateName(pw);
+            if (superClass != null) {
+                pw.print("extends ");
+                superClass.generate(pw);
+                pw.print(" ");
+            }
+            generateBody(pw, "implements");
+        }
+
+        public void generateAsDependency(
+                SourceProcessor processor, Set<Method> neededMethods) {
+            StringWriter sw = new StringWriter();
+            PrintWriter pw = new PrintWriter(sw);
+            generateAccessFlags(pw);
+            pw.print("class ");
+            generateName(pw);
+            pw.print(" ");
+            generateBodyAsDependency(pw, neededMethods);
+
+            processor.process(getName(), sw.toString());
+        }
+    }
+
+    public static class Interface extends Type {
+
+        public Interface(String name,
+                  List<AccessFlag> flags, List<TypeParameter> params,
+                  List<Extends> interfaces, List<Method> methods) {
+            super(name, flags, params, interfaces, methods);
+        }
+
+        public Interface(String name, Element ... components) {
+            super(name, null, null, null, null);
+            for (Element c : components) {
+                addComponent(c);
+            }
+        }
+
+        protected void setSuperClass(Extends ext) {
+            assert false : "Interfaces cannot have Class supertypes";
+        }
+
+        public void generate(SourceProcessor processor) {
+            StringWriter sw = new StringWriter();
+            PrintWriter pw = new PrintWriter(sw);
+            generate(pw);
+            processor.process(getName(), sw.toString());
+        }
+
+        public void generate(PrintWriter pw) {
+            generateAccessFlags(pw);
+            pw.print("interface ");
+            generateName(pw);
+            pw.print(" ");
+            generateBody(pw, "extends");
+        }
+
+        public void generateAsDependency(
+                SourceProcessor processor, Set<Method> neededMethods) {
+            StringWriter sw = new StringWriter();
+            PrintWriter pw = new PrintWriter(sw);
+
+            generateAccessFlags(pw);
+            pw.print("interface ");
+            generateName(pw);
+            pw.print(" ");
+            generateBodyAsDependency(pw, neededMethods);
+
+            processor.process(getName(), sw.toString());
+        }
+    }
+
+    /**
+     * Represents a type extension that might contain type arguments
+     */
+    public static class Extends extends Element {
+        private final Type supertype;
+        private final List<TypeArgument> arguments;
+
+        public Type getType() { return supertype; }
+        public List<TypeArgument> getArguments() {
+            return arguments;
+        }
+
+        public Extends(Type supertype, String ... args) {
+            assert supertype != null : "Null supertype";
+            this.supertype = supertype;
+            this.arguments = new ArrayList<>();
+            for (String arg : args) {
+                this.arguments.add(new TypeArgument(arg));
+            }
+        }
+
+        public void generate(PrintWriter pw) {
+            StringJoiner joiner = new StringJoiner(",", "<", ">").setEmptyValue("");
+            getArguments().stream().map(Element::toString).forEach(joiner::add);
+            pw.print(supertype.getName());
+            pw.print(joiner.toString());
+        }
+    }
+
+    public static abstract class Method extends Element {
+        private String name;
+        private String returnType;
+        private List<AccessFlag> accessFlags;
+        private List<MethodParameter> parameters;
+        private boolean emitSuppressWarnings;
+
+        protected Method(String ret, String name, Element ... params) {
+            this.name = name;
+            this.returnType = ret;
+            this.accessFlags = new ArrayList<>();
+            this.parameters = new ArrayList<>();
+            this.emitSuppressWarnings = false;
+
+            Arrays.asList(params).stream()
+                .filter(x -> x instanceof MethodParameter)
+                .map(x -> (MethodParameter)x)
+                .forEach(this.parameters::add);
+            Arrays.asList(params).stream()
+                .filter(x -> x instanceof AccessFlag)
+                .map(x -> (AccessFlag)x)
+                .forEach(this.accessFlags::add);
+            assert accessFlags.size() + parameters.size() == params.length :
+                   "Non method parameters or access flags in constructor";
+        }
+
+        public String getName() { return this.name; }
+        public String getReturnType() { return this.returnType; }
+        public List<MethodParameter> getParameters() {
+            return this.parameters;
+        }
+        public List<AccessFlag> getAccessFlags() {
+            return this.accessFlags;
+        }
+        public Element[] getElements() {
+            ArrayList<Element> elements = new ArrayList<>();
+            getParameters().stream().forEach(elements::add);
+            getAccessFlags().stream().forEach(elements::add);
+            return elements.toArray(new Element[elements.size()]);
+        }
+
+        public void suppressWarnings() { this.emitSuppressWarnings = true; }
+
+        public void generateWarningSuppression(PrintWriter pw) {
+            if (this.emitSuppressWarnings) {
+                pw.printf("@SuppressWarnings(\"unchecked\")\n    ");
+            }
+        }
+
+        protected void generateDecl(PrintWriter pw) {
+            generateWarningSuppression(pw);
+            StringJoiner joiner = new StringJoiner(" ", "", " ");
+            accessFlags.stream().map(AccessFlag::toString).forEach(joiner::add);
+            pw.print(joiner.toString());
+            joiner = new StringJoiner(",");
+            pw.printf("%s %s(", returnType, name);
+            parameters.stream().map(MethodParameter::toString).forEach(joiner::add);
+            pw.print(joiner.toString());
+            pw.print(")");
+        }
+    }
+
+    public static class AbstractMethod extends Method {
+        public AbstractMethod(
+                String ret, String name, Element ... params) {
+            super(ret, name, params);
+            this.getAccessFlags().add(AccessFlag.ABSTRACT);
+        }
+
+        public void generate(PrintWriter pw) {
+            generateDecl(pw);
+            pw.print(";");
+        }
+
+        public static AbstractMethod std() {
+            return new AbstractMethod(
+                "int", SourceModel.stdMethodName, AccessFlag.PUBLIC);
+        }
+    }
+
+    public static class ConcreteMethod extends Method {
+        protected String body;
+
+        public ConcreteMethod(String ret, String name,
+                String body, Element ... params) {
+            super(ret, name, params);
+            this.body = body;
+        }
+
+        public void generate(PrintWriter pw) {
+            generateDecl(pw);
+            pw.printf(" { %s }", this.body);
+        }
+
+        public static ConcreteMethod std(String value) {
+            return new ConcreteMethod(
+                "int", SourceModel.stdMethodName, "return " + value + ";",
+                AccessFlag.PUBLIC);
+        }
+    }
+
+    // When the default method flag gets moved into the traditional
+    // access flags location, we can remove this class completely and
+    // use a ConcreteMethod with an AccessFlag("default") in the constructor
+    public static class DefaultMethod extends Method {
+        protected String body;
+
+        public DefaultMethod(String ret, String name, String body,
+                Element ... params) {
+            super(ret, name, params);
+            this.body = body;
+            this.getAccessFlags().add(AccessFlag.DEFAULT);
+        }
+
+        public void generate(PrintWriter pw) {
+            generateDecl(pw);
+            pw.printf(" { %s }", this.body);
+        }
+
+        public static DefaultMethod std(String value) {
+            return new DefaultMethod(
+                "int", SourceModel.stdMethodName, "return " + value + ";");
+        }
+    }
+}
diff --git a/jdk/test/jdk/lambda/separate/TestHarness.java b/jdk/test/jdk/lambda/separate/TestHarness.java
new file mode 100644
index 0000000..d5ba449
--- /dev/null
+++ b/jdk/test/jdk/lambda/separate/TestHarness.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package separate;
+
+import org.testng.ITestResult;
+import org.testng.annotations.AfterMethod;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.stream.Collectors;
+
+import static separate.SourceModel.Class;
+import static separate.SourceModel.*;
+import static org.testng.Assert.*;
+
+public class TestHarness {
+
+    /**
+     * Creates a per-thread persistent compiler object to allow as much
+     * sharing as possible, but still allows for parallel execution of tests.
+     */
+    protected ThreadLocal<Compiler> compilerLocal = new ThreadLocal<Compiler>(){
+         protected synchronized Compiler initialValue() {
+             return new Compiler();
+         }
+    };
+
+    protected ThreadLocal<Boolean> verboseLocal = new ThreadLocal<Boolean>() {
+         protected synchronized Boolean initialValue() {
+             return Boolean.FALSE;
+         }
+    };
+
+    protected boolean verbose;
+    protected boolean canUseCompilerCache;
+    public static final String stdMethodName = SourceModel.stdMethodName;
+
+    private TestHarness() {
+    }
+
+    protected TestHarness(boolean verbose, boolean canUseCompilerCache) {
+        this.verbose = verbose;
+        this.canUseCompilerCache = canUseCompilerCache;
+    }
+
+    public void setTestVerbose() {
+        verboseLocal.set(Boolean.TRUE);
+    }
+
+    @AfterMethod
+    public void reset() {
+        if (!this.verbose) {
+            verboseLocal.set(Boolean.FALSE);
+        }
+    }
+
+    public Compiler.Flags[] compilerFlags() {
+        HashSet<Compiler.Flags> flags = new HashSet<>();
+        if (verboseLocal.get() == Boolean.TRUE) {
+            flags.add(Compiler.Flags.VERBOSE);
+        }
+        if (this.canUseCompilerCache) {
+            flags.add(Compiler.Flags.USECACHE);
+        }
+        return flags.toArray(new Compiler.Flags[0]);
+    }
+
+    @AfterMethod
+    public void printError(ITestResult result) {
+        if (result.getStatus() == ITestResult.FAILURE) {
+            String clsName = result.getTestClass().getName();
+            clsName = clsName.substring(clsName.lastIndexOf(".") + 1);
+            System.out.println("Test " + clsName + "." +
+                               result.getName() + " FAILED");
+        }
+    }
+
+    private static final ConcreteMethod stdCM = ConcreteMethod.std("-1");
+    private static final AbstractMethod stdAM =
+            new AbstractMethod("int", stdMethodName);
+
+    /**
+     * Returns a class which has a static method with the same name as
+     * 'method', whose body creates an new instance of 'specimen' and invokes
+     * 'method' upon it via an invokevirtual instruction with 'args' as
+     * function call parameters.
+     *
+     * 'returns' is a dummy return value that need only match 'methods'
+     * return type (it is only used in the dummy class when compiling IV).
+     */
+    private Class invokeVirtualHarness(
+            Class specimen, ConcreteMethod method,
+            String returns, String ... args) {
+        Method cm = new ConcreteMethod(
+            method.getReturnType(), method.getName(),
+            "return " + returns + ";",  method.getElements());
+        Class stub = new Class(specimen.getName(), cm);
+
+        String params =
+            Arrays.asList(args).stream().collect(Collectors.toStringJoiner(", ")).toString();
+
+        ConcreteMethod sm = new ConcreteMethod(
+            method.getReturnType(), method.getName(),
+            String.format("return (new %s()).%s(%s);",
+                          specimen.getName(), method.getName(), params),
+            new AccessFlag("public"), new AccessFlag("static"));
+
+        Class iv = new Class("IV_" + specimen.getName(), sm);
+
+        iv.addCompilationDependency(stub);
+        iv.addCompilationDependency(cm);
+
+        return iv;
+    }
+
+    /**
+     * Returns a class which has a static method with the same name as
+     * 'method', whose body creates an new instance of 'specimen', casts it
+     * to 'iface' (including the type parameters)  and invokes
+     * 'method' upon it via an invokeinterface instruction with 'args' as
+     * function call parameters.
+     */
+    private Class invokeInterfaceHarness(Class specimen, Extends iface,
+            AbstractMethod method, String ... args) {
+        Interface istub = new Interface(
+            iface.getType().getName(), iface.getType().getAccessFlags(),
+            iface.getType().getParameters(),
+            null, Arrays.asList((Method)method));
+        Class cstub = new Class(specimen.getName());
+
+        String params = Arrays.asList(args).stream().collect(Collectors.toStringJoiner(", ")).toString();
+
+        ConcreteMethod sm = new ConcreteMethod(
+            "int", SourceModel.stdMethodName,
+            String.format("return ((%s)(new %s())).%s(%s);", iface.toString(),
+                specimen.getName(), method.getName(), params),
+            new AccessFlag("public"), new AccessFlag("static"));
+        sm.suppressWarnings();
+
+        Class ii = new Class("II_" + specimen.getName() + "_" +
+            iface.getType().getName(), sm);
+        ii.addCompilationDependency(istub);
+        ii.addCompilationDependency(cstub);
+        ii.addCompilationDependency(method);
+        return ii;
+    }
+
+
+    /**
+     * Uses 'loader' to load class 'clzz', and calls the static method
+     * 'method'.  If the return value does not equal 'value' (or if an
+     * exception is thrown), then a test failure is indicated.
+     *
+     * If 'value' is null, then no equality check is performed -- the assertion
+     * fails only if an exception is thrown.
+     */
+    protected void assertStaticCallEquals(
+            ClassLoader loader, Class clzz, String method, Object value) {
+        java.lang.Class<?> cls = null;
+        try {
+            cls = java.lang.Class.forName(clzz.getName(), true, loader);
+        } catch (ClassNotFoundException e) {}
+        assertNotNull(cls);
+
+        java.lang.reflect.Method m = null;
+        try {
+            m = cls.getMethod(method);
+        } catch (NoSuchMethodException e) {}
+        assertNotNull(m);
+
+        try {
+            Object res = m.invoke(null);
+            assertNotNull(res);
+            if (value != null) {
+                assertEquals(res, value);
+            }
+        } catch (InvocationTargetException | IllegalAccessException e) {
+            fail("Unexpected exception thrown: " + e.getCause());
+        }
+    }
+
+    /**
+     * Creates a class which calls target::method(args) via invokevirtual,
+     * compiles and loads both the new class and 'target', and then invokes
+     * the method.  If the returned value does not match 'value' then a
+     * test failure is indicated.
+     */
+    public void assertInvokeVirtualEquals(
+            Object value, Class target, ConcreteMethod method,
+            String returns, String ... args) {
+
+        Compiler compiler = compilerLocal.get();
+        compiler.setFlags(compilerFlags());
+
+        Class iv = invokeVirtualHarness(target, method, returns, args);
+        ClassLoader loader = compiler.compile(iv, target);
+
+        assertStaticCallEquals(loader, iv, method.getName(), value);
+        compiler.cleanup();
+    }
+
+    /**
+     * Convenience method for above, which assumes stdMethodName,
+     * a return type of 'int', and no arguments.
+     */
+    public void assertInvokeVirtualEquals(int value, Class target) {
+        assertInvokeVirtualEquals(
+            new Integer(value), target, stdCM, "-1");
+    }
+
+    /**
+     * Creates a class which calls target::method(args) via invokeinterface
+     * through 'iface', compiles and loads both it and 'target', and
+     * then invokes the method.  If the returned value does not match
+     * 'value' then a test failure is indicated.
+     */
+    public void assertInvokeInterfaceEquals(Object value, Class target,
+            Extends iface, AbstractMethod method, String ... args) {
+
+        Compiler compiler = compilerLocal.get();
+        compiler.setFlags(compilerFlags());
+
+        Class ii = invokeInterfaceHarness(target, iface, method, args);
+        ClassLoader loader = compiler.compile(ii, target);
+
+        assertStaticCallEquals(loader, ii, method.getName(), value);
+        compiler.cleanup();
+    }
+
+    /**
+     * Convenience method for above, which assumes stdMethodName,
+     * a return type of 'int', and no arguments.
+     */
+    public void assertInvokeInterfaceEquals(
+            int value, Class target, Interface iface) {
+
+        Compiler compiler = compilerLocal.get();
+        compiler.setFlags(compilerFlags());
+
+        assertInvokeInterfaceEquals(
+            new Integer(value), target, new Extends(iface), stdAM);
+
+        compiler.cleanup();
+    }
+
+    /**
+     * Creates a class which calls target::method(args) via invokevirtual,
+     * compiles and loads both the new class and 'target', and then invokes
+     * the method.  If an exception of type 'exceptionType' is not thrown,
+     * then a test failure is indicated.
+     */
+    public void assertThrows(java.lang.Class<?> exceptionType, Class target,
+            ConcreteMethod method, String returns, String ... args) {
+
+        Compiler compiler = compilerLocal.get();
+        compiler.setFlags(compilerFlags());
+
+        Class iv = invokeVirtualHarness(target, method, returns, args);
+        ClassLoader loader = compiler.compile(iv, target);
+
+        java.lang.Class<?> cls = null;
+        try {
+            cls = java.lang.Class.forName(iv.getName(), true, loader);
+        } catch (ClassNotFoundException e) {}
+        assertNotNull(cls);
+
+        java.lang.reflect.Method m = null;
+        try {
+            m = cls.getMethod(method.getName());
+        } catch (NoSuchMethodException e) {}
+        assertNotNull(m);
+
+        try {
+            m.invoke(null);
+            fail("Exception should have been thrown");
+        } catch (InvocationTargetException | IllegalAccessException e) {
+            if (verboseLocal.get() == Boolean.TRUE) {
+                System.out.println(e.getCause());
+            }
+            assertEquals(e.getCause().getClass(), exceptionType);
+        }
+        compiler.cleanup();
+    }
+
+    /**
+     * Convenience method for above, which assumes stdMethodName,
+     * a return type of 'int', and no arguments.
+     */
+    public void assertThrows(java.lang.Class<?> exceptionType, Class target) {
+        assertThrows(exceptionType, target, stdCM, "-1");
+    }
+}
diff --git a/jdk/test/jdk/lambda/shapegen/ClassCase.java b/jdk/test/jdk/lambda/shapegen/ClassCase.java
new file mode 100644
index 0000000..7ad096a
--- /dev/null
+++ b/jdk/test/jdk/lambda/shapegen/ClassCase.java
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package shapegen;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * @author Robert Field
+ */
+public class ClassCase {
+
+    public enum Kind {
+        IVAC        (true,  "v"),
+        IPRESENT    (true,  "p"),
+        IDEFAULT    (true,  "d"),
+        CNONE       (false, "n"),
+        CABSTRACT   (false, "a"),
+        CCONCRETE   (false, "c");
+
+        private final String prefix;
+        public final boolean isInterface;
+
+        Kind(boolean isInterface, String prefix) {
+            this.isInterface = isInterface;
+            this.prefix = prefix;
+        }
+
+        public String getPrefix() { return prefix; }
+    }
+
+    public final Kind kind;
+    private final ClassCase superclass;
+    private final List<ClassCase> supertypes;
+
+    private String name;
+    private boolean _OK;
+    private boolean _HasClassMethod;
+    private Set<ClassCase> _mprov;
+    private boolean _IsConcrete;
+    private boolean _HasDefault;
+    private ClassCase _mres;
+    private ClassCase _mdefend;
+
+    private Set<RuleGroup> executed = new HashSet<RuleGroup>();
+
+    public ClassCase(Kind kind, ClassCase superclass, List<ClassCase> interfaces) {
+        this.kind = kind;
+        this.superclass = superclass;
+
+        // Set supertypes from superclass (if any) and interfaces
+        List<ClassCase> lc;
+        if (superclass == null) {
+            lc = interfaces;
+        } else {
+            lc = new ArrayList<>();
+            lc.add(superclass);
+            lc.addAll(interfaces);
+        }
+        this.supertypes = lc;
+    }
+
+    public final boolean isInterface() { return kind.isInterface; }
+    public final boolean isClass() { return !kind.isInterface; }
+
+    public Set<ClassCase> get_mprov() {
+        exec(RuleGroup.PROVENENCE);
+        return _mprov;
+    }
+
+    public void set_mprov(ClassCase cc) {
+        Set<ClassCase> s = new HashSet<>();
+        s.add(cc);
+        _mprov = s;
+    }
+
+    public void set_mprov(Set<ClassCase> s) {
+        _mprov = s;
+    }
+
+    public ClassCase get_mres() {
+        exec(RuleGroup.RESOLUTION);
+        return _mres;
+    }
+
+    public void set_mres(ClassCase cc) {
+        _mres = cc;
+    }
+
+    public ClassCase get_mdefend() {
+        exec(RuleGroup.DEFENDER);
+        return _mdefend;
+    }
+
+    public void set_mdefend(ClassCase cc) {
+        _mdefend = cc;
+    }
+
+    public boolean get_HasClassMethod() {
+        exec(RuleGroup.PROVENENCE);
+        return _HasClassMethod;
+    }
+
+    public void set_HasClassMethod(boolean bool) {
+        _HasClassMethod = bool;
+    }
+
+    public boolean get_HasDefault() {
+        exec(RuleGroup.MARKER);
+        return _HasDefault;
+    }
+
+    public void set_HasDefault(boolean bool) {
+        _HasDefault = bool;
+    }
+
+    public boolean get_IsConcrete() {
+        exec(RuleGroup.MARKER);
+        return _IsConcrete;
+    }
+
+    public void set_IsConcrete(boolean bool) {
+        _IsConcrete = bool;
+    }
+
+    public boolean get_OK() {
+        exec(RuleGroup.CHECKING);
+        return _OK;
+    }
+
+    public void set_OK(boolean bool) {
+        _OK = bool;
+    }
+
+    public boolean isMethodDefined() {
+        for (ClassCase cc : supertypes) {
+            if (cc.isMethodDefined()) {
+                return true;
+            }
+        }
+        switch (kind) {
+            case CCONCRETE:
+            case CABSTRACT:
+            case IPRESENT:
+            case IDEFAULT:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    public boolean isAbstract() {
+        return isMethodDefined() && (get_mres()==null);
+    }
+
+    public boolean hasSuperclass() {
+        return superclass != null;
+    }
+
+    public ClassCase getSuperclass() {
+        return superclass;
+    }
+
+    public List<ClassCase> getSupertypes() {
+        return supertypes;
+    }
+
+    public List<ClassCase> getInterfaces() {
+        if (superclass != null) {
+            if (supertypes.get(0) != superclass) {
+                throw new AssertionError("superclass missing from supertypes");
+            }
+            return supertypes.subList(1, supertypes.size());
+        } else {
+            return supertypes;
+        }
+    }
+
+    public boolean isSubtypeOf(ClassCase cc) {
+        // S-Refl
+        if (cc.equals(this)) {
+            return true;
+        }
+
+        // S-Def
+        for (ClassCase sp : getSupertypes()) {
+            if (cc.equals(sp)) {
+                return true;
+            }
+        }
+
+        // _S-Trans
+        for (ClassCase sp : getSupertypes()) {
+            if (sp.isSubtypeOf(cc)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public void init(Map<String, Integer> namingContext) {
+        if (name != null) {
+            return; // Already inited
+        }
+
+        for (ClassCase sup : supertypes) {
+            sup.init(namingContext);
+        }
+
+        // Build name
+        StringBuilder sb = new StringBuilder();
+        if (!supertypes.isEmpty()) {
+            sb.append(isInterface() ? "I" : "C");
+            for (ClassCase cc : supertypes) {
+                sb.append(cc.getName());
+            }
+            sb.append(kind.isInterface ? "i" : "c");
+        }
+        sb.append(kind.prefix);
+        String pname = sb.toString();
+        Integer icnt = namingContext.get(pname);
+        int cnt = icnt == null ? 0 : icnt;
+        ++cnt;
+        namingContext.put(pname, cnt);
+        if (cnt > 1) {
+            sb.append(cnt);
+        }
+        this.name = sb.toString();
+    }
+
+    public boolean isa(Kind... kinds) {
+        for (Kind k : kinds) {
+            if (kind == k) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void exec(RuleGroup rg ) {
+        if (!executed.contains(rg)) {
+            rg.exec(this);
+            executed.add(rg);
+        }
+    }
+
+    public void collectClasses(Set<ClassCase> seen) {
+        seen.add(this);
+        for (ClassCase cc : supertypes) {
+            cc.collectClasses(seen);
+        }
+    }
+
+    public String getID() {
+        if (name == null) {
+            throw new Error("Access to uninitialized ClassCase");
+        } else {
+            return name;
+        }
+    }
+
+    public final String getName() {
+        if (name == null) {
+            return "ClassCase uninited@" + hashCode();
+        } else {
+            return name;
+        }
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return obj instanceof ClassCase && getID().equals(((ClassCase)obj).getID());
+    }
+
+    @Override
+    public int hashCode() {
+        return getID().hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return getName();
+    }
+}
diff --git a/jdk/test/jdk/lambda/shapegen/Hierarchy.java b/jdk/test/jdk/lambda/shapegen/Hierarchy.java
new file mode 100644
index 0000000..2315a9e
--- /dev/null
+++ b/jdk/test/jdk/lambda/shapegen/Hierarchy.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package shapegen;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static shapegen.ClassCase.Kind.*;
+
+/**
+ *
+ * @author Robert Field
+ */
+public class Hierarchy {
+
+    public final ClassCase root;
+    public final Set<ClassCase> all;
+
+    public Hierarchy(ClassCase root) {
+        this.root = root;
+        root.init(new HashMap<String,Integer>());
+        Set<ClassCase> allClasses = new HashSet<>();
+        root.collectClasses(allClasses);
+        this.all = allClasses;
+    }
+
+    public boolean anyDefaults() {
+        for (ClassCase cc : all) {
+            if (cc.kind == IDEFAULT) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean get_OK() {
+        return root.get_OK();
+    }
+
+    public String testName() {
+        return root + "Test";
+    }
+
+    private static void genInterfaceList(StringBuilder buf, String prefix, List<ClassCase> interfaces) {
+            if (!interfaces.isEmpty()) {
+                buf.append(" ");
+                buf.append(prefix);
+                buf.append(" ");
+                buf.append(interfaces.get(0));
+                for (int i = 1; i < interfaces.size(); ++i) {
+                    buf.append(", " + interfaces.get(i));
+                }
+            }
+    }
+
+    public static void genClassDef(StringBuilder buf, ClassCase cc, String implClass, List<ClassCase> defaultRef) {
+        if (cc.isInterface()) {
+            buf.append("interface ");
+            buf.append(cc.getName() + " ");
+            genInterfaceList(buf, "extends", cc.getInterfaces());
+            buf.append(" {\n");
+
+            switch (cc.kind) {
+                case IDEFAULT:
+                    buf.append("    default String m() { return \"\"; }\n");
+                    defaultRef.add(cc);
+                    break;
+                case IPRESENT:
+                    buf.append("    String m();\n");
+                    break;
+                case IVAC:
+                    break;
+                default:
+                    throw new AssertionError("Unexpected kind");
+            }
+            buf.append("}\n\n");
+        } else {
+            buf.append((cc.isAbstract()? "abstract " : ""));
+            buf.append(" class " + cc.getName());
+            if (cc.getSuperclass() != null) {
+                buf.append(" extends " + cc.getSuperclass());
+            }
+
+            genInterfaceList(buf, "implements", cc.getInterfaces());
+            buf.append(" {\n");
+
+            switch (cc.kind) {
+                case CCONCRETE:
+                    buf.append("   public String m() { return \"\"; }\n");
+                    break;
+                case CABSTRACT:
+                    buf.append("   public abstract String m();\n");
+                    break;
+                case CNONE:
+                    break;
+                default:
+                    throw new AssertionError("Unexpected kind");
+            }
+            buf.append("}\n\n");
+        }
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return obj instanceof Hierarchy && root.getID().equals(((Hierarchy)obj).root.getID());
+    }
+
+    @Override
+    public int hashCode() {
+        return root.getID().hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return root.getName();
+    }
+
+    private static String classNames[] = {
+        "C", "D", "E", "F", "G", "H", "S", "T", "U", "V"
+    };
+
+    private static String interfaceNames[] = {
+        "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R"
+    };
+
+    private static int CLASS_INDEX = 0;
+    private static int INTERFACE_INDEX = 1;
+    private static int NUM_INDICIES = 2;
+
+    public List<String> getDescription() {
+        Map<ClassCase,String> nameMap = new HashMap<>();
+        assignNames(root, new int[NUM_INDICIES], nameMap);
+
+        ArrayList<String> res = new ArrayList<>();
+        if (root.getSupertypes().size() == 0) {
+           res.add(nameMap.get(root) + root.kind.getPrefix() + "()");
+        } else {
+            genCaseDescription(root, res, new HashSet<ClassCase>(), nameMap);
+        }
+        return res;
+    }
+
+    private static void assignNames(
+            ClassCase cc, int indices[], Map<ClassCase,String> names) {
+        String name = names.get(cc);
+        if (name == null) {
+            if (cc.isInterface()) {
+                names.put(cc, interfaceNames[indices[INTERFACE_INDEX]++]);
+            } else {
+                names.put(cc, classNames[indices[CLASS_INDEX]++]);
+            }
+            for (int i = 0; i < cc.getSupertypes().size(); ++i) {
+                assignNames(cc.getSupertypes().get(i), indices, names);
+            }
+        }
+    }
+
+    private static void genCaseDescription(
+            ClassCase cc, List<String> res, Set<ClassCase> alreadyDone,
+            Map<ClassCase,String> nameMap) {
+        if (!alreadyDone.contains(cc)) {
+            if (cc.getSupertypes().size() > 0) {
+                StringBuilder sb = new StringBuilder();
+                sb.append(nameMap.get(cc));
+                sb.append(cc.kind.getPrefix());
+                sb.append("(");
+                for (int i = 0; i < cc.getSupertypes().size(); ++i) {
+                    ClassCase supertype = cc.getSupertypes().get(i);
+                    if (i != 0) {
+                        sb.append(",");
+                    }
+                    genCaseDescription(supertype, res, alreadyDone, nameMap);
+                    sb.append(nameMap.get(supertype));
+                    sb.append(supertype.kind.getPrefix());
+                }
+                sb.append(")");
+                res.add(sb.toString());
+            }
+        }
+        alreadyDone.add(cc);
+    }
+}
diff --git a/jdk/test/jdk/lambda/shapegen/HierarchyGenerator.java b/jdk/test/jdk/lambda/shapegen/HierarchyGenerator.java
new file mode 100644
index 0000000..4bf5af9
--- /dev/null
+++ b/jdk/test/jdk/lambda/shapegen/HierarchyGenerator.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package shapegen;
+
+import shapegen.ClassCase.Kind;
+
+import java.util.Collection;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+import java.util.ArrayList;
+import java.util.List;
+
+import static shapegen.ClassCase.Kind.*;
+
+import static java.lang.Math.pow;
+
+/**
+ *
+ * @author Robert Field
+ */
+public final class HierarchyGenerator {
+
+    private int okcnt = 0;
+    private int errcnt = 0;
+    private Set<Hierarchy> uniqueOK = new HashSet<>();
+    private Set<Hierarchy> uniqueErr = new HashSet<>();
+
+    /**
+     * @param args the command line arguments
+     */
+    public HierarchyGenerator() {
+        organize("exhaustive interface", iExhaustive(2));
+        organize("exhaustive class", cExhaustive());
+        organize("shapes interface", iShapes());
+        organize("shapes class/interface", ciShapes());
+
+        System.out.printf("\nExpect OK:    %d -- unique %d",   okcnt,  uniqueOK.size());
+        System.out.printf("\nExpect Error: %d -- unique %d\n", errcnt, uniqueErr.size());
+    }
+
+    public Collection<Hierarchy> getOK() {
+        return uniqueOK;
+    }
+
+    public Collection<Hierarchy> getErr() {
+        return uniqueErr;
+    }
+
+    private void organize(String tname, List<Hierarchy> totest) {
+        System.out.printf("\nGenerating %s....\n", tname);
+        int nodefault = 0;
+        List<Hierarchy> ok = new ArrayList<>();
+        List<Hierarchy> err = new ArrayList<>();
+        for (Hierarchy cc : totest) {
+            if (cc.anyDefaults()) {
+                //System.out.printf("  %s\n", cc);
+                if (cc.get_OK()) {
+                    ok.add(cc);
+                } else {
+                    err.add(cc);
+                }
+            } else {
+                ++nodefault;
+            }
+        }
+
+        errcnt += err.size();
+        okcnt += ok.size();
+        uniqueErr.addAll(err);
+        uniqueOK.addAll(ok);
+
+        System.out.printf("  %5d No default\n  %5d Error\n  %5d OK\n  %5d Total\n",
+                nodefault, err.size(), ok.size(), totest.size());
+    }
+
+    public List<Hierarchy> iExhaustive(int idepth) {
+        List<ClassCase> current = new ArrayList<>();
+        for (int i = 0; i < idepth; ++i) {
+            current = ilayer(current);
+        }
+        return wrapInClassAndHierarchy(current);
+    }
+
+    private List<ClassCase> ilayer(List<ClassCase> srcLayer) {
+        List<ClassCase> lay = new ArrayList<>();
+        for (int i = (int) pow(2, srcLayer.size()) - 1; i >= 0; --i) {
+            List<ClassCase> itfs = new ArrayList<>();
+            for (int b = srcLayer.size() - 1; b >= 0; --b) {
+                if ((i & (1<<b)) != 0) {
+                    itfs.add(srcLayer.get(b));
+                }
+            }
+            lay.add(new ClassCase(IVAC, null, itfs));
+            lay.add(new ClassCase(IPRESENT, null, itfs));
+            lay.add(new ClassCase(IDEFAULT, null, itfs));
+            lay.add(new ClassCase(IDEFAULT, null, itfs));
+        }
+        return lay;
+    }
+
+    public List<Hierarchy> cExhaustive() {
+        final Kind[] iKinds = new Kind[]{IDEFAULT, IVAC, IPRESENT, null};
+        final Kind[] cKinds = new Kind[]{CNONE, CABSTRACT, CCONCRETE};
+        List<Hierarchy> totest = new ArrayList<>();
+        for (int i1 = 0; i1 < iKinds.length; ++i1) {
+            for (int i2 = 0; i2 < iKinds.length; ++i2) {
+                for (int i3 = 0; i3 < iKinds.length; ++i3) {
+                    for (int c1 = 0; c1 < cKinds.length; ++c1) {
+                        for (int c2 = 0; c2 < cKinds.length; ++c2) {
+                            for (int c3 = 0; c3 < cKinds.length; ++c3) {
+                                totest.add( new Hierarchy(
+                                        new ClassCase(cKinds[c1],
+                                            new ClassCase(cKinds[c2],
+                                                new ClassCase(cKinds[c3],
+                                                    null,
+                                                    iList(iKinds[i1])
+                                                ),
+                                                iList(iKinds[i2])
+                                            ),
+                                            iList(iKinds[i3])
+                                        )));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return totest;
+    }
+
+    public static final List<ClassCase> EMPTY_LIST = new ArrayList<>();
+
+    private List<ClassCase> iList(Kind kind) {
+        if (kind == null) {
+            return EMPTY_LIST;
+        } else {
+            List<ClassCase> itfs = new ArrayList<>();
+            itfs.add(new ClassCase(kind, null, EMPTY_LIST));
+            return itfs;
+        }
+    }
+
+    public List<Hierarchy> ciShapes() {
+        return wrapInHierarchy(TTShape.allCases(true));
+    }
+
+    public List<Hierarchy> iShapes() {
+        return wrapInClassAndHierarchy(TTShape.allCases(false));
+    }
+
+    public List<Hierarchy> wrapInClassAndHierarchy(List<ClassCase> ihs) {
+        List<Hierarchy> totest = new ArrayList<>();
+        for (ClassCase cc : ihs) {
+            List<ClassCase> interfaces = new ArrayList<>();
+            interfaces.add(cc);
+            totest.add(new Hierarchy(new ClassCase(CNONE, null, interfaces)));
+        }
+        return totest;
+    }
+
+    public List<Hierarchy> wrapInHierarchy(List<ClassCase> ihs) {
+        List<Hierarchy> totest = new ArrayList<>();
+        for (ClassCase cc : ihs) {
+            totest.add(new Hierarchy(cc));
+        }
+        return totest;
+    }
+}
diff --git a/hotspot/src/share/tools/launcher/jli_util.h b/jdk/test/jdk/lambda/shapegen/Rule.java
similarity index 70%
copy from hotspot/src/share/tools/launcher/jli_util.h
copy to jdk/test/jdk/lambda/shapegen/Rule.java
index 535f7c4..5995ecd 100644
--- a/hotspot/src/share/tools/launcher/jli_util.h
+++ b/jdk/test/jdk/lambda/shapegen/Rule.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -19,17 +19,28 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
-#ifndef _JLI_UTIL_H
-#define _JLI_UTIL_H
+package shapegen;
 
-#include <stdlib.h>
+/**
+ *
+ * @author Robert Field
+ */
+public abstract class Rule {
 
-void *JLI_MemAlloc(size_t size);
-void *JLI_MemRealloc(void *ptr, size_t size);
-char *JLI_StringDup(const char *s1);
-void  JLI_MemFree(void *ptr);
+    public final String name;
 
-#endif  /* _JLI_UTIL_H */
+    public Rule(String name) {
+        this.name = name;
+    }
+
+    abstract boolean guard(ClassCase cc);
+
+    abstract void eval(ClassCase cc);
+
+    @Override
+    public String toString() {
+        return name;
+    }
+}
diff --git a/jdk/test/jdk/lambda/shapegen/RuleGroup.java b/jdk/test/jdk/lambda/shapegen/RuleGroup.java
new file mode 100644
index 0000000..b67ffcd
--- /dev/null
+++ b/jdk/test/jdk/lambda/shapegen/RuleGroup.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package shapegen;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import static shapegen.ClassCase.Kind.*;
+
+/**
+ *
+ * @author Robert Field
+ */
+public class RuleGroup {
+
+    final String name;
+    private final Rule[] rules;
+
+    public RuleGroup(String name, Rule[] rules) {
+        this.name = name;
+        this.rules = rules;
+    }
+
+    public boolean exec(ClassCase cc) {
+        boolean found = false;
+        for (Rule rule : rules) {
+            if (rule.guard(cc)) {
+                if (found) {
+                    throw new RuntimeException("Bad rules -- multiple matches " + toString() + " for " + cc);
+                } else {
+                    rule.eval(cc);
+                    found = true;
+                }
+            }
+        }
+        return found;
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    public static RuleGroup PROVENENCE = new RuleGroup("Provenence", new Rule[] {
+      new Rule("P-CDeclare") {
+          boolean guard(ClassCase cc) {
+              return cc.isa(CCONCRETE, CABSTRACT);
+          }
+
+          void eval(ClassCase cc) {
+              cc.set_mprov(cc);
+              cc.set_HasClassMethod(true);
+          }
+      },
+
+      new Rule("P-IDeclare") {
+          boolean guard(ClassCase cc) {
+              return cc.isa(IDEFAULT, IPRESENT);
+          }
+
+          void eval(ClassCase cc) {
+              cc.set_mprov(cc);
+          }
+      },
+
+      new Rule("P-IntfInh") {
+          boolean guard(ClassCase cc) {
+              return cc.isa(IVAC, CNONE) && !(cc.hasSuperclass() && cc.getSuperclass().get_HasClassMethod());
+          }
+
+          void eval(ClassCase cc) {
+              Set<ClassCase> _S = new HashSet<>();
+              for (ClassCase t : cc.getSupertypes()) {
+                  _S.addAll(t.get_mprov());
+              }
+              Set<ClassCase> tops = new HashSet<>();
+              for (ClassCase _W : _S) {
+                  for (ClassCase _V : _S) {
+                      if (_V.equals(_W) || !(_V.isSubtypeOf(_W))) {
+                          tops.add(_W);
+                      }
+                  }
+              }
+              cc.set_mprov(tops);
+          }
+      },
+
+      new Rule("P-ClassInh") {
+          boolean guard(ClassCase cc) {
+              return cc.isa(CNONE) && (cc.hasSuperclass() && cc.getSuperclass().get_HasClassMethod());
+          }
+
+          void eval(ClassCase cc) {
+              cc.set_mprov(cc.getSuperclass());
+              cc.set_HasClassMethod(true);
+          }
+      },
+
+    });
+
+    public static RuleGroup MARKER = new RuleGroup("Marker", new Rule[] {
+      new Rule("M-Default") {
+          boolean guard(ClassCase cc) {
+              return cc.isa(IDEFAULT);
+          }
+
+          void eval(ClassCase cc) {
+              cc.set_HasDefault(true);
+          }
+      },
+
+      new Rule("M-Conc") {
+          boolean guard(ClassCase cc) {
+            return cc.isa(CCONCRETE);
+          }
+
+          void eval(ClassCase cc) {
+              cc.set_IsConcrete(true);
+          }
+      },
+
+    });
+
+    public static RuleGroup RESOLUTION = new RuleGroup("Resolution", new Rule[] {
+      new Rule("R-Resolve") {
+          boolean guard(ClassCase cc) {
+              if (!(cc.isClass() && cc.get_mprov().size() == 1)) {
+                  return false;
+              }
+              ClassCase _V = cc.get_mprov().iterator().next();
+              return _V.get_IsConcrete() || _V.get_HasDefault();
+          }
+
+          void eval(ClassCase cc) {
+              ClassCase _V = cc.get_mprov().iterator().next();
+              cc.set_mres(_V);
+          }
+      },
+
+    });
+
+    public static RuleGroup DEFENDER = new RuleGroup("Defender", new Rule[] {
+      new Rule("D-Defend") {
+          boolean guard(ClassCase cc) {
+              ClassCase mresSuper = cc.hasSuperclass() ? cc.getSuperclass().get_mres() : null;
+              boolean eq = cc.get_mres() == null ? mresSuper == null : cc.get_mres().equals(mresSuper);
+              return cc.isa(CNONE) && !eq;
+          }
+
+          void eval(ClassCase cc) {
+              cc.set_mdefend(cc.get_mres());
+          }
+      },
+
+    });
+
+    public static RuleGroup CHECKING = new RuleGroup("Checking", new Rule[] {
+      new Rule("C-Check") {
+          boolean guard(ClassCase cc) {
+              for (ClassCase t : cc.getSupertypes()) {
+                  if (! t.get_OK()) {
+                      return false;
+                  }
+              }
+              int defenderCount = 0;
+              int provCount = 0;
+              for (ClassCase prov : cc.get_mprov()) {
+                  if (prov.get_HasDefault()) {
+                      defenderCount++;
+                  }
+                  provCount++;
+              }
+              return provCount <= 1 || defenderCount == 0;
+          }
+
+          void eval(ClassCase cc) {
+              cc.set_OK(true);
+          }
+      },
+
+    });
+
+}
diff --git a/jdk/test/jdk/lambda/shapegen/TTNode.java b/jdk/test/jdk/lambda/shapegen/TTNode.java
new file mode 100644
index 0000000..141b052
--- /dev/null
+++ b/jdk/test/jdk/lambda/shapegen/TTNode.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package shapegen;
+
+import shapegen.ClassCase.Kind;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import static shapegen.ClassCase.Kind.*;
+
+/**
+ * Type Template Node
+ *
+ * @author Robert Field
+ */
+public class TTNode {
+
+    final List<TTNode> supertypes;
+    final boolean canBeClass;
+
+    private int currentKindIndex;
+    private Kind[] kinds;
+
+    public TTNode(List<TTNode> subtypes, boolean canBeClass) {
+        this.supertypes = subtypes;
+        this.canBeClass = canBeClass;
+    }
+
+    public void start(boolean includeClasses) {
+        kinds =
+             supertypes.isEmpty()?
+                (new Kind[]{IDEFAULT, IPRESENT})
+             :  ((includeClasses && canBeClass)?
+                  new Kind[]{CNONE, IVAC, IDEFAULT, IPRESENT}
+                : new Kind[]{IVAC, IDEFAULT, IPRESENT});
+        currentKindIndex = 0;
+
+        for (TTNode sub : supertypes) {
+            sub.start(includeClasses);
+        }
+    }
+
+    public boolean next() {
+        ++currentKindIndex;
+        if (currentKindIndex >= kinds.length) {
+            currentKindIndex = 0;
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    public void collectAllSubtypes(Set<TTNode> subs) {
+        subs.add(this);
+        for (TTNode n : supertypes) {
+            n.collectAllSubtypes(subs);
+        }
+    }
+
+    private Kind getKind() {
+        return kinds[currentKindIndex];
+    }
+
+    boolean isInterface() {
+        return getKind().isInterface;
+    }
+
+    boolean isClass() {
+        return !isInterface();
+    }
+
+    boolean hasDefault() {
+        return getKind() == IDEFAULT;
+    }
+
+    public boolean isValid() {
+        for (TTNode n : supertypes) {
+            if (!n.isValid() || (isInterface() && n.isClass())) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public ClassCase genCase() {
+        ClassCase subclass;
+        List<TTNode> ttintfs;
+        if (isClass() && !supertypes.isEmpty() && supertypes.get(0).isClass()) {
+            subclass = supertypes.get(0).genCase();
+            ttintfs = supertypes.subList(1, supertypes.size());
+        } else {
+            subclass = null;
+            ttintfs = supertypes;
+        }
+        List<ClassCase> intfs = new ArrayList<>();
+        for (TTNode node : ttintfs) {
+            intfs.add(node.genCase());
+        }
+        return new ClassCase(getKind(), subclass, intfs);
+    }
+}
diff --git a/jdk/test/jdk/lambda/shapegen/TTParser.java b/jdk/test/jdk/lambda/shapegen/TTParser.java
new file mode 100644
index 0000000..6f56ac7
--- /dev/null
+++ b/jdk/test/jdk/lambda/shapegen/TTParser.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package shapegen;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.StringReader;
+
+import static java.lang.Character.isLetter;
+import static java.lang.Character.isUpperCase;
+import static java.lang.Character.isWhitespace;
+
+/**
+ * Parse a type template definition string
+ *
+ *   input     :: classDef
+ *   classDef  :: letter [ ( classDef* ) ]
+ *
+ * @author Robert Field
+ */
+public class TTParser extends StringReader {
+
+    private Map<Character, TTNode> letterMap = new HashMap<>();
+    private char ch;
+
+    private final String def;
+
+    public TTParser(String s) {
+        super(s);
+        this.def = s;
+    }
+
+    private void advance() throws IOException {
+        do {
+            ch = (char)read();
+        } while (isWhitespace(ch));
+    }
+
+    public TTNode parse() {
+        try {
+            advance();
+            return classDef();
+        } catch (IOException t) {
+            throw new RuntimeException(t);
+        }
+    }
+
+    private TTNode classDef() throws IOException {
+        if (!isLetter(ch)) {
+            if (ch == (char)-1) {
+                throw new IOException("Unexpected end of type template in " + def);
+            } else {
+                throw new IOException("Unexpected character in type template: " + (Character)ch + " in " + def);
+            }
+        }
+        char nodeCh = ch;
+        TTNode node = letterMap.get(nodeCh);
+        boolean canBeClass = isUpperCase(nodeCh);
+        advance();
+        if (node == null) {
+            List<TTNode> subtypes = new ArrayList<>();
+            if (ch == '(') {
+                advance();
+                while (ch != ')') {
+                    subtypes.add(classDef());
+                }
+                advance();
+            }
+            node = new TTNode(subtypes, canBeClass);
+            letterMap.put(nodeCh, node);
+        }
+        return node;
+    }
+}
diff --git a/jdk/test/jdk/lambda/shapegen/TTShape.java b/jdk/test/jdk/lambda/shapegen/TTShape.java
new file mode 100644
index 0000000..8064387
--- /dev/null
+++ b/jdk/test/jdk/lambda/shapegen/TTShape.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package shapegen;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * @author Robert Field
+ */
+public class TTShape {
+
+    private final TTNode root;
+    private final TTNode[] nodes;
+
+    TTShape(TTNode root) {
+        this.root = root;
+        Set<TTNode> subs = new HashSet<>();
+        root.collectAllSubtypes(subs);
+        nodes = subs.toArray(new TTNode[subs.size()]);
+    }
+
+    private List<ClassCase> toCases(boolean includeClasses) {
+        List<ClassCase> ccs = new ArrayList<>();
+        root.start(includeClasses);
+        int i;
+        outer:
+        while (true) {
+            if (root.isValid()) {
+                ClassCase cc = root.genCase();
+                //System.out.println(cc);
+                ccs.add(cc);
+            }
+
+            i = 0;
+            do {
+                if (i >= nodes.length) {
+                    break outer;
+                }
+            } while(!nodes[i++].next());
+        }
+        return ccs;
+    }
+
+   public static List<ClassCase> allCases(boolean includeClasses) {
+        List<ClassCase> ccs = new ArrayList<>();
+        for (TTShape shape : SHAPES) {
+            ccs.addAll(shape.toCases(includeClasses));
+        }
+        return ccs;
+    }
+
+    public static TTShape parse(String s) {
+        return new TTShape(new TTParser(s).parse());
+    }
+
+    public static final TTShape[] SHAPES = new TTShape[] {
+        parse("a"),
+        parse("a(b)"),
+        parse("A(bb)"),
+        parse("A(B(d)c(d))"),
+        parse("A(b(c))"),
+        parse("A(B(cd)d)"),
+        parse("A(B(c)c)"),
+        parse("A(B(Ce)d(e))"),
+        parse("A(B(C)d(e))"),
+        parse("A(Bc(d))"),
+        parse("A(B(d)dc)"),
+        parse("A(B(dc)dc)"),
+        parse("A(B(c(d))d)"),
+        parse("A(B(C(d))d)"),
+        parse("A(B(C(e)d(e))e)"),
+        parse("A(B(c(d))c)"),
+        parse("A(B(dc(d))c)"),
+        parse("A(B(C(d))d)"),
+    };
+
+}
diff --git a/jdk/test/jdk/lambda/vm/DefaultMethodRegressionTests.java b/jdk/test/jdk/lambda/vm/DefaultMethodRegressionTests.java
new file mode 100644
index 0000000..538d26d
--- /dev/null
+++ b/jdk/test/jdk/lambda/vm/DefaultMethodRegressionTests.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package vm;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+/**
+ * This set of classes/interfaces (K/I/C) is specially designed to expose a
+ * bug in the JVM where it did not find some overloaded methods in some
+ * specific situations. (fixed by hotspot changeset ffb9316fd9ed)
+ */
+interface K {
+    int bbb(Long l);
+}
+
+interface I extends K {
+    default void aaa() {}
+    default void aab() {}
+    default void aac() {}
+
+    default int bbb(Integer i) { return 22; }
+    default int bbb(Float f) { return 33; }
+    default int bbb(Long l) { return 44; }
+    default int bbb(Double d) { return 55; }
+    default int bbb(String s) { return 66; }
+
+    default void caa() {}
+    default void cab() {}
+    default void cac() {}
+}
+
+class C implements I {}
+
+public class DefaultMethodRegressionTests {
+
+    @Test(groups = "vm")
+    public void testLostOverloadedMethod() {
+        C c = new C();
+        assertEquals(c.bbb(new Integer(1)), 22);
+        assertEquals(c.bbb(new Float(1.1)), 33);
+        assertEquals(c.bbb(new Long(1L)), 44);
+        assertEquals(c.bbb(new Double(0.01)), 55);
+        assertEquals(c.bbb(new String("")), 66);
+    }
+
+    // Test to ensure that the inference verifier accepts older classfiles
+    // with classes that implement interfaces with defaults.
+    @Test(groups = "vm")
+    public void testInferenceVerifier() {
+        // interface I { int m() default { return 99; } }
+        byte I_bytes[] = {
+            (byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, 0x00, 0x00, 0x00, 0x34,
+            0x00, 0x08, 0x07, 0x00, 0x06, 0x07, 0x00, 0x07,
+            0x01, 0x00, 0x03, 0x66, 0x6f, 0x6f, 0x01, 0x00,
+            0x03, 0x28, 0x29, 0x49, 0x01, 0x00, 0x04, 0x43,
+            0x6f, 0x64, 0x65, 0x01, 0x00, 0x01, 0x49, 0x01,
+            0x00, 0x10, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c,
+            0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65,
+            0x63, 0x74, 0x06, 0x00, 0x00, 0x01, 0x00, 0x02,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x01,
+            0x00, 0x03, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05,
+            0x00, 0x00, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x01,
+            0x00, 0x00, 0x00, 0x03, 0x10, 0x63, (byte)0xac, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00
+        };
+        // public class C implements I {}  /* -target 1.5 */
+        byte C_bytes[] = {
+            (byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, 0x00, 0x00, 0x00, 0x31,
+            0x00, 0x0c, 0x0a, 0x00, 0x03, 0x00, 0x08, 0x07,
+            0x00, 0x09, 0x07, 0x00, 0x0a, 0x07, 0x00, 0x0b,
+            0x01, 0x00, 0x06, 0x3c, 0x69, 0x6e, 0x69, 0x74,
+            0x3e, 0x01, 0x00, 0x03, 0x28, 0x29, 0x56, 0x01,
+            0x00, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x0c, 0x00,
+            0x05, 0x00, 0x06, 0x01, 0x00, 0x01, 0x43, 0x01,
+            0x00, 0x10, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c,
+            0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65,
+            0x63, 0x74, 0x01, 0x00, 0x01, 0x49, 0x00, 0x21,
+            0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04,
+            0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x05,
+            0x00, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00,
+            0x00, 0x11, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
+            0x00, 0x05, 0x2a, (byte)0xb7, 0x00, 0x01, (byte)0xb1, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00
+        };
+
+        ClassLoader cl = new ClassLoader() {
+            protected Class<?> findClass(String name) {
+                if (name.equals("I")) {
+                    return defineClass("I", I_bytes, 0, I_bytes.length);
+                } else if (name.equals("C")) {
+                    return defineClass("C", C_bytes, 0, C_bytes.length);
+                } else {
+                    return null;
+                }
+            }
+        };
+        try {
+            Class.forName("C", true, cl);
+        } catch (Exception e) {
+            // unmodified verifier will throw VerifyError
+            fail("No exception should be thrown");
+        }
+    }
+}
diff --git a/jdk/test/jdk/lambda/vm/DefaultMethodsTest.java b/jdk/test/jdk/lambda/vm/DefaultMethodsTest.java
new file mode 100644
index 0000000..76ae86c
--- /dev/null
+++ b/jdk/test/jdk/lambda/vm/DefaultMethodsTest.java
@@ -0,0 +1,810 @@
+/*
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package vm;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.io.File;
+import java.io.IOException;
+
+import org.testng.annotations.Test;
+import separate.*;
+import separate.Compiler;
+
+import static org.testng.Assert.*;
+import static separate.SourceModel.*;
+import static separate.SourceModel.Class;
+
+@Test(groups = "vm")
+public class DefaultMethodsTest extends TestHarness {
+    public DefaultMethodsTest() {
+        super(false, false);
+    }
+
+    /**
+     * class C { public int m() { return 22; } }
+     *
+     * TEST: C c = new C(); c.m() == 22
+     */
+    public void testHarnessInvokeVirtual() {
+        Class C = new Class("C", ConcreteMethod.std("22"));
+        assertInvokeVirtualEquals(22, C);
+    }
+
+    /**
+     * interface I { int m(); }
+     * class C implements I { public int m() { return 33; } }
+     *
+     * TEST: I i = new C(); i.m() == 33;
+     */
+    public void testHarnessInvokeInterface() {
+        Interface I = new Interface("I", AbstractMethod.std());
+        Class C = new Class("C", I, ConcreteMethod.std("33"));
+        assertInvokeInterfaceEquals(33, C, I);
+    }
+
+    /**
+     * class C {}
+     *
+     * TEST: C c = new C(); c.m() throws NoSuchMethod
+     */
+    public void testHarnessThrows() {
+        Class C = new Class("C");
+        assertThrows(NoSuchMethodError.class, C);
+    }
+
+    /**
+     * interface I { int m() default { return 44; } }
+     * class C implements I {}
+     *
+     * TEST: C c = new C(); c.m() == 44;
+     * TEST: I i = new C(); i.m() == 44;
+     */
+    public void testBasicDefault() {
+        Interface I = new Interface("I", DefaultMethod.std("44"));
+        Class C = new Class("C", I);
+
+        assertInvokeVirtualEquals(44, C);
+        assertInvokeInterfaceEquals(44, C, I);
+    }
+
+    /**
+     * interface I { default int m() { return 44; } }
+     * interface J extends I {}
+     * interface K extends J {}
+     * class C implements K {}
+     *
+     * TEST: C c = new C(); c.m() == 44;
+     * TEST: I i = new C(); i.m() == 44;
+     */
+    public void testFarDefault() {
+        Interface I = new Interface("I", DefaultMethod.std("44"));
+        Interface J = new Interface("J", I);
+        Interface K = new Interface("K", J);
+        Class C = new Class("C", K);
+
+        assertInvokeVirtualEquals(44, C);
+        assertInvokeInterfaceEquals(44, C, K);
+    }
+
+    /**
+     * interface I { int m(); }
+     * interface J extends I { default int m() { return 44; } }
+     * interface K extends J {}
+     * class C implements K {}
+     *
+     * TEST: C c = new C(); c.m() == 44;
+     * TEST: K k = new C(); k.m() == 44;
+     */
+    public void testOverrideAbstract() {
+        Interface I = new Interface("I", AbstractMethod.std());
+        Interface J = new Interface("J", I, DefaultMethod.std("44"));
+        Interface K = new Interface("K", J);
+        Class C = new Class("C", K);
+
+        assertInvokeVirtualEquals(44, C);
+        assertInvokeInterfaceEquals(44, C, K);
+    }
+
+    /**
+     * interface I { int m() default { return 44; } }
+     * class C implements I { public int m() { return 55; } }
+     *
+     * TEST: C c = new C(); c.m() == 55;
+     * TEST: I i = new C(); i.m() == 55;
+     */
+    public void testExisting() {
+        Interface I = new Interface("I", DefaultMethod.std("44"));
+        Class C = new Class("C", I, ConcreteMethod.std("55"));
+
+        assertInvokeVirtualEquals(55, C);
+        assertInvokeInterfaceEquals(55, C, I);
+    }
+
+    /**
+     * interface I { default int m() { return 99; } }
+     * class B implements I {}
+     * class C extends B {}
+     *
+     * TEST: C c = new C(); c.m() == 99;
+     * TEST: I i = new C(); i.m() == 99;
+     */
+    public void testInherited() {
+        Interface I = new Interface("I", DefaultMethod.std("99"));
+        Class B = new Class("B", I);
+        Class C = new Class("C", B);
+
+        assertInvokeVirtualEquals(99, C);
+        assertInvokeInterfaceEquals(99, C, I);
+    }
+
+    /**
+     * interface I { default int m() { return 99; } }
+     * class C { public int m() { return 11; } }
+     * class D extends C implements I {}
+     *
+     * TEST: D d = new D(); d.m() == 11;
+     * TEST: I i = new D(); i.m() == 11;
+     */
+    public void testExistingInherited() {
+        Interface I = new Interface("I", DefaultMethod.std("99"));
+        Class C = new Class("C", ConcreteMethod.std("11"));
+        Class D = new Class("D", C, I);
+
+        assertInvokeVirtualEquals(11, D);
+        assertInvokeInterfaceEquals(11, D, I);
+    }
+
+    /**
+     * interface I { default int m() { return 44; } }
+     * class C implements I { public int m() { return 11; } }
+     * class D extends C { public int m() { return 22; } }
+     *
+     * TEST: D d = new D(); d.m() == 22;
+     * TEST: I i = new D(); i.m() == 22;
+     */
+    void testExistingInheritedOverride() {
+        Interface I = new Interface("I", DefaultMethod.std("99"));
+        Class C = new Class("C", I, ConcreteMethod.std("11"));
+        Class D = new Class("D", C, ConcreteMethod.std("22"));
+
+        assertInvokeVirtualEquals(22, D);
+        assertInvokeInterfaceEquals(22, D, I);
+    }
+
+    /**
+     * interface I { default int m() { return 99; } }
+     * interface J { defaultint m() { return 88; } }
+     * class C implements I { public int m() { return 11; } }
+     * class D extends C { public int m() { return 22; } }
+     * class E extends D implements J {}
+     *
+     * TEST: E e = new E(); e.m() == 22;
+     * TEST: J j = new E(); j.m() == 22;
+     */
+    public void testExistingInheritedPlusDefault() {
+        Interface I = new Interface("I", DefaultMethod.std("99"));
+        Interface J = new Interface("J", DefaultMethod.std("88"));
+        Class C = new Class("C", I, ConcreteMethod.std("11"));
+        Class D = new Class("D", C, ConcreteMethod.std("22"));
+        Class E = new Class("E", D, J);
+
+        assertInvokeVirtualEquals(22, E);
+        assertInvokeInterfaceEquals(22, E, J);
+    }
+
+    /**
+     * interface I { default int m() { return 99; } }
+     * class B implements I {}
+     * class C extends B { public int m() { return 77; } }
+     *
+     * TEST: C c = new C(); c.m() == 77;
+     * TEST: I i = new C(); i.m() == 77;
+     */
+    public void testInheritedWithConcrete() {
+        Interface I = new Interface("I", DefaultMethod.std("99"));
+        Class B = new Class("B", I);
+        Class C = new Class("C", B, ConcreteMethod.std("77"));
+
+        assertInvokeVirtualEquals(77, C);
+        assertInvokeInterfaceEquals(77, C, I);
+    }
+
+    /**
+     * interface I { default int m() { return 99; } }
+     * class B implements I {}
+     * class C extends B implements I { public int m() { return 66; } }
+     *
+     * TEST: C c = new C(); c.m() == 66;
+     * TEST: I i = new C(); i.m() == 66;
+     */
+    public void testInheritedWithConcreteAndImpl() {
+        Interface I = new Interface("I", DefaultMethod.std("99"));
+        Class B = new Class("B", I);
+        Class C = new Class("C", B, I, ConcreteMethod.std("66"));
+
+        assertInvokeVirtualEquals(66, C);
+        assertInvokeInterfaceEquals(66, C, I);
+    }
+
+    /**
+     * interface I { default int m() { return 99; } }
+     * interface J { default int m() { return 88; } }
+     * class C implements I, J {}
+     *
+     * TEST: C c = new C(); c.m() throws AME
+     */
+    public void testConflict() {
+        // debugTest();
+        Interface I = new Interface("I", DefaultMethod.std("99"));
+        Interface J = new Interface("J", DefaultMethod.std("88"));
+        Class C = new Class("C", I, J);
+
+        assertThrows(AbstractMethodError.class, C);
+    }
+
+    /**
+     * interface I { int m(); }
+     * interface J { default int m() { return 88; } }
+     * class C implements I, J {}
+     *
+     * TEST: C c = new C(); c.m() throws AME
+     */
+    public void testAmbiguousReabstract() {
+        Interface I = new Interface("I", AbstractMethod.std());
+        Interface J = new Interface("J", DefaultMethod.std("88"));
+        Class C = new Class("C", I, J);
+
+        assertThrows(AbstractMethodError.class, C);
+    }
+
+    /**
+     * interface I { default int m() { return 99; } }
+     * interface J extends I { }
+     * interface K extends I { }
+     * class C implements J, K {}
+     *
+     * TEST: C c = new C(); c.m() == 99
+     * TEST: J j = new C(); j.m() == 99
+     * TEST: K k = new C(); k.m() == 99
+     * TEST: I i = new C(); i.m() == 99
+     */
+    public void testDiamond() {
+        Interface I = new Interface("I", DefaultMethod.std("99"));
+        Interface J = new Interface("J", I);
+        Interface K = new Interface("K", I);
+        Class C = new Class("C", J, K);
+
+        assertInvokeVirtualEquals(99, C);
+        assertInvokeInterfaceEquals(99, C, J);
+        assertInvokeInterfaceEquals(99, C, K);
+        assertInvokeInterfaceEquals(99, C, I);
+    }
+
+    /**
+     * interface I { default int m() { return 99; } }
+     * interface J extends I { }
+     * interface K extends I { }
+     * interface L extends I { }
+     * interface M extends I { }
+     * class C implements I, J, K, L, M {}
+     *
+     * TEST: C c = new C(); c.m() == 99
+     * TEST: J j = new C(); j.m() == 99
+     * TEST: K k = new C(); k.m() == 99
+     * TEST: I i = new C(); i.m() == 99
+     * TEST: L l = new C(); l.m() == 99
+     * TEST: M m = new C(); m.m() == 99
+     */
+    public void testExpandedDiamond() {
+        Interface I = new Interface("I", DefaultMethod.std("99"));
+        Interface J = new Interface("J", I);
+        Interface K = new Interface("K", I);
+        Interface L = new Interface("L", I);
+        Interface M = new Interface("M", L);
+        Class C = new Class("C", I, J, K, L, M);
+
+        assertInvokeVirtualEquals(99, C);
+        assertInvokeInterfaceEquals(99, C, J);
+        assertInvokeInterfaceEquals(99, C, K);
+        assertInvokeInterfaceEquals(99, C, I);
+        assertInvokeInterfaceEquals(99, C, L);
+        assertInvokeInterfaceEquals(99, C, M);
+    }
+
+    /**
+     * interface I { int m() default { return 99; } }
+     * interface J extends I { int m(); }
+     * class C implements J {}
+     *
+     * TEST: C c = new C(); c.m() throws AME
+     */
+    public void testReabstract() {
+        Interface I = new Interface("I", DefaultMethod.std("99"));
+        Interface J = new Interface("J", I, AbstractMethod.std());
+        Class C = new Class("C", J);
+
+        assertThrows(AbstractMethodError.class, C);
+    }
+
+    /**
+     * interface I { default int m() { return 88; } }
+     * interface J extends I { default int m() { return 99; } }
+     * class C implements J {}
+     *
+     * TEST: C c = new C(); c.m() == 99;
+     * TEST: J j = new C(); j.m() == 99;
+     * TEST: I i = new C(); i.m() == 99;
+     */
+    public void testShadow() {
+        Interface I = new Interface("I", DefaultMethod.std("88"));
+        Interface J = new Interface("J", I, DefaultMethod.std("99"));
+        Class C = new Class("C", J);
+
+        assertInvokeVirtualEquals(99, C);
+        assertInvokeInterfaceEquals(99, C, J);
+        assertInvokeInterfaceEquals(99, C, I);
+    }
+
+    /**
+     * interface I { default int m() { return 88; } }
+     * interface J extends I { default int m() { return 99; } }
+     * class C implements I, J {}
+     *
+     * TEST: C c = new C(); c.m() == 99;
+     * TEST: J j = new C(); j.m() == 99;
+     * TEST: I i = new C(); i.m() == 99;
+     */
+    public void testDisqualified() {
+        Interface I = new Interface("I", DefaultMethod.std("88"));
+        Interface J = new Interface("J", I, DefaultMethod.std("99"));
+        Class C = new Class("C", I, J);
+
+        assertInvokeVirtualEquals(99, C);
+        assertInvokeInterfaceEquals(99, C, J);
+        assertInvokeInterfaceEquals(99, C, I);
+    }
+
+    /**
+     * interface I<T> { default int m(T t) { return 99; } }
+     * Class C implements I<String> { public int m() { return 88; } }
+     *
+     * TEST: C c = new C(); c.m() == 88;
+     * TEST: I i = new C(); i.m() == 88;
+     */
+    public void testSelfFill() {
+        // This test ensures that a concrete method overrides a default method
+        // that matches at the language-level, but has a different method
+        // signature due to erasure.
+
+        // debugTest();
+
+        DefaultMethod dm = new DefaultMethod(
+            "int", "m", "return 99;", new MethodParameter("T", "t"));
+        ConcreteMethod cm = new ConcreteMethod(
+            "int", "m", "return 88;", AccessFlag.PUBLIC,
+            new MethodParameter("String", "s"));
+
+        Interface I = new Interface("I", new TypeParameter("T"), dm);
+        Class C = new Class("C", I.with("String"), cm);
+
+        AbstractMethod pm = new AbstractMethod(
+            "int", "m", new MethodParameter("T", "t"));
+
+        assertInvokeVirtualEquals(new Integer(88), C, cm, "-1", "\"string\"");
+        assertInvokeInterfaceEquals(
+            new Integer(88), C, I.with("String"), pm, "\"string\"");
+    }
+
+    /**
+     * interface I { default int m() { return 99; } }
+     * class C implements I {}
+     *
+     * TEST: C.class.getMethod("m").invoke(new C()) == 99
+     */
+    public void testReflectCall() {
+        Interface I = new Interface("I", DefaultMethod.std("99"));
+        //workaround accessibility issue when loading C with DirectedClassLoader
+        I.addAccessFlag(AccessFlag.PUBLIC);
+        Class C = new Class("C", I);
+
+        Compiler.Flags[] flags = this.verbose ?
+            new Compiler.Flags[] { Compiler.Flags.VERBOSE } :
+            new Compiler.Flags[] {};
+        Compiler compiler = new Compiler(flags);
+        java.lang.Class<?> cls = null;
+        try {
+            cls = compiler.compileAndLoad(C);
+        } catch (ClassNotFoundException e) {
+            fail("Could not load class");
+        }
+
+        java.lang.reflect.Method method = null;
+        try {
+            method = cls.getMethod(stdMethodName);
+        } catch (NoSuchMethodException e) {
+            fail("Could not find method in class");
+        }
+        assertNotNull(method);
+
+        Object c = null;
+        try {
+            c = cls.newInstance();
+        } catch (InstantiationException | IllegalAccessException e) {
+            fail("Could not create instance of class");
+        }
+        assertNotNull(c);
+
+        Integer res = null;
+        try {
+            res = (Integer)method.invoke(c);
+        } catch (IllegalAccessException |
+                 java.lang.reflect.InvocationTargetException e) {
+            fail("Could not invoke default instance method");
+        }
+        assertNotNull(res);
+
+        assertEquals(res.intValue(), 99);
+
+        compiler.cleanup();
+    }
+
+    /**
+     * interface I<T,V,W> { default int m(T t, V v, W w) { return 99; } }
+     * interface J<T,V> extends I<String,T,V> { int m(T t, V v, String w); } }
+     * interface K<T> extends J<String,T> { int m(T t, String v, String w); } }
+     * class C implements K<String> {
+     *     public int m(String t, String v, String w) { return 88; }
+     * }
+     *
+     * TEST: I<String,String,String> i = new C(); i.m("A","B","C") == 88;
+     * TEST: J<String,String> j = new C(); j.m("A","B","C") == 88;
+     * TEST: K<String> k = new C(); k.m("A","B","C") == 88;
+     */
+    public void testBridges() {
+        DefaultMethod dm = new DefaultMethod("int", stdMethodName, "return 99;",
+            new MethodParameter("T", "t"), new MethodParameter("V", "v"),
+            new MethodParameter("W", "w"));
+
+        AbstractMethod pm0 = new AbstractMethod("int", stdMethodName,
+            new MethodParameter("T", "t"), new MethodParameter("V", "v"),
+            new MethodParameter("W", "w"));
+
+        AbstractMethod pm1 = new AbstractMethod("int", stdMethodName,
+            new MethodParameter("T", "t"), new MethodParameter("V", "v"),
+            new MethodParameter("String", "w"));
+
+        AbstractMethod pm2 = new AbstractMethod("int", stdMethodName,
+            new MethodParameter("T", "t"), new MethodParameter("String", "v"),
+            new MethodParameter("String", "w"));
+
+        ConcreteMethod cm = new ConcreteMethod("int",stdMethodName,"return 88;",
+            AccessFlag.PUBLIC,
+            new MethodParameter("String", "t"),
+            new MethodParameter("String", "v"),
+            new MethodParameter("String", "w"));
+
+        Interface I = new Interface("I", new TypeParameter("T"),
+            new TypeParameter("V"), new TypeParameter("W"), dm);
+        Interface J = new Interface("J",
+            new TypeParameter("T"), new TypeParameter("V"),
+            I.with("String", "T", "V"), pm1);
+        Interface K = new Interface("K", new TypeParameter("T"),
+            J.with("String", "T"), pm2);
+        Class C = new Class("C", K.with("String"), cm);
+
+        String[] args = new String[] { "\"A\"", "\"B\"", "\"C\"" };
+        assertInvokeInterfaceEquals(new Integer(88), C,
+            I.with("String", "String", "String"), pm0, args);
+        assertInvokeInterfaceEquals(new Integer(88), C,
+            J.with("String", "String"), pm1, args);
+        assertInvokeInterfaceEquals(new Integer(88), C,
+            K.with("String"), pm2, args);
+    }
+
+    /**
+     * interface J { default int m() { return 88; } }
+     * interface I extends J { default int m() { return J.super.m(); } }
+     * class C implements I {}
+     *
+     * TEST: C c = new C(); c.m() == 88;
+     * TEST: I i = new C(); i.m() == 88;
+     */
+    public void testSuperBasic() {
+        // debugTest();
+
+        Interface J = new Interface("J", DefaultMethod.std("88"));
+        Interface I = new Interface("I", J, new DefaultMethod(
+            "int", stdMethodName, "return J.super.m();"));
+        I.addCompilationDependency(J.findMethod(stdMethodName));
+        Class C = new Class("C", I);
+
+        assertInvokeVirtualEquals(88, C);
+        assertInvokeInterfaceEquals(88, C, I);
+    }
+
+    /**
+     * interface K { int m() default { return 99; } }
+     * interface L { int m() default { return 101; } }
+     * interface J extends K, L {}
+     * interface I extends J, K { int m() default { J.super.m(); } }
+     * class C implements I {}
+     *
+     * TEST: C c = new C(); c.m() throws AME
+     * TODO: add case for K k = new C(); k.m() throws AME
+     */
+    public void testSuperConflict() {
+        // debugTest();
+
+        Interface K = new Interface("K", DefaultMethod.std("99"));
+        Interface L = new Interface("L", DefaultMethod.std("101"));
+        Interface J = new Interface("J", K, L);
+        Interface I = new Interface("I", J, K, new DefaultMethod(
+            "int", stdMethodName, "return J.super.m();"));
+        Interface Jstub = new Interface("J", DefaultMethod.std("-1"));
+        I.addCompilationDependency(Jstub);
+        I.addCompilationDependency(Jstub.findMethod(stdMethodName));
+        Class C = new Class("C", I);
+
+        assertThrows(AbstractMethodError.class, C);
+    }
+
+    /**
+     * interface I { default int m() { return 99; } }
+     * interface J extends I { default int m() { return 55; } }
+     * class C implements I, J { public int m() { return I.super.m(); } }
+     *
+     * TEST: C c = new C(); c.m() throws AME
+     * TODO: add case for J j = new C(); j.m() throws AME
+     */
+    public void testSuperDisqual() {
+        Interface I = new Interface("I", DefaultMethod.std("99"));
+        Interface J = new Interface("J", I, DefaultMethod.std("55"));
+        Class C = new Class("C", I, J,
+            new ConcreteMethod("int", stdMethodName, "return I.super.m();",
+                AccessFlag.PUBLIC));
+        C.addCompilationDependency(I.findMethod(stdMethodName));
+
+        assertThrows(AbstractMethodError.class, C);
+    }
+
+    /**
+     * interface J { int m(); }
+     * interface I extends J { default int m() { return J.super.m(); } }
+     * class C implements I {}
+     *
+     * TEST: C c = new C(); c.m() throws AME
+     * TODO: add case for I i = new C(); i.m() throws AME
+     */
+    public void testSuperNull() {
+        Interface J = new Interface("J", AbstractMethod.std());
+        Interface I = new Interface("I", J, new DefaultMethod(
+            "int", stdMethodName, "return J.super.m();"));
+        Interface Jstub = new Interface("J", DefaultMethod.std("99"));
+        I.addCompilationDependency(Jstub);
+        I.addCompilationDependency(Jstub.findMethod(stdMethodName));
+        Class C = new Class("C", I);
+
+        assertThrows(AbstractMethodError.class, C);
+    }
+
+    /**
+     * interface J<T> { default int m(T t) { return 88; } }
+     * interface I extends J<String> {
+     *     int m(String s) default { return J.super.m(); }
+     * }
+     * class C implements I {}
+     *
+     * TEST: I i = new C(); i.m("") == 88;
+     */
+    public void testSuperGeneric() {
+        Interface J = new Interface("J", new TypeParameter("T"),
+            new DefaultMethod("int", stdMethodName, "return 88;",
+                new MethodParameter("T", "t")));
+        Interface I = new Interface("I", J.with("String"),
+            new DefaultMethod("int", stdMethodName, "return J.super.m(s);",
+                new MethodParameter("String", "s")));
+        I.addCompilationDependency(J.findMethod(stdMethodName));
+        Class C = new Class("C", I);
+
+        AbstractMethod pm = new AbstractMethod("int", stdMethodName,
+            new MethodParameter("String", "s"));
+
+        assertInvokeInterfaceEquals(
+            new Integer(88), C, new Extends(I), pm, "\"\"");
+    }
+
+    /**
+     * interface I<T> { int m(T t) default { return 44; } }
+     * interface J extends I<String> { int m(String s) default { return 55; } }
+     * class C implements I<String>, J {
+     *     public int m(String s) { return I.super.m(s); }
+     * }
+     *
+     * TEST: C c = new C(); c.m("string") throws AME
+     */
+    public void testSuperGenericDisqual() {
+        MethodParameter t = new MethodParameter("T", "t");
+        MethodParameter s = new MethodParameter("String", "s");
+
+        Interface I = new Interface("I", new TypeParameter("T"),
+            new DefaultMethod("int", stdMethodName, "return 44;", t));
+        Interface J = new Interface("J", I.with("String"),
+            new DefaultMethod("int", stdMethodName, "return 55;", s));
+        Class C = new Class("C", I.with("String"), J,
+            new ConcreteMethod("int", stdMethodName,
+                "return I.super.m(s);", AccessFlag.PUBLIC, s));
+        C.addCompilationDependency(I.findMethod(stdMethodName));
+
+        assertThrows(AbstractMethodError.class, C,
+            new ConcreteMethod(
+                "int", stdMethodName, "return -1;", AccessFlag.PUBLIC, s),
+            "-1", "\"string\"");
+    }
+
+    /**
+     * interface I { default Integer m() { return new Integer(88); } }
+     * class C { Number m() { return new Integer(99); } }
+     * class D extends C implements I {}
+     * class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger;
+     * TEST: S s = new S(); s.foo() == new Integer(99)
+     */
+    public void testCovarBridge() {
+        Interface I = new Interface("I", new DefaultMethod(
+            "Integer", "m", "return new Integer(88);"));
+        Class C = new Class("C", new ConcreteMethod(
+            "Number", "m", "return new Integer(99);", AccessFlag.PUBLIC));
+        Class D = new Class("D", I, C);
+
+        ConcreteMethod DstubMethod = new ConcreteMethod(
+            "Integer", "m", "return null;", AccessFlag.PUBLIC);
+        Class Dstub = new Class("D", DstubMethod);
+
+        ConcreteMethod toCall = new ConcreteMethod(
+            "Object", "foo", "return (new D()).m();", AccessFlag.PUBLIC);
+        Class S = new Class("S", D, toCall);
+        S.addCompilationDependency(Dstub);
+        S.addCompilationDependency(DstubMethod);
+
+        assertInvokeVirtualEquals(new Integer(99), S, toCall, "null");
+    }
+
+    /**
+     * interface I { default Integer m() { return new Integer(88); } }
+     * class C { int m() { return 99; } }
+     * class D extends C implements I {}
+     * class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger;
+     * TEST: S s = new S(); s.foo() == new Integer(88)
+     */
+    public void testNoCovarNoBridge() {
+        Interface I = new Interface("I", new DefaultMethod(
+            "Integer", "m", "return new Integer(88);"));
+        Class C = new Class("C", new ConcreteMethod(
+            "int", "m", "return 99;", AccessFlag.PUBLIC));
+        Class D = new Class("D", I, C);
+
+        ConcreteMethod DstubMethod = new ConcreteMethod(
+            "Integer", "m", "return null;", AccessFlag.PUBLIC);
+        Class Dstub = new Class("D", DstubMethod);
+
+        ConcreteMethod toCall = new ConcreteMethod(
+            "Object", "foo", "return (new D()).m();", AccessFlag.PUBLIC);
+        Class S = new Class("S", D, toCall);
+        S.addCompilationDependency(Dstub);
+        S.addCompilationDependency(DstubMethod);
+
+        assertInvokeVirtualEquals(new Integer(88), S, toCall, "null");
+    }
+
+    /**
+     * interface J { int m(); }
+     * interface I extends J { default int m() { return 99; } }
+     * class B implements J {}
+     * class C extends B implements I {}
+     * TEST: C c = new C(); c.m() == 99
+     *
+     * The point of this test is that B does not get default method analysis,
+     * and C does not generate any new miranda methods in the vtable.
+     * It verifies that default method analysis occurs when mirandas have been
+     * inherited and the supertypes don't have any overpass methods.
+     */
+    public void testNoNewMiranda() {
+        Interface J = new Interface("J", AbstractMethod.std());
+        Interface I = new Interface("I", J, DefaultMethod.std("99"));
+        Class B = new Class("B", J);
+        Class C = new Class("C", B, I);
+        assertInvokeVirtualEquals(99, C);
+    }
+
+    /**
+     * interface I<T,V,W> { int m(T t, V v, W w); }
+     * interface J<T,V> implements I<T,V,String> { int m(T t, V v, String w); }
+     * interface K<T> implements J<T,String> {
+     *     int m(T t, String v, String w); { return 99; } }
+     * class C implements K<String> {
+     *     public int m(Object t, Object v, String w) { return 77; }
+     * }
+     * TEST C = new C(); ((I)c).m(Object,Object,Object) == 99
+     * TEST C = new C(); ((J)c).m(Object,Object,String) == 77
+     * TEST C = new C(); ((K)c).m(Object,String,String) == 99
+     *
+     * Test that a erased-signature-matching method does not implement
+     * non-language-level matching methods
+     */
+    public void testNonConcreteFill() {
+        AbstractMethod ipm = new AbstractMethod("int", "m",
+            new MethodParameter("T", "t"),
+            new MethodParameter("V", "s"),
+            new MethodParameter("W", "w"));
+        Interface I = new Interface("I",
+            new TypeParameter("T"),
+            new TypeParameter("V"),
+            new TypeParameter("W"), ipm);
+
+        AbstractMethod jpm = new AbstractMethod("int", "m",
+            new MethodParameter("T", "t"),
+            new MethodParameter("V", "s"),
+            new MethodParameter("String", "w"));
+        Interface J = new Interface("J",
+            new TypeParameter("T"),
+            new TypeParameter("V"),
+            I.with("T", "V", "String"), jpm);
+
+        AbstractMethod kpm = new AbstractMethod("int", "m",
+            new MethodParameter("T", "t"),
+            new MethodParameter("String", "s"),
+            new MethodParameter("String", "w"));
+        Interface K = new Interface("K",
+            new TypeParameter("T"),
+            J.with("T", "String"),
+            new DefaultMethod("int", "m", "return 99;",
+                new MethodParameter("T", "t"),
+                new MethodParameter("String", "v"),
+                new MethodParameter("String", "w")));
+
+        Class C = new Class("C",
+            K.with("String"),
+            new ConcreteMethod("int", "m", "return 77;",
+                AccessFlag.PUBLIC,
+                new MethodParameter("Object", "t"),
+                new MethodParameter("Object", "v"),
+                new MethodParameter("String", "w")));
+
+        String a = "\"\"";
+        assertInvokeInterfaceEquals(99, C,
+            K.with("String"), kpm, a, a, a);
+        assertInvokeInterfaceEquals(77, C,
+            J.with("String", "String"), jpm, a, a, a);
+        assertInvokeInterfaceEquals(99, C,
+            I.with("String", "String", "String"), ipm, a, a, a);
+    }
+
+    public void testStrictfpDefault() {
+        try {
+            java.lang.Class.forName("vm.StrictfpDefault");
+        } catch (Exception e) {
+            fail("Could not load class", e);
+        }
+    }
+}
diff --git a/jdk/test/jdk/lambda/vm/InterfaceAccessFlagsTest.java b/jdk/test/jdk/lambda/vm/InterfaceAccessFlagsTest.java
new file mode 100644
index 0000000..b08e67c
--- /dev/null
+++ b/jdk/test/jdk/lambda/vm/InterfaceAccessFlagsTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package vm;
+
+import java.io.*;
+
+import org.testng.annotations.Test;
+import separate.*;
+import separate.Compiler;
+
+import static org.testng.Assert.*;
+import static separate.SourceModel.*;
+import static separate.SourceModel.Class;
+
+public class InterfaceAccessFlagsTest extends TestHarness {
+    public InterfaceAccessFlagsTest() {
+        super(false, false);
+    }
+
+    public void testMethodCallWithFlag(AccessFlag ... flags) {
+        Class I = new Class("I",
+            new ConcreteMethod("int", "m", "return priv();", AccessFlag.PUBLIC),
+            new ConcreteMethod("int", "priv", "return 99;", flags));
+        Interface Istub = new Interface("I",
+            new DefaultMethod("int", "m", "return 0;"));
+        Class C = new Class("C", Istub,
+            new ConcreteMethod("int", "foo", "return (new C()).m();",
+                AccessFlag.PUBLIC, AccessFlag.STATIC));
+        C.addCompilationDependency(Istub.findMethod("m"));
+
+        Compiler compiler = new Compiler(/*Compiler.Flags.VERBOSE*/);
+        compiler.addPostprocessor(new ClassToInterfaceConverter("I"));
+        // Turns I from a class into an interface when loading
+
+        ClassLoader cl = compiler.compile(C, I);
+        try {
+            java.lang.Class<?> C_class =
+                java.lang.Class.forName("C", true, cl);
+            assertNotNull(C_class);
+            java.lang.reflect.Method m = C_class.getMethod("foo");
+            assertNotNull(m);
+            Integer res = (Integer)m.invoke(null);
+            assertEquals(res.intValue(), 99);
+        } catch (java.lang.reflect.InvocationTargetException e) {
+            fail("Unexpected exception: " + e.getCause());
+        } catch (Throwable e) {
+            fail("Unexpected exception: " + e);
+        } finally {
+            compiler.cleanup();
+        }
+    }
+
+    @Test(groups = "vm_prototype")
+    public void testPrivateMethodCall() {
+        testMethodCallWithFlag(AccessFlag.PRIVATE);
+    }
+
+    @Test(groups = "vm_prototype")
+    public void testStaticMethodCall() {
+        testMethodCallWithFlag(AccessFlag.PUBLIC, AccessFlag.STATIC);
+    }
+
+    @Test(groups = "vm_prototype")
+    public void testPrivateStaticMethodCall() {
+        testMethodCallWithFlag(AccessFlag.PRIVATE, AccessFlag.STATIC);
+    }
+
+    // Test other combos?  Protected?
+}
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java b/jdk/test/jdk/lambda/vm/StrictfpDefault.java
similarity index 76%
copy from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
copy to jdk/test/jdk/lambda/vm/StrictfpDefault.java
index 06196c2..9b7e168 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
+++ b/jdk/test/jdk/lambda/vm/StrictfpDefault.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,16 +21,12 @@
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
+package vm;
 
-@GenerateNativeHeader
-public class TestClass2 {
-    byte b;
-    short s;
-    int i;
-    long l;
-    float f;
-    double d;
-    Object o;
-    String t;
+/*
+* @test
+* @ignore
+*/
+interface StrictfpDefault {
+    default strictfp void m() {}
 }
diff --git a/jdk/test/sun/misc/JavaLangAccess/NewUnsafeString.java b/jdk/test/sun/misc/JavaLangAccess/NewUnsafeString.java
new file mode 100644
index 0000000..930d57b
--- /dev/null
+++ b/jdk/test/sun/misc/JavaLangAccess/NewUnsafeString.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Objects;
+import java.util.Comparators;
+import sun.misc.JavaLangAccess;
+import sun.misc.SharedSecrets;
+
+/*
+ * @test
+ * @summary Test JavaLangAccess.newUnsafeString
+ * @bug 8013528
+ * @compile -XDignore.symbol.file NewUnsafeString.java
+ */
+public class NewUnsafeString {
+
+    static final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
+
+    public static void testNewUnsafeString() {
+        String benchmark = "exemplar";
+        String constructorCopy = new String(benchmark);
+        char[] jlaChars = benchmark.toCharArray();
+        String jlaCopy = jla.newStringUnsafe(jlaChars);
+
+        if (benchmark == constructorCopy) {
+            throw new Error("should be different instances");
+        }
+        if (!benchmark.equals(constructorCopy)) {
+            throw new Error("Copy not equal");
+        }
+        if (0 != Objects.compare(benchmark, constructorCopy, Comparators.naturalOrder())) {
+            throw new Error("Copy not equal");
+        }
+
+        if (benchmark == jlaCopy) {
+            throw new Error("should be different instances");
+        }
+        if (!benchmark.equals(jlaCopy)) {
+            throw new Error("Copy not equal");
+        }
+        if (0 != Objects.compare(benchmark, jlaCopy, Comparators.naturalOrder())) {
+            throw new Error("Copy not equal");
+        }
+
+        if (constructorCopy == jlaCopy) {
+            throw new Error("should be different instances");
+        }
+        if (!constructorCopy.equals(jlaCopy)) {
+            throw new Error("Copy not equal");
+        }
+        if (0 != Objects.compare(constructorCopy, jlaCopy, Comparators.naturalOrder())) {
+            throw new Error("Copy not equal");
+        }
+
+        // The following is extremely "evil". Never ever do this in non-test code.
+        jlaChars[0] = 'X';
+        if (!"Xxemplar".equals(jlaCopy)) {
+            throw new Error("jla.newStringUnsafe did not use provided string");
+        }
+
+    }
+
+    public static void main(String[] args) {
+        testNewUnsafeString();
+    }
+}
diff --git a/jdk/test/sun/net/www/protocol/http/B6299712.java b/jdk/test/sun/net/www/protocol/http/B6299712.java
index 2cdedcb..1f87acc 100644
--- a/jdk/test/sun/net/www/protocol/http/B6299712.java
+++ b/jdk/test/sun/net/www/protocol/http/B6299712.java
@@ -23,33 +23,33 @@
 
 /*
  * @test
- * @bug 6299712
- * @library ../../httptest/
- * @build HttpCallback TestHttpServer ClosedChannelList HttpTransaction
+ * @bug 6299712 7150552
  * @run main/othervm B6299712
  * @summary  NullPointerException in sun.net.www.protocol.http.HttpURLConnection.followRedirect
  */
 
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
 import java.net.*;
 import java.io.*;
 import java.util.*;
 
 /*
  * Test Description:
- *      - main thread run as a http client
- *      - another thread runs a http server, which redirect the first call to "/redirect"
- *        and return '200 OK' for the successive call
- *      - a global ResponseCache instance is installed, which return DeployCacheResponse
- *        for url ends with "/redirect", i.e. the url redirected to by our simple http server,
- *        and null for other url.
+ *      - main thread is run as a http client
+ *      - another thread runs an http server, which redirects calls to "/" to
+ *        "/redirect" and returns '200 OK' for the successive call
+ *      - a global ResponseCache instance is installed, which returns DeployCacheResponse
+ *        for urls that end with "/redirect", i.e. the url redirected to by our simple http server,
+ *        and null for other urls.
  *      - the whole result is that the first call will be served by our simple
  *        http server and is redirected to "/redirect". The successive call will be done
  *        automatically by HttpURLConnection, which will be served by DeployCacheResponse.
  *        The NPE will be thrown on the second round if the bug is there.
  */
 public class B6299712 {
-    static SimpleHttpTransaction httpTrans;
-    static TestHttpServer server;
+    static HttpServer server;
 
     public static void main(String[] args) throws Exception {
         ResponseCache.setDefault(new DeployCacheHandler());
@@ -58,123 +58,119 @@
         makeHttpCall();
     }
 
-    public static void startHttpServer() {
-        try {
-            httpTrans = new SimpleHttpTransaction();
-            server = new TestHttpServer(httpTrans, 1, 10, 0);
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
+    public static void startHttpServer() throws IOException {
+        server = HttpServer.create(new InetSocketAddress(0), 0);
+        server.createContext("/", new DefaultHandler());
+        server.createContext("/redirect", new RedirectHandler());
+        server.start();
     }
 
-    public static void makeHttpCall() {
+    public static void makeHttpCall() throws IOException {
         try {
-            System.out.println("http server listen on: " + server.getLocalPort());
-            URL url = new URL("http" , InetAddress.getLocalHost().getHostAddress(),
-                                server.getLocalPort(), "/");
+            System.out.println("http server listen on: "
+                    + server.getAddress().getPort());
+            URL url = new URL("http",
+                               InetAddress.getLocalHost().getHostAddress(),
+                               server.getAddress().getPort(), "/");
             HttpURLConnection uc = (HttpURLConnection)url.openConnection();
-            System.out.println(uc.getResponseCode());
-        } catch (IOException e) {
-            e.printStackTrace();
+            if (uc.getResponseCode() != 200)
+                throw new RuntimeException("Expected Response Code was 200,"
+                        + "received: " + uc.getResponseCode());
+            uc.disconnect();
         } finally {
-            server.terminate();
+            server.stop(0);
         }
     }
-}
 
-class SimpleHttpTransaction implements HttpCallback {
-    /*
-     * Our http server which simply redirect first call
-     */
-    public void request(HttpTransaction trans) {
-        try {
-            String path = trans.getRequestURI().getPath();
-            if (path.equals("/")) {
-                // the first call, redirect it
-                String location = "/redirect";
-                trans.addResponseHeader("Location", location);
-                trans.sendResponse(302, "Moved Temporarily");
-            } else {
-                // the second call
-                trans.sendResponse(200, "OK");
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
+    static class RedirectHandler implements HttpHandler {
+
+        @Override
+        public void handle(HttpExchange exchange) throws IOException {
+            exchange.sendResponseHeaders(200, -1);
+            exchange.close();
         }
+
     }
-}
 
-class DeployCacheHandler extends java.net.ResponseCache {
-    private boolean inCacheHandler = false;
-    private boolean _downloading = false;
+    static class DefaultHandler implements HttpHandler {
 
-    public synchronized CacheResponse get(final URI uri, String rqstMethod,
-            Map requestHeaders) throws IOException {
-        System.out.println("get!!!: " + uri);
-        try {
+        @Override
+        public void handle(HttpExchange exchange) throws IOException {
+            exchange.getResponseHeaders().add("Location", "/redirect");
+            exchange.sendResponseHeaders(302, -1);
+            exchange.close();
+        }
+
+    }
+
+    static class DeployCacheHandler extends java.net.ResponseCache {
+
+        public synchronized CacheResponse get(final URI uri, String rqstMethod,
+                Map<String, List<String>> requestHeaders) throws IOException
+        {
+            System.out.println("get!!!: " + uri);
             if (!uri.toString().endsWith("redirect")) {
                 return null;
             }
-        } catch (Exception e) {
-            e.printStackTrace();
+            System.out.println("Serving request from cache");
+            return new DeployCacheResponse(new EmptyInputStream(),
+                                           new HashMap<String, List<String>>());
         }
 
-        return new DeployCacheResponse(new EmptyInputStream(), new HashMap());
+        public synchronized CacheRequest put(URI uri, URLConnection conn)
+            throws IOException
+        {
+            URL url = uri.toURL();
+            return new DeployCacheRequest(url, conn);
+
+        }
     }
 
-    public synchronized CacheRequest put(URI uri, URLConnection conn)
-    throws IOException {
-        URL url = uri.toURL();
-        return new DeployCacheRequest(url, conn);
+    static class DeployCacheRequest extends java.net.CacheRequest {
 
-    }
-}
+        private URL _url;
+        private URLConnection _conn;
 
-class DeployCacheRequest extends java.net.CacheRequest {
+        DeployCacheRequest(URL url, URLConnection conn) {
+            _url = url;
+            _conn = conn;
+        }
 
-    private URL _url;
-    private URLConnection _conn;
-    private boolean _downloading = false;
+        public void abort() {
 
-    DeployCacheRequest(URL url, URLConnection conn) {
-        _url = url;
-        _conn = conn;
+        }
+
+        public OutputStream getBody() throws IOException {
+
+            return null;
+        }
     }
 
-    public void abort() {
+    static class DeployCacheResponse extends java.net.CacheResponse {
+        protected InputStream is;
+        protected Map<String, List<String>> headers;
 
+        DeployCacheResponse(InputStream is, Map<String, List<String>> headers) {
+            this.is = is;
+            this.headers = headers;
+        }
+
+        public InputStream getBody() throws IOException {
+            return is;
+        }
+
+        public Map<String, List<String>> getHeaders() throws IOException {
+            List<String> val = new ArrayList<>();
+            val.add("HTTP/1.1 200 OK");
+            headers.put(null, val);
+            return headers;
+        }
     }
 
-    public OutputStream getBody() throws IOException {
+    static class EmptyInputStream extends InputStream {
 
-        return null;
-    }
-}
-
-class DeployCacheResponse extends java.net.CacheResponse {
-    protected InputStream is;
-    protected Map headers;
-
-    DeployCacheResponse(InputStream is, Map headers) {
-        this.is = is;
-        this.headers = headers;
-    }
-
-    public InputStream getBody() throws IOException {
-        return is;
-    }
-
-    public Map getHeaders() throws IOException {
-        return headers;
-    }
-}
-
-class EmptyInputStream extends InputStream {
-    public EmptyInputStream() {
-    }
-
-    public int read()
-    throws IOException {
-        return -1;
+        public int read() throws IOException {
+            return -1;
+        }
     }
 }
diff --git a/jdk/test/sun/net/www/protocol/http/B8012625.java b/jdk/test/sun/net/www/protocol/http/B8012625.java
new file mode 100644
index 0000000..c8c8ef0
--- /dev/null
+++ b/jdk/test/sun/net/www/protocol/http/B8012625.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8012625
+ * @run main B8012625
+ */
+
+import java.net.*;
+import java.io.*;
+
+import java.net.*;
+import java.io.*;
+import java.util.concurrent.*;
+import com.sun.net.httpserver.*;
+
+public class B8012625 implements HttpHandler {
+
+    public static void main (String[] args) throws Exception {
+        B8012625 test = new B8012625();
+        test.run();
+    }
+
+    public void run() throws Exception {
+        String u = "http://127.0.0.1:" + port + "/foo";
+        URL url = new URL(u);
+        HttpURLConnection uc = (HttpURLConnection)url.openConnection();
+        uc.setDoOutput(true);
+        uc.setRequestMethod("POST");
+        uc.addRequestProperty("Expect", "100-Continue");
+        //uc.setFixedLengthStreamingMode(256);
+        System.out.println ("Client: getting outputstream");
+        long before = System.currentTimeMillis();
+        OutputStream os = uc.getOutputStream();
+        long after = System.currentTimeMillis();
+        System.out.println ("Client: writing to outputstream");
+        byte[] buf = new byte[256];
+        os.write(buf);
+        System.out.println ("Client: done writing ");
+        int r = uc.getResponseCode();
+        System.out.println ("Client: received response code " + r);
+        server.stop(1);
+        ex.shutdownNow();
+        if (after - before >= 5000) {
+            throw new RuntimeException("Error: 5 second delay seen");
+        }
+    }
+
+    int port;
+    HttpServer server;
+    ExecutorService ex;
+
+    public B8012625 () throws Exception {
+        server = HttpServer.create(new InetSocketAddress(0), 10);
+        HttpContext ctx = server.createContext("/", this);
+        ex = Executors.newFixedThreadPool(5);
+        server.setExecutor(ex);
+        server.start();
+        port = server.getAddress().getPort();
+   }
+
+    public void handle(HttpExchange ex) throws IOException {
+        String s = ex.getRequestMethod();
+        if (!s.equals("POST")) {
+            ex.getResponseHeaders().set("Allow", "POST");
+            ex.sendResponseHeaders(500, -1);
+            ex.close();
+            return;
+        }
+        System.out.println ("Server: reading request body");
+        InputStream is = ex.getRequestBody();
+        // read request
+        byte[] buf = new byte [1024];
+        while (is.read(buf) != -1) ;
+        is.close();
+        ex.sendResponseHeaders(200, -1);
+        ex.close();
+   }
+}
diff --git a/jdk/test/sun/security/krb5/auto/DupEtypes.java b/jdk/test/sun/security/krb5/auto/DupEtypes.java
index 92da74b..cb4f32d 100644
--- a/jdk/test/sun/security/krb5/auto/DupEtypes.java
+++ b/jdk/test/sun/security/krb5/auto/DupEtypes.java
@@ -34,6 +34,7 @@
  */
 
 import sun.security.jgss.GSSUtil;
+import sun.security.krb5.Config;
 
 public class DupEtypes {
 
@@ -42,6 +43,14 @@
         OneKDC kdc = new OneKDC(null);
         kdc.writeJAASConf();
 
+        KDC.saveConfig(OneKDC.KRB5_CONF, kdc,
+                "default_keytab_name = " + OneKDC.KTAB,
+                "allow_weak_crypto = true");
+        Config.refresh();
+
+        // Rewrite to include DES keys
+        kdc.writeKtab(OneKDC.KTAB);
+
         // Different test cases, read KDC.processAsReq for details
         kdc.setOption(KDC.Option.DUP_ETYPE, Integer.parseInt(args[0]));
 
diff --git a/jdk/test/sun/security/krb5/etype/WeakCrypto.java b/jdk/test/sun/security/krb5/etype/WeakCrypto.java
index 8f0ec37..459e10c 100644
--- a/jdk/test/sun/security/krb5/etype/WeakCrypto.java
+++ b/jdk/test/sun/security/krb5/etype/WeakCrypto.java
@@ -22,29 +22,41 @@
  */
 /*
  * @test
- * @bug 6844909
+ * @bug 6844909 8012679
  * @run main/othervm WeakCrypto
+ * @run main/othervm WeakCrypto true
+ * @run main/othervm WeakCrypto false
  * @summary support allow_weak_crypto in krb5.conf
  */
 
 import java.io.File;
+import java.lang.Exception;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
 import sun.security.krb5.internal.crypto.EType;
 import sun.security.krb5.EncryptedData;
 
 public class WeakCrypto {
     public static void main(String[] args) throws Exception {
-        System.setProperty("java.security.krb5.conf",
-                System.getProperty("test.src", ".") +
-                File.separator +
-                "weakcrypto.conf");
+        String conf = "[libdefaults]\n" +
+                (args.length > 0 ? ("allow_weak_crypto = " + args[0]) : "");
+        Files.write(Paths.get("krb5.conf"), conf.getBytes());
+        System.setProperty("java.security.krb5.conf", "krb5.conf");
+
+        boolean expected = args.length != 0 && args[0].equals("true");
         int[] etypes = EType.getBuiltInDefaults();
 
+        boolean found = false;
         for (int i=0, length = etypes.length; i<length; i++) {
             if (etypes[i] == EncryptedData.ETYPE_DES_CBC_CRC ||
                     etypes[i] == EncryptedData.ETYPE_DES_CBC_MD4 ||
                     etypes[i] == EncryptedData.ETYPE_DES_CBC_MD5) {
-                throw new Exception("DES should not appear");
+                found = true;
             }
         }
+        if (expected != found) {
+            throw new Exception();
+        }
     }
 }
diff --git a/jdk/test/sun/security/krb5/runNameEquals.sh b/jdk/test/sun/security/krb5/runNameEquals.sh
index 1c3dca3..6db90c3 100644
--- a/jdk/test/sun/security/krb5/runNameEquals.sh
+++ b/jdk/test/sun/security/krb5/runNameEquals.sh
@@ -52,15 +52,11 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     PATHSEP=":"
     FILESEP="/"
     NATIVE=true
     ;;
-  Darwin )
-    PATHSEP=":"
-    FILESEP="/"
-    ;;
   CYGWIN* )
     PATHSEP=";"
     FILESEP="/"
diff --git a/jdk/test/sun/security/pkcs11/Cipher/TestSymmCiphersNoPad.java b/jdk/test/sun/security/pkcs11/Cipher/TestSymmCiphersNoPad.java
index 5f94ea4..a8b71a3 100644
--- a/jdk/test/sun/security/pkcs11/Cipher/TestSymmCiphersNoPad.java
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestSymmCiphersNoPad.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 4898484 6604496
+ * @bug 4898484 6604496 8001284
  * @summary basic test for symmetric ciphers with no padding
  * @author Valerie Peng
  * @library ..
@@ -60,7 +60,8 @@
         new CI("DESede/CBC/NoPadding", "DESede", 160),
         new CI("AES/CBC/NoPadding", "AES", 4800),
         new CI("Blowfish/CBC/NoPadding", "Blowfish", 24),
-        new CI("AES/CTR/NoPadding", "AES", 1600)
+        new CI("AES/CTR/NoPadding", "AES", 1600),
+        new CI("AES/CTR/NoPadding", "AES", 65)
     };
 
     private static StringBuffer debugBuf;
@@ -182,6 +183,29 @@
         debugBuf.append("(post) outputBuf: " + outDirectBuf + "\n");
         match(outDirectBuf, answer);
 
+        // test#6: Streams
+        debugBuf.append("Test#6: Streaming\n");
+        outBuf.position(0);
+        InputStream stream =
+            new CipherInputStream(new ByteArrayInputStream(in), cipher);
+        byte[] data = new byte[1024];
+        int bytesRead = 0;
+        try {
+            while (bytesRead >= 0) {
+                bytesRead = stream.read(data);
+                if (bytesRead == -1)
+                    break;
+                debugBuf.append("bytesRead: " + bytesRead);
+                debugBuf.append("\toutBuf.position(): " + outBuf.position() +
+                    "\n");
+                outBuf.put(data, 0 , bytesRead);
+            }
+        } catch (Exception ex) {
+            debugBuf.append("Caught Exception during stream reading\n");
+            throw ex;
+        }
+        match(outBuf, answer);
+
         debugBuf = null;
     }
 
diff --git a/jdk/test/sun/security/pkcs11/Provider/ConfigShortPath.java b/jdk/test/sun/security/pkcs11/Provider/ConfigShortPath.java
index 21238f7..030e420 100644
--- a/jdk/test/sun/security/pkcs11/Provider/ConfigShortPath.java
+++ b/jdk/test/sun/security/pkcs11/Provider/ConfigShortPath.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,8 +22,8 @@
  */
 /**
  * @test
- * @bug 6581254 6986789
- * @summary Allow '~' and '+' in config file
+ * @bug 6581254 6986789 7196009
+ * @summary Allow '~', '+' and quoted paths in config file
  * @author Valerie Peng
  */
 
@@ -33,7 +33,9 @@
 
 public class ConfigShortPath {
 
-    private static final String[] configNames = { "csp.cfg", "cspPlus.cfg" };
+    private static final String[] configNames = {
+        "csp.cfg", "cspPlus.cfg", "cspQuotedPath.cfg"
+    };
 
     public static void main(String[] args) throws Exception {
         Constructor cons = null;
@@ -53,12 +55,22 @@
                 Object obj = cons.newInstance(configFile);
             } catch (InvocationTargetException ite) {
                 Throwable cause = ite.getCause();
+                System.out.println(cause);
                 if (cause instanceof ProviderException) {
-                    String causeMsg = cause.getCause().getMessage();
-                    // Indicate failure if due to parsing config
-                    if (causeMsg.indexOf("Unexpected token") != -1) {
-                        throw (ProviderException) cause;
+                    while ((cause = cause.getCause()) != null) {
+                        System.out.println(cause);
+                        String causeMsg = cause.getMessage();
+                        // Indicate failure if due to parsing config
+                        if (causeMsg.indexOf("Unexpected") != -1) {
+                            throw (ProviderException) cause;
+                        }
                     }
+                    // Consider the test passes if the exception is
+                    // thrown after parsing, i.e. due to the absolute
+                    // path requirement or the non-existent path.
+                } else {
+                    // unexpected exception
+                    throw new RuntimeException("Unexpected Exception", cause);
                 }
             }
         }
diff --git a/jdk/test/sun/security/pkcs11/Provider/cspQuotedPath.cfg b/jdk/test/sun/security/pkcs11/Provider/cspQuotedPath.cfg
new file mode 100644
index 0000000..fee4cd2
--- /dev/null
+++ b/jdk/test/sun/security/pkcs11/Provider/cspQuotedPath.cfg
@@ -0,0 +1,6 @@
+showInfo = false
+name=GemPlusPKCS11
+library="C:\\Program Files (x86)\\Gemalto\\Classic Client\\BIN\\gclib.dll"
+attributes(*,CKO_PRIVATE_KEY,*) = {
+  CKA_SIGN = true
+}
diff --git a/jdk/test/sun/security/pkcs11/ec/TestCurves.java b/jdk/test/sun/security/pkcs11/ec/TestCurves.java
index aa19e33..69a3743 100644
--- a/jdk/test/sun/security/pkcs11/ec/TestCurves.java
+++ b/jdk/test/sun/security/pkcs11/ec/TestCurves.java
@@ -38,9 +38,6 @@
 
 import javax.crypto.*;
 
-// XXX no public API to enumerate supported named curves
-import sun.security.ec.NamedCurve;
-
 public class TestCurves extends PKCS11Test {
 
     public static void main(String[] args) throws Exception {
@@ -57,8 +54,8 @@
         byte[] data = new byte[2048];
         random.nextBytes(data);
 
-        Collection<? extends ECParameterSpec> curves =
-            NamedCurve.knownECParameterSpecs();
+        Vector<ECParameterSpec> curves = getKnownCurves(p);
+
         for (ECParameterSpec params : curves) {
             System.out.println("Testing " + params + "...");
             KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", p);
@@ -92,6 +89,66 @@
         System.out.println("OK");
     }
 
+    private static Vector<ECParameterSpec>
+            getKnownCurves(Provider p) throws Exception {
+
+        int index;
+        int begin;
+        int end;
+        String curve;
+        Vector<ECParameterSpec> results = new Vector<ECParameterSpec>();
+        String kcProp =
+            p.getProperty("AlgorithmParameters.EC SupportedCurves");
+
+        if (kcProp == null) {
+            throw new RuntimeException(
+            "\"AlgorithmParameters.EC SupportedCurves property\" not found");
+        }
+
+        index = 0;
+        for (;;) {
+            // Each set of curve names is enclosed with brackets.
+            begin = kcProp.indexOf('[', index);
+            end = kcProp.indexOf(']', index);
+            if (begin == -1 || end == -1) {
+                break;
+            }
+
+            /*
+             * Each name is separated by a comma.
+             * Just get the first name in the set.
+             */
+            index = end + 1;
+            begin++;
+            end = kcProp.indexOf(',', begin);
+            if (end == -1) {
+                // Only one name in the set.
+                end = index -1;
+            }
+
+            curve = kcProp.substring(begin, end);
+
+            results.add(getECParameterSpec(p, curve));
+        }
+
+        if (results.size() == 0) {
+            throw new RuntimeException("No supported EC curves found");
+        }
+
+        return results;
+    }
+
+    private static ECParameterSpec getECParameterSpec(Provider p, String name)
+            throws Exception {
+
+        AlgorithmParameters parameters =
+            AlgorithmParameters.getInstance("EC", p);
+
+        parameters.init(new ECGenParameterSpec(name));
+
+        return parameters.getParameterSpec(ECParameterSpec.class);
+    }
+
     private static void testSigning(Provider p, String algorithm,
             byte[] data, KeyPair kp1, KeyPair kp2) throws Exception {
         // System.out.print("  " + algorithm);
@@ -115,6 +172,4 @@
             throw new Exception("Signature should not verify");
         }
     }
-
-
 }
diff --git a/jdk/test/sun/security/pkcs11/ec/TestECDH2.java b/jdk/test/sun/security/pkcs11/ec/TestECDH2.java
index 21d1490..c30cb5a 100644
--- a/jdk/test/sun/security/pkcs11/ec/TestECDH2.java
+++ b/jdk/test/sun/security/pkcs11/ec/TestECDH2.java
@@ -41,7 +41,7 @@
 import java.security.interfaces.*;
 import javax.crypto.*;
 
-import sun.security.ec.NamedCurve;
+import sun.security.util.ECUtil;
 
 public class TestECDH2 extends PKCS11Test {
 
@@ -79,8 +79,8 @@
     }
 
     private KeyPair genECKeyPair(String curvName, String privD, String pubX,
-                                 String pubY) throws Exception {
-        ECParameterSpec ecParams = NamedCurve.getECParameterSpec(curvName);
+                                 String pubY, Provider p) throws Exception {
+        ECParameterSpec ecParams = ECUtil.getECParameterSpec(p, curvName);
         ECPrivateKeySpec privKeySpec =
             new ECPrivateKeySpec(new BigInteger(privD, 16), ecParams);
         ECPublicKeySpec pubKeySpec =
@@ -112,12 +112,14 @@
         System.out.println("Testing against NIST P-256");
 
         long start = System.currentTimeMillis();
-        KeyPair kp256A = genECKeyPair("secp256r1", privD256, pubX256, pubY256);
+        KeyPair kp256A =
+            genECKeyPair("secp256r1", privD256, pubX256, pubY256, provider);
         KeyPair kp256B = genECKeyPair("secp256r1");
         testKeyAgreement(kp256A, kp256B, provider);
 
         System.out.println("Testing against NIST P-384");
-        KeyPair kp384A = genECKeyPair("secp384r1", privD384, pubX384, pubY384);
+        KeyPair kp384A =
+            genECKeyPair("secp384r1", privD384, pubX384, pubY384, provider);
         KeyPair kp384B = genECKeyPair("secp384r1");
         testKeyAgreement(kp384A, kp384B, provider);
 
diff --git a/jdk/test/sun/security/pkcs11/ec/TestECDSA2.java b/jdk/test/sun/security/pkcs11/ec/TestECDSA2.java
index 98c7f03..886f7f2 100644
--- a/jdk/test/sun/security/pkcs11/ec/TestECDSA2.java
+++ b/jdk/test/sun/security/pkcs11/ec/TestECDSA2.java
@@ -40,7 +40,7 @@
 import java.security.spec.*;
 import java.security.interfaces.*;
 
-import sun.security.ec.NamedCurve;
+import sun.security.util.ECUtil;
 
 public class TestECDSA2 extends PKCS11Test {
 
@@ -75,8 +75,9 @@
         System.out.println(p.getName() + ": " + alg + " Passed");
     }
 
-    private KeyPair genECKeyPair(String curvName, String privD, String pubX, String pubY) throws Exception {
-        ECParameterSpec ecParams = NamedCurve.getECParameterSpec(curvName);
+    private KeyPair genECKeyPair(String curvName, String privD, String pubX,
+            String pubY, Provider p) throws Exception {
+        ECParameterSpec ecParams = ECUtil.getECParameterSpec(p, curvName);
         ECPrivateKeySpec privKeySpec =
             new ECPrivateKeySpec(new BigInteger(privD, 16), ecParams);
         ECPublicKeySpec pubKeySpec =
@@ -108,12 +109,14 @@
         long start = System.currentTimeMillis();
         if (testP256) {
             // can use secp256r1, NIST P-256, X9.62 prime256v1, or 1.2.840.10045.3.1.7
-            KeyPair kp = genECKeyPair("secp256r1", privD256, pubX256, pubY256);
+            KeyPair kp =
+                genECKeyPair("secp256r1", privD256, pubX256, pubY256, provider);
             testSignAndVerify("SHA256withECDSA", kp, provider);
         }
         if (testP384) {
             // can use secp384r1, NIST P-384, 1.3.132.0.34
-            KeyPair kp = genECKeyPair("secp384r1", privD384, pubX384, pubY384);
+            KeyPair kp =
+                genECKeyPair("secp384r1", privD384, pubX384, pubY384, provider);
             testSignAndVerify("SHA384withECDSA", kp, provider);
         }
         long stop = System.currentTimeMillis();
diff --git a/jdk/test/sun/security/provider/certpath/X509CertPath/ForwardBuildCompromised.java b/jdk/test/sun/security/provider/certpath/X509CertPath/ForwardBuildCompromised.java
deleted file mode 100644
index 9ee45b7..0000000
--- a/jdk/test/sun/security/provider/certpath/X509CertPath/ForwardBuildCompromised.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 7123519
- * @summary Problem with java/classes_security
- */
-
-import java.net.*;
-import java.util.*;
-import java.io.*;
-import javax.net.ssl.*;
-import java.security.KeyStore;
-import java.security.cert.*;
-import java.security.spec.*;
-import java.security.interfaces.*;
-
-public class ForwardBuildCompromised {
-    // DigiNotar Root CA, untrusted root certificate
-    static String trustedCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC\n" +
-        "VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u\n" +
-        "ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc\n" +
-        "KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u\n" +
-        "ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1\n" +
-        "MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE\n" +
-        "ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j\n" +
-        "b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF\n" +
-        "bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg\n" +
-        "U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA\n" +
-        "A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/\n" +
-        "I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3\n" +
-        "wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC\n" +
-        "AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb\n" +
-        "oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5\n" +
-        "BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p\n" +
-        "dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk\n" +
-        "MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp\n" +
-        "b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu\n" +
-        "dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0\n" +
-        "MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi\n" +
-        "E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa\n" +
-        "MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI\n" +
-        "hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN\n" +
-        "95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd\n" +
-        "2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=\n" +
-        "-----END CERTIFICATE-----";
-
-    // DigiNotar Root CA, untrusted cross-certificate
-    static String untrustedCrossCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIFSDCCBLGgAwIBAgIERpwsrzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC\n" +
-        "VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u\n" +
-        "ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc\n" +
-        "KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u\n" +
-        "ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA3\n" +
-        "MjYxNTU3MzlaFw0xMzA4MjYxNjI3MzlaMF8xCzAJBgNVBAYTAk5MMRIwEAYDVQQK\n" +
-        "EwlEaWdpTm90YXIxGjAYBgNVBAMTEURpZ2lOb3RhciBSb290IENBMSAwHgYJKoZI\n" +
-        "hvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIwDQYJKoZIhvcNAQEBBQADggIP\n" +
-        "ADCCAgoCggIBAKywWMEAvdghCAsrmv5uVjAFnxt3kBBBXMMNhxF3joHxynzpjGrt\n" +
-        "OHQ1u9rf+bvACTe0lnOBfTMamDn3k2+Vfz25sXWHulFI6ItwPpUExdi2wxbZiLCx\n" +
-        "hx1w2oa0DxSLes8Q0XQ2ohJ7d4ZKeeZ73wIRaKVOhq40WJskE3hWIiUeAYtLUXH7\n" +
-        "gsxZlmmIWmhTxbkNAjfLS7xmSpB+KgsFB+0WX1WQddhGyRuD4gi+8SPMmR3WKg+D\n" +
-        "IBVYJ4Iu+uIiwkmxuQGBap1tnUB3aHZOISpthECFTnaZfILz87cCWdQmARuO361T\n" +
-        "BtGuGN3isjrL14g4jqxbKbkZ05j5GAPPSIKGZgsbaQ/J6ziIeiYaBUyS1yTUlvKs\n" +
-        "Ui2jR9VS9j/+zoQGcKaqPqLytlY0GFei5IFt58rwatPHkWsCg0F8Fe9rmmRe49A8\n" +
-        "5bHre12G+8vmd0nNo2Xc97mcuOQLX5PPzDAaMhzOHGOVpfnq4XSLnukrqTB7oBgf\n" +
-        "DhgL5Vup09FsHgdnj5FLqYq80maqkwGIspH6MVzVpsFSCAnNCmOi0yKm6KHZOQaX\n" +
-        "9W6NApCMFHs/gM0bnLrEWHIjr7ZWn8Z6QjMpBz+CyeYfBQ3NTCg2i9PIPhzGiO9e\n" +
-        "7olk6R3r2ol+MqZp0d3MiJ/R0MlmIdwGZ8WUepptYkx9zOBkgLKeR46jAgMBAAGj\n" +
-        "ggEmMIIBIjASBgNVHRMBAf8ECDAGAQH/AgEBMCcGA1UdJQQgMB4GCCsGAQUFBwMB\n" +
-        "BggrBgEFBQcDAgYIKwYBBQUHAwQwEQYDVR0gBAowCDAGBgRVHSAAMDMGCCsGAQUF\n" +
-        "BwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMwYD\n" +
-        "VR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbnRydXN0Lm5ldC9zZXJ2ZXIxLmNy\n" +
-        "bDAdBgNVHQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wCwYDVR0PBAQDAgEGMB8G\n" +
-        "A1UdIwQYMBaAFPAXYhNVPbP/CgBr+1CEl/PtYtAaMBkGCSqGSIb2fQdBAAQMMAob\n" +
-        "BFY3LjEDAgCBMA0GCSqGSIb3DQEBBQUAA4GBAEa6RcDNcEIGUlkDJUY/pWTds4zh\n" +
-        "xbVkp3wSmpwPFhx5fxTyF4HD2L60jl3aqjTB7gPpsL2Pk5QZlNsi3t4UkCV70UOd\n" +
-        "ueJRN3o/LOtk4+bjXY2lC0qTHbN80VMLqPjmaf9ghSA9hwhskdtMgRsgfd90q5QP\n" +
-        "ZFdYf+hthc3m6IcJ\n" +
-        "-----END CERTIFICATE-----";
-
-    // DigiNotar Root CA, compromised certificate
-    static String compromisedCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIFijCCA3KgAwIBAgIQDHbanJEMTiye/hXQWJM8TDANBgkqhkiG9w0BAQUFADBf\n" +
-        "MQswCQYDVQQGEwJOTDESMBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdp\n" +
-        "Tm90YXIgUm9vdCBDQTEgMB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmww\n" +
-        "HhcNMDcwNTE2MTcxOTM2WhcNMjUwMzMxMTgxOTIxWjBfMQswCQYDVQQGEwJOTDES\n" +
-        "MBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdpTm90YXIgUm9vdCBDQTEg\n" +
-        "MB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmwwggIiMA0GCSqGSIb3DQEB\n" +
-        "AQUAA4ICDwAwggIKAoICAQCssFjBAL3YIQgLK5r+blYwBZ8bd5AQQVzDDYcRd46B\n" +
-        "8cp86Yxq7Th0Nbva3/m7wAk3tJZzgX0zGpg595NvlX89ubF1h7pRSOiLcD6VBMXY\n" +
-        "tsMW2YiwsYcdcNqGtA8Ui3rPENF0NqISe3eGSnnme98CEWilToauNFibJBN4ViIl\n" +
-        "HgGLS1Fx+4LMWZZpiFpoU8W5DQI3y0u8ZkqQfioLBQftFl9VkHXYRskbg+IIvvEj\n" +
-        "zJkd1ioPgyAVWCeCLvriIsJJsbkBgWqdbZ1Ad2h2TiEqbYRAhU52mXyC8/O3AlnU\n" +
-        "JgEbjt+tUwbRrhjd4rI6y9eIOI6sWym5GdOY+RgDz0iChmYLG2kPyes4iHomGgVM\n" +
-        "ktck1JbyrFIto0fVUvY//s6EBnCmqj6i8rZWNBhXouSBbefK8GrTx5FrAoNBfBXv\n" +
-        "a5pkXuPQPOWx63tdhvvL5ndJzaNl3Pe5nLjkC1+Tz8wwGjIczhxjlaX56uF0i57p\n" +
-        "K6kwe6AYHw4YC+VbqdPRbB4HZ4+RS6mKvNJmqpMBiLKR+jFc1abBUggJzQpjotMi\n" +
-        "puih2TkGl/VujQKQjBR7P4DNG5y6xFhyI6+2Vp/GekIzKQc/gsnmHwUNzUwoNovT\n" +
-        "yD4cxojvXu6JZOkd69qJfjKmadHdzIif0dDJZiHcBmfFlHqabWJMfczgZICynkeO\n" +
-        "owIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV\n" +
-        "HQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wDQYJKoZIhvcNAQEFBQADggIBADsC\n" +
-        "jcs8MOhuoK3yc7NfniUTBAXT9uOLuwt5zlPe5JbF0a9zvNXD0EBVfEB/zRtfCdXy\n" +
-        "fJ9oHbtdzno5wozWmHvFg1Wo1X1AyuAe94leY12hE8JdiraKfADzI8PthV9xdvBo\n" +
-        "Y6pFITlIYXg23PFDk9Qlx/KAZeFTAnVR/Ho67zerhChXDNjU1JlWbOOi/lmEtDHo\n" +
-        "M/hklJRRl6s5xUvt2t2AC298KQ3EjopyDedTFLJgQT2EkTFoPSdE2+Xe9PpjRchM\n" +
-        "Ppj1P0G6Tss3DbpmmPHdy59c91Q2gmssvBNhl0L4eLvMyKKfyvBovWsdst+Nbwed\n" +
-        "2o5nx0ceyrm/KkKRt2NTZvFCo+H0Wk1Ya7XkpDOtXHAd3ODy63MUkZoDweoAZbwH\n" +
-        "/M8SESIsrqC9OuCiKthZ6SnTGDWkrBFfGbW1G/8iSlzGeuQX7yCpp/Q/rYqnmgQl\n" +
-        "nQ7KN+ZQ/YxCKQSa7LnPS3K94gg2ryMvYuXKAdNw23yCIywWMQzGNgeQerEfZ1jE\n" +
-        "O1hZibCMjFCz2IbLaKPECudpSyDOwR5WS5WpI2jYMNjD67BVUc3l/Su49bsRn1NU\n" +
-        "9jQZjHkJNsphFyUXC4KYcwx3dMPVDceoEkzHp1RxRy4sGn3J4ys7SN4nhKdjNrN9\n" +
-        "j6BkOSQNPXuHr2ZcdBtLc7LljPCGmbjlxd+Ewbfr\n" +
-        "-----END CERTIFICATE-----";
-
-    // DigiNotar Public CA 2025, intermediate certificate
-    static String intermediateCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIGAzCCA+ugAwIBAgIQHn16Uz1FMEGWQA9xSB9FBDANBgkqhkiG9w0BAQUFADBf\n" +
-        "MQswCQYDVQQGEwJOTDESMBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdp\n" +
-        "Tm90YXIgUm9vdCBDQTEgMB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmww\n" +
-        "HhcNMDYwMjA2MTYwNzAyWhcNMjUwMzI4MTYwNzAyWjBmMQswCQYDVQQGEwJOTDES\n" +
-        "MBAGA1UEChMJRGlnaU5vdGFyMSEwHwYDVQQDExhEaWdpTm90YXIgUHVibGljIENB\n" +
-        "IDIwMjUxIDAeBgkqhkiG9w0BCQEWEWluZm9AZGlnaW5vdGFyLm5sMIIBIjANBgkq\n" +
-        "hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs/2eu/I5fMG8lbvPph3e8zfJpZQtg/72\n" +
-        "Yx29+ivtKehiF6A3n785XyoY6IT3vlCrhy1CbMOY3M0x1n4YQlv17B0XZ/DqHyBA\n" +
-        "SQvnDNbkM9j4NoSy/sRtGsP6PetIFFjrhE9whZuvuSUC1PY4PruEEJp8zOCx4+wU\n" +
-        "Zt9xvjy4Xra+bSia5rwccQ/R5FYTGKrYCthOy9C9ud5Fhd++rlVhgdA/78w+Cs2s\n" +
-        "xS4i0MAxG75P3/e/bATJKepbydHdDjkyz9o3RW/wdPUXhzEw4EwUjYg6XJrDzMad\n" +
-        "6aL9M/eaxDjgz6o48EaWRDrGptaE2uJRuErVz7oOO0p/wYKq/BU+/wIDAQABo4IB\n" +
-        "sjCCAa4wOgYIKwYBBQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vdmFsaWRh\n" +
-        "dGlvbi5kaWdpbm90YXIubmwwHwYDVR0jBBgwFoAUiGi/4I41xDs4a2L3KDuEgcgM\n" +
-        "100wEgYDVR0TAQH/BAgwBgEB/wIBADCBxgYDVR0gBIG+MIG7MIG4Bg5ghBABh2kB\n" +
-        "AQEBBQIGBDCBpTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdpbm90YXIubmwv\n" +
-        "Y3BzMHoGCCsGAQUFBwICMG4abENvbmRpdGlvbnMsIGFzIG1lbnRpb25lZCBvbiBv\n" +
-        "dXIgd2Vic2l0ZSAod3d3LmRpZ2lub3Rhci5ubCksIGFyZSBhcHBsaWNhYmxlIHRv\n" +
-        "IGFsbCBvdXIgcHJvZHVjdHMgYW5kIHNlcnZpY2VzLjBDBgNVHR8EPDA6MDigNqA0\n" +
-        "hjJodHRwOi8vc2VydmljZS5kaWdpbm90YXIubmwvY3JsL3Jvb3QvbGF0ZXN0Q1JM\n" +
-        "LmNybDAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFN8zwK+S/jf8ttgWFtDZsZHV\n" +
-        "+m6lMA0GCSqGSIb3DQEBBQUAA4ICAQCfV1rmBd9QStEyQ40lT0tqby0/3ez0STuJ\n" +
-        "ESBQLQD56XYdb4VFSuqA6xTtiuSVHLoiv2xyISN9FvX3A5VtifkJ00JEaLQJiSsE\n" +
-        "wGDkYGl1DT7SsqtAVKdMAuCM+e0j0/RV3hZ6kcrM7/wFccHwM+/TiurR9lgZDzB4\n" +
-        "a7++A4XrYyKx9vc9ZwBEnD1nrAe7++gg9cuZgP7e+QL0FBHMjpw+gnCDjr2dzBZC\n" +
-        "4r+b8SOqlbPRPexBuNghlc7PfcPIyFis2LJXDRMWiAd3TcfdALwRsuKMR/T+cwyr\n" +
-        "asy69OEGHplLT57otQ524BDctDXNzlH9bHEh52QzqkWvIDqs42910IUy1nYNPIUG\n" +
-        "yYJV/T7H8Jb6vfMZWe47iUFvtNZCi8+b542gRUwdi+ca+hGviBC9Qr4Wv1pl7CBQ\n" +
-        "Hy1axTkHiQawUo/hgmoetCpftugl9yJTfvsBorUV1ZMxn9B1JLSGtWnbUsFRla7G\n" +
-        "fNa0IsUkzmmha8XCzvNu0d1PDGtcQyUqmDOE1Hx4cIBeuF8ipuIXkrVCr9zAZ4ZC\n" +
-        "hgz6aA1gDTW8whSRJqYEYEQ0pcMEFLyXE+Nz3O8NinO2AuxqKhjMk13203xA7lPY\n" +
-        "MnBQ0v7S3qqbp/pvPMiUhOz/VaYted6QmOY5EATBnFiLCuw87JXoAyp382eJ3WX1\n" +
-        "hOiR4IX9Tg==\n" +
-        "-----END CERTIFICATE-----";
-
-    // The fraudulent certificate issued by above compromised CA
-    static String targetCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIFKDCCBBCgAwIBAgIQBeLmpM0J6lTWZbB1/iKiVjANBgkqhkiG9w0BAQUFADBm\n" +
-        "MQswCQYDVQQGEwJOTDESMBAGA1UEChMJRGlnaU5vdGFyMSEwHwYDVQQDExhEaWdp\n" +
-        "Tm90YXIgUHVibGljIENBIDIwMjUxIDAeBgkqhkiG9w0BCQEWEWluZm9AZGlnaW5v\n" +
-        "dGFyLm5sMB4XDTExMDcxMDE5MDYzMFoXDTEzMDcwOTE5MDYzMFowajELMAkGA1UE\n" +
-        "BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxFjAUBgNVBAcTDU1vdW50YWluIFZp\n" +
-        "ZXcxFzAVBgNVBAUTDlBLMDAwMjI5MjAwMDAyMRUwEwYDVQQDEwwqLmdvb2dsZS5j\n" +
-        "b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNbeKubCV0aCxhOiOS\n" +
-        "CSQ/w9HXTYuD5BLKuiqXNw3setdTymeJz2L8aWOHo3nicFNDVwWTgwWomGNr2J6Q\n" +
-        "7g1iINNSW0rR4E1l2szRkcnAY6c6i/Eke93nF4i2hDsnIBveolF5yjpuRm73uQQD\n" +
-        "ulHjA3BFRF/PTi0fw2/Yt+8ieoMuNcMWN6Eou5Gqt5YZkWv176ofeCbsBmMrP87x\n" +
-        "OhhtTDckCapk4VQZG2XrfzZcV6tdzCp5TI8uHdu17cdzXm1imZ8tyvzFeiCEOQN8\n" +
-        "vPNzB/fIr3CJQ5q4uM5aKT3DD5PeVzf4rfJKQNgCTWiIBc9XcWEUuszwAsnmg7e2\n" +
-        "EJRdAgMBAAGjggHMMIIByDA6BggrBgEFBQcBAQQuMCwwKgYIKwYBBQUHMAGGHmh0\n" +
-        "dHA6Ly92YWxpZGF0aW9uLmRpZ2lub3Rhci5ubDAfBgNVHSMEGDAWgBTfM8Cvkv43\n" +
-        "/LbYFhbQ2bGR1fpupTAJBgNVHRMEAjAAMIHGBgNVHSAEgb4wgbswgbgGDmCEEAGH\n" +
-        "aQEBAQIEAQICMIGlMCcGCCsGAQUFBwIBFhtodHRwOi8vd3d3LmRpZ2lub3Rhci5u\n" +
-        "bC9jcHMwegYIKwYBBQUHAgIwbhpsQ29uZGl0aW9ucywgYXMgbWVudGlvbmVkIG9u\n" +
-        "IG91ciB3ZWJzaXRlICh3d3cuZGlnaW5vdGFyLm5sKSwgYXJlIGFwcGxpY2FibGUg\n" +
-        "dG8gYWxsIG91ciBwcm9kdWN0cyBhbmQgc2VydmljZXMuMEkGA1UdHwRCMEAwPqA8\n" +
-        "oDqGOGh0dHA6Ly9zZXJ2aWNlLmRpZ2lub3Rhci5ubC9jcmwvcHVibGljMjAyNS9s\n" +
-        "YXRlc3RDUkwuY3JsMA4GA1UdDwEB/wQEAwIEsDAbBgNVHREEFDASgRBhZG1pbkBn\n" +
-        "b29nbGUuY29tMB0GA1UdDgQWBBQHSn0WJzIo0eMBMQUNsMqN6eF/7TANBgkqhkiG\n" +
-        "9w0BAQUFAAOCAQEAAs5dL7N9wzRJkI4Aq4lC5t8j5ZadqnqUcgYLADzSv4ExytNH\n" +
-        "UY2nH6iVTihC0UPSsILWraoeApdT7Rphz/8DLQEBRGdeKWAptNM3EbiXtQaZT2uB\n" +
-        "pidL8UoafX0kch3f71Y1scpBEjvu5ZZLnjg0A8AL0tnsereOVdDpU98bKqdbbrnM\n" +
-        "FRmBlSf7xdaNca6JJHeEpga4E9Ty683CmccrSGXdU2tTCuHEJww+iOAUtPIZcsum\n" +
-        "U7/eYeY1pMyGLyIjbNgRY7nDzRwvM/BsbL9eh4/mSQj/4nncqJd22sVQpCggQiVK\n" +
-        "baB2sVGcVNBkK55bT8gPqnx8JypubyUvayzZGg==\n" +
-        "-----END CERTIFICATE-----";
-
-    public static void main(String args[]) throws Exception {
-
-        Exception reservedException = null;
-        try {
-            build();
-        } catch (CertPathBuilderException cpbe) {
-            reservedException = cpbe;
-        }
-
-        if (reservedException == null) {
-            throw new Exception("Unable to block fraudulent certificate");
-        }
-
-        System.out.println(
-            "The expected untrusted cert exception: " + reservedException);
-    }
-
-    private static X509CertSelector generateSelector() throws Exception {
-
-        // generate certificate from cert strings
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-
-        X509Certificate target = null;
-        try (ByteArrayInputStream is =
-                new ByteArrayInputStream(targetCertStr.getBytes())) {
-            target = (X509Certificate)cf.generateCertificate(is);
-        }
-
-        X509CertSelector selector = new X509CertSelector();
-        selector.setCertificate(target);
-
-        return selector;
-    }
-
-
-    private static CertStore generateCertificateStore() throws Exception {
-
-        // generate certificate from cert strings
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-
-        // generate certification path
-        Set<Certificate> entries = new HashSet();
-
-        try (ByteArrayInputStream is =
-                new ByteArrayInputStream(targetCertStr.getBytes())) {
-            entries.add(cf.generateCertificate(is));
-        }
-
-        try (ByteArrayInputStream is =
-                new ByteArrayInputStream(intermediateCertStr.getBytes())) {
-            entries.add(cf.generateCertificate(is));
-        }
-
-        try (ByteArrayInputStream is =
-                new ByteArrayInputStream(compromisedCertStr.getBytes())) {
-            entries.add(cf.generateCertificate(is));
-        }
-
-        try (ByteArrayInputStream is =
-                new ByteArrayInputStream(untrustedCrossCertStr.getBytes())) {
-            entries.add(cf.generateCertificate(is));
-        }
-
-        return CertStore.getInstance("Collection",
-                            new CollectionCertStoreParameters(entries));
-    }
-
-    private static Set<TrustAnchor> generateTrustAnchors()
-            throws CertificateException, IOException {
-        // generate certificate from cert string
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-
-        Certificate trustedCert = null;
-        try (ByteArrayInputStream is =
-                new ByteArrayInputStream(trustedCertStr.getBytes())) {
-            trustedCert = cf.generateCertificate(is);
-        }
-
-        // generate a trust anchor
-        TrustAnchor anchor =
-            new TrustAnchor((X509Certificate)trustedCert, null);
-
-        return Collections.singleton(anchor);
-    }
-
-    private static void build() throws Exception {
-        X509CertSelector selector = generateSelector();
-        Set<TrustAnchor> anchors = generateTrustAnchors();
-        CertStore certs = generateCertificateStore();
-
-        PKIXBuilderParameters params =
-                new PKIXBuilderParameters(anchors, selector);
-        params.addCertStore(certs);
-        params.setRevocationEnabled(false);
-        params.setDate(new Date(111, 11, 25));   // 2011-12-25
-
-        CertPathBuilder builder = CertPathBuilder.getInstance("PKIX");
-        PKIXCertPathBuilderResult result =
-                        (PKIXCertPathBuilderResult)builder.build(params);
-    }
-}
-
diff --git a/jdk/test/sun/security/provider/certpath/X509CertPath/ReverseBuildCompromised.java b/jdk/test/sun/security/provider/certpath/X509CertPath/ReverseBuildCompromised.java
deleted file mode 100644
index 845a149..0000000
--- a/jdk/test/sun/security/provider/certpath/X509CertPath/ReverseBuildCompromised.java
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 7123519
- * @summary Problem with java/classes_security
- */
-
-import java.net.*;
-import java.util.*;
-import java.io.*;
-import javax.net.ssl.*;
-import java.security.KeyStore;
-import java.security.cert.*;
-import java.security.spec.*;
-import java.security.interfaces.*;
-import sun.security.provider.certpath.SunCertPathBuilderParameters;
-
-public class ReverseBuildCompromised {
-    // DigiNotar Root CA, untrusted root certificate
-    static String trustedCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC\n" +
-        "VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u\n" +
-        "ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc\n" +
-        "KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u\n" +
-        "ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1\n" +
-        "MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE\n" +
-        "ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j\n" +
-        "b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF\n" +
-        "bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg\n" +
-        "U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA\n" +
-        "A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/\n" +
-        "I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3\n" +
-        "wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC\n" +
-        "AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb\n" +
-        "oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5\n" +
-        "BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p\n" +
-        "dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk\n" +
-        "MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp\n" +
-        "b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu\n" +
-        "dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0\n" +
-        "MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi\n" +
-        "E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa\n" +
-        "MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI\n" +
-        "hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN\n" +
-        "95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd\n" +
-        "2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=\n" +
-        "-----END CERTIFICATE-----";
-
-    // DigiNotar Root CA, untrusted cross-certificate
-    static String untrustedCrossCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIFSDCCBLGgAwIBAgIERpwsrzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC\n" +
-        "VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u\n" +
-        "ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc\n" +
-        "KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u\n" +
-        "ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA3\n" +
-        "MjYxNTU3MzlaFw0xMzA4MjYxNjI3MzlaMF8xCzAJBgNVBAYTAk5MMRIwEAYDVQQK\n" +
-        "EwlEaWdpTm90YXIxGjAYBgNVBAMTEURpZ2lOb3RhciBSb290IENBMSAwHgYJKoZI\n" +
-        "hvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIwDQYJKoZIhvcNAQEBBQADggIP\n" +
-        "ADCCAgoCggIBAKywWMEAvdghCAsrmv5uVjAFnxt3kBBBXMMNhxF3joHxynzpjGrt\n" +
-        "OHQ1u9rf+bvACTe0lnOBfTMamDn3k2+Vfz25sXWHulFI6ItwPpUExdi2wxbZiLCx\n" +
-        "hx1w2oa0DxSLes8Q0XQ2ohJ7d4ZKeeZ73wIRaKVOhq40WJskE3hWIiUeAYtLUXH7\n" +
-        "gsxZlmmIWmhTxbkNAjfLS7xmSpB+KgsFB+0WX1WQddhGyRuD4gi+8SPMmR3WKg+D\n" +
-        "IBVYJ4Iu+uIiwkmxuQGBap1tnUB3aHZOISpthECFTnaZfILz87cCWdQmARuO361T\n" +
-        "BtGuGN3isjrL14g4jqxbKbkZ05j5GAPPSIKGZgsbaQ/J6ziIeiYaBUyS1yTUlvKs\n" +
-        "Ui2jR9VS9j/+zoQGcKaqPqLytlY0GFei5IFt58rwatPHkWsCg0F8Fe9rmmRe49A8\n" +
-        "5bHre12G+8vmd0nNo2Xc97mcuOQLX5PPzDAaMhzOHGOVpfnq4XSLnukrqTB7oBgf\n" +
-        "DhgL5Vup09FsHgdnj5FLqYq80maqkwGIspH6MVzVpsFSCAnNCmOi0yKm6KHZOQaX\n" +
-        "9W6NApCMFHs/gM0bnLrEWHIjr7ZWn8Z6QjMpBz+CyeYfBQ3NTCg2i9PIPhzGiO9e\n" +
-        "7olk6R3r2ol+MqZp0d3MiJ/R0MlmIdwGZ8WUepptYkx9zOBkgLKeR46jAgMBAAGj\n" +
-        "ggEmMIIBIjASBgNVHRMBAf8ECDAGAQH/AgEBMCcGA1UdJQQgMB4GCCsGAQUFBwMB\n" +
-        "BggrBgEFBQcDAgYIKwYBBQUHAwQwEQYDVR0gBAowCDAGBgRVHSAAMDMGCCsGAQUF\n" +
-        "BwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMwYD\n" +
-        "VR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbnRydXN0Lm5ldC9zZXJ2ZXIxLmNy\n" +
-        "bDAdBgNVHQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wCwYDVR0PBAQDAgEGMB8G\n" +
-        "A1UdIwQYMBaAFPAXYhNVPbP/CgBr+1CEl/PtYtAaMBkGCSqGSIb2fQdBAAQMMAob\n" +
-        "BFY3LjEDAgCBMA0GCSqGSIb3DQEBBQUAA4GBAEa6RcDNcEIGUlkDJUY/pWTds4zh\n" +
-        "xbVkp3wSmpwPFhx5fxTyF4HD2L60jl3aqjTB7gPpsL2Pk5QZlNsi3t4UkCV70UOd\n" +
-        "ueJRN3o/LOtk4+bjXY2lC0qTHbN80VMLqPjmaf9ghSA9hwhskdtMgRsgfd90q5QP\n" +
-        "ZFdYf+hthc3m6IcJ\n" +
-        "-----END CERTIFICATE-----";
-
-    // DigiNotar Root CA, compromised certificate
-    static String compromisedCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIFijCCA3KgAwIBAgIQDHbanJEMTiye/hXQWJM8TDANBgkqhkiG9w0BAQUFADBf\n" +
-        "MQswCQYDVQQGEwJOTDESMBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdp\n" +
-        "Tm90YXIgUm9vdCBDQTEgMB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmww\n" +
-        "HhcNMDcwNTE2MTcxOTM2WhcNMjUwMzMxMTgxOTIxWjBfMQswCQYDVQQGEwJOTDES\n" +
-        "MBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdpTm90YXIgUm9vdCBDQTEg\n" +
-        "MB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmwwggIiMA0GCSqGSIb3DQEB\n" +
-        "AQUAA4ICDwAwggIKAoICAQCssFjBAL3YIQgLK5r+blYwBZ8bd5AQQVzDDYcRd46B\n" +
-        "8cp86Yxq7Th0Nbva3/m7wAk3tJZzgX0zGpg595NvlX89ubF1h7pRSOiLcD6VBMXY\n" +
-        "tsMW2YiwsYcdcNqGtA8Ui3rPENF0NqISe3eGSnnme98CEWilToauNFibJBN4ViIl\n" +
-        "HgGLS1Fx+4LMWZZpiFpoU8W5DQI3y0u8ZkqQfioLBQftFl9VkHXYRskbg+IIvvEj\n" +
-        "zJkd1ioPgyAVWCeCLvriIsJJsbkBgWqdbZ1Ad2h2TiEqbYRAhU52mXyC8/O3AlnU\n" +
-        "JgEbjt+tUwbRrhjd4rI6y9eIOI6sWym5GdOY+RgDz0iChmYLG2kPyes4iHomGgVM\n" +
-        "ktck1JbyrFIto0fVUvY//s6EBnCmqj6i8rZWNBhXouSBbefK8GrTx5FrAoNBfBXv\n" +
-        "a5pkXuPQPOWx63tdhvvL5ndJzaNl3Pe5nLjkC1+Tz8wwGjIczhxjlaX56uF0i57p\n" +
-        "K6kwe6AYHw4YC+VbqdPRbB4HZ4+RS6mKvNJmqpMBiLKR+jFc1abBUggJzQpjotMi\n" +
-        "puih2TkGl/VujQKQjBR7P4DNG5y6xFhyI6+2Vp/GekIzKQc/gsnmHwUNzUwoNovT\n" +
-        "yD4cxojvXu6JZOkd69qJfjKmadHdzIif0dDJZiHcBmfFlHqabWJMfczgZICynkeO\n" +
-        "owIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV\n" +
-        "HQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wDQYJKoZIhvcNAQEFBQADggIBADsC\n" +
-        "jcs8MOhuoK3yc7NfniUTBAXT9uOLuwt5zlPe5JbF0a9zvNXD0EBVfEB/zRtfCdXy\n" +
-        "fJ9oHbtdzno5wozWmHvFg1Wo1X1AyuAe94leY12hE8JdiraKfADzI8PthV9xdvBo\n" +
-        "Y6pFITlIYXg23PFDk9Qlx/KAZeFTAnVR/Ho67zerhChXDNjU1JlWbOOi/lmEtDHo\n" +
-        "M/hklJRRl6s5xUvt2t2AC298KQ3EjopyDedTFLJgQT2EkTFoPSdE2+Xe9PpjRchM\n" +
-        "Ppj1P0G6Tss3DbpmmPHdy59c91Q2gmssvBNhl0L4eLvMyKKfyvBovWsdst+Nbwed\n" +
-        "2o5nx0ceyrm/KkKRt2NTZvFCo+H0Wk1Ya7XkpDOtXHAd3ODy63MUkZoDweoAZbwH\n" +
-        "/M8SESIsrqC9OuCiKthZ6SnTGDWkrBFfGbW1G/8iSlzGeuQX7yCpp/Q/rYqnmgQl\n" +
-        "nQ7KN+ZQ/YxCKQSa7LnPS3K94gg2ryMvYuXKAdNw23yCIywWMQzGNgeQerEfZ1jE\n" +
-        "O1hZibCMjFCz2IbLaKPECudpSyDOwR5WS5WpI2jYMNjD67BVUc3l/Su49bsRn1NU\n" +
-        "9jQZjHkJNsphFyUXC4KYcwx3dMPVDceoEkzHp1RxRy4sGn3J4ys7SN4nhKdjNrN9\n" +
-        "j6BkOSQNPXuHr2ZcdBtLc7LljPCGmbjlxd+Ewbfr\n" +
-        "-----END CERTIFICATE-----";
-
-    // DigiNotar Public CA 2025, intermediate certificate
-    static String intermediateCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIGAzCCA+ugAwIBAgIQHn16Uz1FMEGWQA9xSB9FBDANBgkqhkiG9w0BAQUFADBf\n" +
-        "MQswCQYDVQQGEwJOTDESMBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdp\n" +
-        "Tm90YXIgUm9vdCBDQTEgMB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmww\n" +
-        "HhcNMDYwMjA2MTYwNzAyWhcNMjUwMzI4MTYwNzAyWjBmMQswCQYDVQQGEwJOTDES\n" +
-        "MBAGA1UEChMJRGlnaU5vdGFyMSEwHwYDVQQDExhEaWdpTm90YXIgUHVibGljIENB\n" +
-        "IDIwMjUxIDAeBgkqhkiG9w0BCQEWEWluZm9AZGlnaW5vdGFyLm5sMIIBIjANBgkq\n" +
-        "hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs/2eu/I5fMG8lbvPph3e8zfJpZQtg/72\n" +
-        "Yx29+ivtKehiF6A3n785XyoY6IT3vlCrhy1CbMOY3M0x1n4YQlv17B0XZ/DqHyBA\n" +
-        "SQvnDNbkM9j4NoSy/sRtGsP6PetIFFjrhE9whZuvuSUC1PY4PruEEJp8zOCx4+wU\n" +
-        "Zt9xvjy4Xra+bSia5rwccQ/R5FYTGKrYCthOy9C9ud5Fhd++rlVhgdA/78w+Cs2s\n" +
-        "xS4i0MAxG75P3/e/bATJKepbydHdDjkyz9o3RW/wdPUXhzEw4EwUjYg6XJrDzMad\n" +
-        "6aL9M/eaxDjgz6o48EaWRDrGptaE2uJRuErVz7oOO0p/wYKq/BU+/wIDAQABo4IB\n" +
-        "sjCCAa4wOgYIKwYBBQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vdmFsaWRh\n" +
-        "dGlvbi5kaWdpbm90YXIubmwwHwYDVR0jBBgwFoAUiGi/4I41xDs4a2L3KDuEgcgM\n" +
-        "100wEgYDVR0TAQH/BAgwBgEB/wIBADCBxgYDVR0gBIG+MIG7MIG4Bg5ghBABh2kB\n" +
-        "AQEBBQIGBDCBpTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdpbm90YXIubmwv\n" +
-        "Y3BzMHoGCCsGAQUFBwICMG4abENvbmRpdGlvbnMsIGFzIG1lbnRpb25lZCBvbiBv\n" +
-        "dXIgd2Vic2l0ZSAod3d3LmRpZ2lub3Rhci5ubCksIGFyZSBhcHBsaWNhYmxlIHRv\n" +
-        "IGFsbCBvdXIgcHJvZHVjdHMgYW5kIHNlcnZpY2VzLjBDBgNVHR8EPDA6MDigNqA0\n" +
-        "hjJodHRwOi8vc2VydmljZS5kaWdpbm90YXIubmwvY3JsL3Jvb3QvbGF0ZXN0Q1JM\n" +
-        "LmNybDAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFN8zwK+S/jf8ttgWFtDZsZHV\n" +
-        "+m6lMA0GCSqGSIb3DQEBBQUAA4ICAQCfV1rmBd9QStEyQ40lT0tqby0/3ez0STuJ\n" +
-        "ESBQLQD56XYdb4VFSuqA6xTtiuSVHLoiv2xyISN9FvX3A5VtifkJ00JEaLQJiSsE\n" +
-        "wGDkYGl1DT7SsqtAVKdMAuCM+e0j0/RV3hZ6kcrM7/wFccHwM+/TiurR9lgZDzB4\n" +
-        "a7++A4XrYyKx9vc9ZwBEnD1nrAe7++gg9cuZgP7e+QL0FBHMjpw+gnCDjr2dzBZC\n" +
-        "4r+b8SOqlbPRPexBuNghlc7PfcPIyFis2LJXDRMWiAd3TcfdALwRsuKMR/T+cwyr\n" +
-        "asy69OEGHplLT57otQ524BDctDXNzlH9bHEh52QzqkWvIDqs42910IUy1nYNPIUG\n" +
-        "yYJV/T7H8Jb6vfMZWe47iUFvtNZCi8+b542gRUwdi+ca+hGviBC9Qr4Wv1pl7CBQ\n" +
-        "Hy1axTkHiQawUo/hgmoetCpftugl9yJTfvsBorUV1ZMxn9B1JLSGtWnbUsFRla7G\n" +
-        "fNa0IsUkzmmha8XCzvNu0d1PDGtcQyUqmDOE1Hx4cIBeuF8ipuIXkrVCr9zAZ4ZC\n" +
-        "hgz6aA1gDTW8whSRJqYEYEQ0pcMEFLyXE+Nz3O8NinO2AuxqKhjMk13203xA7lPY\n" +
-        "MnBQ0v7S3qqbp/pvPMiUhOz/VaYted6QmOY5EATBnFiLCuw87JXoAyp382eJ3WX1\n" +
-        "hOiR4IX9Tg==\n" +
-        "-----END CERTIFICATE-----";
-
-    // The fraudulent certificate issued by above compromised CA
-    static String targetCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIFKDCCBBCgAwIBAgIQBeLmpM0J6lTWZbB1/iKiVjANBgkqhkiG9w0BAQUFADBm\n" +
-        "MQswCQYDVQQGEwJOTDESMBAGA1UEChMJRGlnaU5vdGFyMSEwHwYDVQQDExhEaWdp\n" +
-        "Tm90YXIgUHVibGljIENBIDIwMjUxIDAeBgkqhkiG9w0BCQEWEWluZm9AZGlnaW5v\n" +
-        "dGFyLm5sMB4XDTExMDcxMDE5MDYzMFoXDTEzMDcwOTE5MDYzMFowajELMAkGA1UE\n" +
-        "BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxFjAUBgNVBAcTDU1vdW50YWluIFZp\n" +
-        "ZXcxFzAVBgNVBAUTDlBLMDAwMjI5MjAwMDAyMRUwEwYDVQQDEwwqLmdvb2dsZS5j\n" +
-        "b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNbeKubCV0aCxhOiOS\n" +
-        "CSQ/w9HXTYuD5BLKuiqXNw3setdTymeJz2L8aWOHo3nicFNDVwWTgwWomGNr2J6Q\n" +
-        "7g1iINNSW0rR4E1l2szRkcnAY6c6i/Eke93nF4i2hDsnIBveolF5yjpuRm73uQQD\n" +
-        "ulHjA3BFRF/PTi0fw2/Yt+8ieoMuNcMWN6Eou5Gqt5YZkWv176ofeCbsBmMrP87x\n" +
-        "OhhtTDckCapk4VQZG2XrfzZcV6tdzCp5TI8uHdu17cdzXm1imZ8tyvzFeiCEOQN8\n" +
-        "vPNzB/fIr3CJQ5q4uM5aKT3DD5PeVzf4rfJKQNgCTWiIBc9XcWEUuszwAsnmg7e2\n" +
-        "EJRdAgMBAAGjggHMMIIByDA6BggrBgEFBQcBAQQuMCwwKgYIKwYBBQUHMAGGHmh0\n" +
-        "dHA6Ly92YWxpZGF0aW9uLmRpZ2lub3Rhci5ubDAfBgNVHSMEGDAWgBTfM8Cvkv43\n" +
-        "/LbYFhbQ2bGR1fpupTAJBgNVHRMEAjAAMIHGBgNVHSAEgb4wgbswgbgGDmCEEAGH\n" +
-        "aQEBAQIEAQICMIGlMCcGCCsGAQUFBwIBFhtodHRwOi8vd3d3LmRpZ2lub3Rhci5u\n" +
-        "bC9jcHMwegYIKwYBBQUHAgIwbhpsQ29uZGl0aW9ucywgYXMgbWVudGlvbmVkIG9u\n" +
-        "IG91ciB3ZWJzaXRlICh3d3cuZGlnaW5vdGFyLm5sKSwgYXJlIGFwcGxpY2FibGUg\n" +
-        "dG8gYWxsIG91ciBwcm9kdWN0cyBhbmQgc2VydmljZXMuMEkGA1UdHwRCMEAwPqA8\n" +
-        "oDqGOGh0dHA6Ly9zZXJ2aWNlLmRpZ2lub3Rhci5ubC9jcmwvcHVibGljMjAyNS9s\n" +
-        "YXRlc3RDUkwuY3JsMA4GA1UdDwEB/wQEAwIEsDAbBgNVHREEFDASgRBhZG1pbkBn\n" +
-        "b29nbGUuY29tMB0GA1UdDgQWBBQHSn0WJzIo0eMBMQUNsMqN6eF/7TANBgkqhkiG\n" +
-        "9w0BAQUFAAOCAQEAAs5dL7N9wzRJkI4Aq4lC5t8j5ZadqnqUcgYLADzSv4ExytNH\n" +
-        "UY2nH6iVTihC0UPSsILWraoeApdT7Rphz/8DLQEBRGdeKWAptNM3EbiXtQaZT2uB\n" +
-        "pidL8UoafX0kch3f71Y1scpBEjvu5ZZLnjg0A8AL0tnsereOVdDpU98bKqdbbrnM\n" +
-        "FRmBlSf7xdaNca6JJHeEpga4E9Ty683CmccrSGXdU2tTCuHEJww+iOAUtPIZcsum\n" +
-        "U7/eYeY1pMyGLyIjbNgRY7nDzRwvM/BsbL9eh4/mSQj/4nncqJd22sVQpCggQiVK\n" +
-        "baB2sVGcVNBkK55bT8gPqnx8JypubyUvayzZGg==\n" +
-        "-----END CERTIFICATE-----";
-
-    public static void main(String args[]) throws Exception {
-
-        Exception reservedException = null;
-        try {
-            build();
-        } catch (CertPathBuilderException cpbe) {
-            reservedException = cpbe;
-        }
-
-        if (reservedException == null) {
-            throw new Exception("Unable to block fraudulent certificate");
-        }
-
-        System.out.println(
-            "The expected untrusted cert exception: " + reservedException);
-    }
-
-    private static X509CertSelector generateSelector() throws Exception {
-
-        // generate certificate from cert strings
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-
-        X509Certificate target = null;
-        try (ByteArrayInputStream is =
-                new ByteArrayInputStream(targetCertStr.getBytes())) {
-            target = (X509Certificate)cf.generateCertificate(is);
-        }
-
-        X509CertSelector selector = new X509CertSelector();
-        selector.setCertificate(target);
-        selector.setSubject(target.getSubjectX500Principal());
-
-        return selector;
-    }
-
-
-    private static CertStore generateCertificateStore() throws Exception {
-
-        // generate certificate from cert strings
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-
-        // generate certification path
-        Set<Certificate> entries = new HashSet();
-
-        try (ByteArrayInputStream is =
-                new ByteArrayInputStream(targetCertStr.getBytes())) {
-            entries.add(cf.generateCertificate(is));
-        }
-
-        try (ByteArrayInputStream is =
-                new ByteArrayInputStream(intermediateCertStr.getBytes())) {
-            entries.add(cf.generateCertificate(is));
-        }
-
-        try (ByteArrayInputStream is =
-                new ByteArrayInputStream(compromisedCertStr.getBytes())) {
-            entries.add(cf.generateCertificate(is));
-        }
-
-        try (ByteArrayInputStream is =
-                new ByteArrayInputStream(untrustedCrossCertStr.getBytes())) {
-            entries.add(cf.generateCertificate(is));
-        }
-
-        return CertStore.getInstance("Collection",
-                            new CollectionCertStoreParameters(entries));
-    }
-
-    private static Set<TrustAnchor> generateTrustAnchors()
-            throws CertificateException, IOException {
-        // generate certificate from cert string
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-
-        Certificate trustedCert = null;
-        try (ByteArrayInputStream is =
-                new ByteArrayInputStream(trustedCertStr.getBytes())) {
-            trustedCert = cf.generateCertificate(is);
-        }
-
-        // generate a trust anchor
-        TrustAnchor anchor =
-            new TrustAnchor((X509Certificate)trustedCert, null);
-
-        return Collections.singleton(anchor);
-    }
-
-    private static void build() throws Exception {
-        X509CertSelector selector = generateSelector();
-        Set<TrustAnchor> anchors = generateTrustAnchors();
-        CertStore certs = generateCertificateStore();
-
-        SunCertPathBuilderParameters params =
-            new SunCertPathBuilderParameters(anchors, selector);
-        params.setBuildForward(false);
-        params.addCertStore(certs);
-        params.setRevocationEnabled(false);
-        params.setDate(new Date(111, 11, 25));   // 2011-12-25
-
-        CertPathBuilder builder = CertPathBuilder.getInstance("PKIX");
-        PKIXCertPathBuilderResult result =
-                        (PKIXCertPathBuilderResult)builder.build(params);
-    }
-}
-
diff --git a/jdk/test/sun/security/provider/certpath/X509CertPath/ValidateCompromised.java b/jdk/test/sun/security/provider/certpath/X509CertPath/ValidateCompromised.java
deleted file mode 100644
index 42cb005..0000000
--- a/jdk/test/sun/security/provider/certpath/X509CertPath/ValidateCompromised.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 7123519
- * @summary Problem with java/classes_security
- */
-
-import java.net.*;
-import java.util.*;
-import java.io.*;
-import javax.net.ssl.*;
-import java.security.KeyStore;
-import java.security.cert.*;
-import java.security.spec.*;
-import java.security.interfaces.*;
-
-public class ValidateCompromised {
-    // DigiNotar Root CA, untrusted root certificate
-    static String trustedCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC\n" +
-        "VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u\n" +
-        "ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc\n" +
-        "KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u\n" +
-        "ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1\n" +
-        "MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE\n" +
-        "ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j\n" +
-        "b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF\n" +
-        "bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg\n" +
-        "U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA\n" +
-        "A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/\n" +
-        "I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3\n" +
-        "wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC\n" +
-        "AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb\n" +
-        "oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5\n" +
-        "BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p\n" +
-        "dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk\n" +
-        "MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp\n" +
-        "b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu\n" +
-        "dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0\n" +
-        "MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi\n" +
-        "E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa\n" +
-        "MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI\n" +
-        "hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN\n" +
-        "95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd\n" +
-        "2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=\n" +
-        "-----END CERTIFICATE-----";
-
-    // DigiNotar Root CA, untrusted cross-certificate
-    static String untrustedCrossCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIFSDCCBLGgAwIBAgIERpwsrzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC\n" +
-        "VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u\n" +
-        "ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc\n" +
-        "KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u\n" +
-        "ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA3\n" +
-        "MjYxNTU3MzlaFw0xMzA4MjYxNjI3MzlaMF8xCzAJBgNVBAYTAk5MMRIwEAYDVQQK\n" +
-        "EwlEaWdpTm90YXIxGjAYBgNVBAMTEURpZ2lOb3RhciBSb290IENBMSAwHgYJKoZI\n" +
-        "hvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIwDQYJKoZIhvcNAQEBBQADggIP\n" +
-        "ADCCAgoCggIBAKywWMEAvdghCAsrmv5uVjAFnxt3kBBBXMMNhxF3joHxynzpjGrt\n" +
-        "OHQ1u9rf+bvACTe0lnOBfTMamDn3k2+Vfz25sXWHulFI6ItwPpUExdi2wxbZiLCx\n" +
-        "hx1w2oa0DxSLes8Q0XQ2ohJ7d4ZKeeZ73wIRaKVOhq40WJskE3hWIiUeAYtLUXH7\n" +
-        "gsxZlmmIWmhTxbkNAjfLS7xmSpB+KgsFB+0WX1WQddhGyRuD4gi+8SPMmR3WKg+D\n" +
-        "IBVYJ4Iu+uIiwkmxuQGBap1tnUB3aHZOISpthECFTnaZfILz87cCWdQmARuO361T\n" +
-        "BtGuGN3isjrL14g4jqxbKbkZ05j5GAPPSIKGZgsbaQ/J6ziIeiYaBUyS1yTUlvKs\n" +
-        "Ui2jR9VS9j/+zoQGcKaqPqLytlY0GFei5IFt58rwatPHkWsCg0F8Fe9rmmRe49A8\n" +
-        "5bHre12G+8vmd0nNo2Xc97mcuOQLX5PPzDAaMhzOHGOVpfnq4XSLnukrqTB7oBgf\n" +
-        "DhgL5Vup09FsHgdnj5FLqYq80maqkwGIspH6MVzVpsFSCAnNCmOi0yKm6KHZOQaX\n" +
-        "9W6NApCMFHs/gM0bnLrEWHIjr7ZWn8Z6QjMpBz+CyeYfBQ3NTCg2i9PIPhzGiO9e\n" +
-        "7olk6R3r2ol+MqZp0d3MiJ/R0MlmIdwGZ8WUepptYkx9zOBkgLKeR46jAgMBAAGj\n" +
-        "ggEmMIIBIjASBgNVHRMBAf8ECDAGAQH/AgEBMCcGA1UdJQQgMB4GCCsGAQUFBwMB\n" +
-        "BggrBgEFBQcDAgYIKwYBBQUHAwQwEQYDVR0gBAowCDAGBgRVHSAAMDMGCCsGAQUF\n" +
-        "BwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMwYD\n" +
-        "VR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbnRydXN0Lm5ldC9zZXJ2ZXIxLmNy\n" +
-        "bDAdBgNVHQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wCwYDVR0PBAQDAgEGMB8G\n" +
-        "A1UdIwQYMBaAFPAXYhNVPbP/CgBr+1CEl/PtYtAaMBkGCSqGSIb2fQdBAAQMMAob\n" +
-        "BFY3LjEDAgCBMA0GCSqGSIb3DQEBBQUAA4GBAEa6RcDNcEIGUlkDJUY/pWTds4zh\n" +
-        "xbVkp3wSmpwPFhx5fxTyF4HD2L60jl3aqjTB7gPpsL2Pk5QZlNsi3t4UkCV70UOd\n" +
-        "ueJRN3o/LOtk4+bjXY2lC0qTHbN80VMLqPjmaf9ghSA9hwhskdtMgRsgfd90q5QP\n" +
-        "ZFdYf+hthc3m6IcJ\n" +
-        "-----END CERTIFICATE-----";
-
-    // DigiNotar Root CA, compromised certificate
-    static String compromisedCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIFijCCA3KgAwIBAgIQDHbanJEMTiye/hXQWJM8TDANBgkqhkiG9w0BAQUFADBf\n" +
-        "MQswCQYDVQQGEwJOTDESMBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdp\n" +
-        "Tm90YXIgUm9vdCBDQTEgMB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmww\n" +
-        "HhcNMDcwNTE2MTcxOTM2WhcNMjUwMzMxMTgxOTIxWjBfMQswCQYDVQQGEwJOTDES\n" +
-        "MBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdpTm90YXIgUm9vdCBDQTEg\n" +
-        "MB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmwwggIiMA0GCSqGSIb3DQEB\n" +
-        "AQUAA4ICDwAwggIKAoICAQCssFjBAL3YIQgLK5r+blYwBZ8bd5AQQVzDDYcRd46B\n" +
-        "8cp86Yxq7Th0Nbva3/m7wAk3tJZzgX0zGpg595NvlX89ubF1h7pRSOiLcD6VBMXY\n" +
-        "tsMW2YiwsYcdcNqGtA8Ui3rPENF0NqISe3eGSnnme98CEWilToauNFibJBN4ViIl\n" +
-        "HgGLS1Fx+4LMWZZpiFpoU8W5DQI3y0u8ZkqQfioLBQftFl9VkHXYRskbg+IIvvEj\n" +
-        "zJkd1ioPgyAVWCeCLvriIsJJsbkBgWqdbZ1Ad2h2TiEqbYRAhU52mXyC8/O3AlnU\n" +
-        "JgEbjt+tUwbRrhjd4rI6y9eIOI6sWym5GdOY+RgDz0iChmYLG2kPyes4iHomGgVM\n" +
-        "ktck1JbyrFIto0fVUvY//s6EBnCmqj6i8rZWNBhXouSBbefK8GrTx5FrAoNBfBXv\n" +
-        "a5pkXuPQPOWx63tdhvvL5ndJzaNl3Pe5nLjkC1+Tz8wwGjIczhxjlaX56uF0i57p\n" +
-        "K6kwe6AYHw4YC+VbqdPRbB4HZ4+RS6mKvNJmqpMBiLKR+jFc1abBUggJzQpjotMi\n" +
-        "puih2TkGl/VujQKQjBR7P4DNG5y6xFhyI6+2Vp/GekIzKQc/gsnmHwUNzUwoNovT\n" +
-        "yD4cxojvXu6JZOkd69qJfjKmadHdzIif0dDJZiHcBmfFlHqabWJMfczgZICynkeO\n" +
-        "owIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV\n" +
-        "HQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wDQYJKoZIhvcNAQEFBQADggIBADsC\n" +
-        "jcs8MOhuoK3yc7NfniUTBAXT9uOLuwt5zlPe5JbF0a9zvNXD0EBVfEB/zRtfCdXy\n" +
-        "fJ9oHbtdzno5wozWmHvFg1Wo1X1AyuAe94leY12hE8JdiraKfADzI8PthV9xdvBo\n" +
-        "Y6pFITlIYXg23PFDk9Qlx/KAZeFTAnVR/Ho67zerhChXDNjU1JlWbOOi/lmEtDHo\n" +
-        "M/hklJRRl6s5xUvt2t2AC298KQ3EjopyDedTFLJgQT2EkTFoPSdE2+Xe9PpjRchM\n" +
-        "Ppj1P0G6Tss3DbpmmPHdy59c91Q2gmssvBNhl0L4eLvMyKKfyvBovWsdst+Nbwed\n" +
-        "2o5nx0ceyrm/KkKRt2NTZvFCo+H0Wk1Ya7XkpDOtXHAd3ODy63MUkZoDweoAZbwH\n" +
-        "/M8SESIsrqC9OuCiKthZ6SnTGDWkrBFfGbW1G/8iSlzGeuQX7yCpp/Q/rYqnmgQl\n" +
-        "nQ7KN+ZQ/YxCKQSa7LnPS3K94gg2ryMvYuXKAdNw23yCIywWMQzGNgeQerEfZ1jE\n" +
-        "O1hZibCMjFCz2IbLaKPECudpSyDOwR5WS5WpI2jYMNjD67BVUc3l/Su49bsRn1NU\n" +
-        "9jQZjHkJNsphFyUXC4KYcwx3dMPVDceoEkzHp1RxRy4sGn3J4ys7SN4nhKdjNrN9\n" +
-        "j6BkOSQNPXuHr2ZcdBtLc7LljPCGmbjlxd+Ewbfr\n" +
-        "-----END CERTIFICATE-----";
-
-    // DigiNotar Public CA 2025, intermediate certificate
-    static String intermediateCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIGAzCCA+ugAwIBAgIQHn16Uz1FMEGWQA9xSB9FBDANBgkqhkiG9w0BAQUFADBf\n" +
-        "MQswCQYDVQQGEwJOTDESMBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdp\n" +
-        "Tm90YXIgUm9vdCBDQTEgMB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmww\n" +
-        "HhcNMDYwMjA2MTYwNzAyWhcNMjUwMzI4MTYwNzAyWjBmMQswCQYDVQQGEwJOTDES\n" +
-        "MBAGA1UEChMJRGlnaU5vdGFyMSEwHwYDVQQDExhEaWdpTm90YXIgUHVibGljIENB\n" +
-        "IDIwMjUxIDAeBgkqhkiG9w0BCQEWEWluZm9AZGlnaW5vdGFyLm5sMIIBIjANBgkq\n" +
-        "hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs/2eu/I5fMG8lbvPph3e8zfJpZQtg/72\n" +
-        "Yx29+ivtKehiF6A3n785XyoY6IT3vlCrhy1CbMOY3M0x1n4YQlv17B0XZ/DqHyBA\n" +
-        "SQvnDNbkM9j4NoSy/sRtGsP6PetIFFjrhE9whZuvuSUC1PY4PruEEJp8zOCx4+wU\n" +
-        "Zt9xvjy4Xra+bSia5rwccQ/R5FYTGKrYCthOy9C9ud5Fhd++rlVhgdA/78w+Cs2s\n" +
-        "xS4i0MAxG75P3/e/bATJKepbydHdDjkyz9o3RW/wdPUXhzEw4EwUjYg6XJrDzMad\n" +
-        "6aL9M/eaxDjgz6o48EaWRDrGptaE2uJRuErVz7oOO0p/wYKq/BU+/wIDAQABo4IB\n" +
-        "sjCCAa4wOgYIKwYBBQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vdmFsaWRh\n" +
-        "dGlvbi5kaWdpbm90YXIubmwwHwYDVR0jBBgwFoAUiGi/4I41xDs4a2L3KDuEgcgM\n" +
-        "100wEgYDVR0TAQH/BAgwBgEB/wIBADCBxgYDVR0gBIG+MIG7MIG4Bg5ghBABh2kB\n" +
-        "AQEBBQIGBDCBpTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdpbm90YXIubmwv\n" +
-        "Y3BzMHoGCCsGAQUFBwICMG4abENvbmRpdGlvbnMsIGFzIG1lbnRpb25lZCBvbiBv\n" +
-        "dXIgd2Vic2l0ZSAod3d3LmRpZ2lub3Rhci5ubCksIGFyZSBhcHBsaWNhYmxlIHRv\n" +
-        "IGFsbCBvdXIgcHJvZHVjdHMgYW5kIHNlcnZpY2VzLjBDBgNVHR8EPDA6MDigNqA0\n" +
-        "hjJodHRwOi8vc2VydmljZS5kaWdpbm90YXIubmwvY3JsL3Jvb3QvbGF0ZXN0Q1JM\n" +
-        "LmNybDAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFN8zwK+S/jf8ttgWFtDZsZHV\n" +
-        "+m6lMA0GCSqGSIb3DQEBBQUAA4ICAQCfV1rmBd9QStEyQ40lT0tqby0/3ez0STuJ\n" +
-        "ESBQLQD56XYdb4VFSuqA6xTtiuSVHLoiv2xyISN9FvX3A5VtifkJ00JEaLQJiSsE\n" +
-        "wGDkYGl1DT7SsqtAVKdMAuCM+e0j0/RV3hZ6kcrM7/wFccHwM+/TiurR9lgZDzB4\n" +
-        "a7++A4XrYyKx9vc9ZwBEnD1nrAe7++gg9cuZgP7e+QL0FBHMjpw+gnCDjr2dzBZC\n" +
-        "4r+b8SOqlbPRPexBuNghlc7PfcPIyFis2LJXDRMWiAd3TcfdALwRsuKMR/T+cwyr\n" +
-        "asy69OEGHplLT57otQ524BDctDXNzlH9bHEh52QzqkWvIDqs42910IUy1nYNPIUG\n" +
-        "yYJV/T7H8Jb6vfMZWe47iUFvtNZCi8+b542gRUwdi+ca+hGviBC9Qr4Wv1pl7CBQ\n" +
-        "Hy1axTkHiQawUo/hgmoetCpftugl9yJTfvsBorUV1ZMxn9B1JLSGtWnbUsFRla7G\n" +
-        "fNa0IsUkzmmha8XCzvNu0d1PDGtcQyUqmDOE1Hx4cIBeuF8ipuIXkrVCr9zAZ4ZC\n" +
-        "hgz6aA1gDTW8whSRJqYEYEQ0pcMEFLyXE+Nz3O8NinO2AuxqKhjMk13203xA7lPY\n" +
-        "MnBQ0v7S3qqbp/pvPMiUhOz/VaYted6QmOY5EATBnFiLCuw87JXoAyp382eJ3WX1\n" +
-        "hOiR4IX9Tg==\n" +
-        "-----END CERTIFICATE-----";
-
-    // The fraudulent certificate issued by above compromised CA
-    static String targetCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIFKDCCBBCgAwIBAgIQBeLmpM0J6lTWZbB1/iKiVjANBgkqhkiG9w0BAQUFADBm\n" +
-        "MQswCQYDVQQGEwJOTDESMBAGA1UEChMJRGlnaU5vdGFyMSEwHwYDVQQDExhEaWdp\n" +
-        "Tm90YXIgUHVibGljIENBIDIwMjUxIDAeBgkqhkiG9w0BCQEWEWluZm9AZGlnaW5v\n" +
-        "dGFyLm5sMB4XDTExMDcxMDE5MDYzMFoXDTEzMDcwOTE5MDYzMFowajELMAkGA1UE\n" +
-        "BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxFjAUBgNVBAcTDU1vdW50YWluIFZp\n" +
-        "ZXcxFzAVBgNVBAUTDlBLMDAwMjI5MjAwMDAyMRUwEwYDVQQDEwwqLmdvb2dsZS5j\n" +
-        "b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNbeKubCV0aCxhOiOS\n" +
-        "CSQ/w9HXTYuD5BLKuiqXNw3setdTymeJz2L8aWOHo3nicFNDVwWTgwWomGNr2J6Q\n" +
-        "7g1iINNSW0rR4E1l2szRkcnAY6c6i/Eke93nF4i2hDsnIBveolF5yjpuRm73uQQD\n" +
-        "ulHjA3BFRF/PTi0fw2/Yt+8ieoMuNcMWN6Eou5Gqt5YZkWv176ofeCbsBmMrP87x\n" +
-        "OhhtTDckCapk4VQZG2XrfzZcV6tdzCp5TI8uHdu17cdzXm1imZ8tyvzFeiCEOQN8\n" +
-        "vPNzB/fIr3CJQ5q4uM5aKT3DD5PeVzf4rfJKQNgCTWiIBc9XcWEUuszwAsnmg7e2\n" +
-        "EJRdAgMBAAGjggHMMIIByDA6BggrBgEFBQcBAQQuMCwwKgYIKwYBBQUHMAGGHmh0\n" +
-        "dHA6Ly92YWxpZGF0aW9uLmRpZ2lub3Rhci5ubDAfBgNVHSMEGDAWgBTfM8Cvkv43\n" +
-        "/LbYFhbQ2bGR1fpupTAJBgNVHRMEAjAAMIHGBgNVHSAEgb4wgbswgbgGDmCEEAGH\n" +
-        "aQEBAQIEAQICMIGlMCcGCCsGAQUFBwIBFhtodHRwOi8vd3d3LmRpZ2lub3Rhci5u\n" +
-        "bC9jcHMwegYIKwYBBQUHAgIwbhpsQ29uZGl0aW9ucywgYXMgbWVudGlvbmVkIG9u\n" +
-        "IG91ciB3ZWJzaXRlICh3d3cuZGlnaW5vdGFyLm5sKSwgYXJlIGFwcGxpY2FibGUg\n" +
-        "dG8gYWxsIG91ciBwcm9kdWN0cyBhbmQgc2VydmljZXMuMEkGA1UdHwRCMEAwPqA8\n" +
-        "oDqGOGh0dHA6Ly9zZXJ2aWNlLmRpZ2lub3Rhci5ubC9jcmwvcHVibGljMjAyNS9s\n" +
-        "YXRlc3RDUkwuY3JsMA4GA1UdDwEB/wQEAwIEsDAbBgNVHREEFDASgRBhZG1pbkBn\n" +
-        "b29nbGUuY29tMB0GA1UdDgQWBBQHSn0WJzIo0eMBMQUNsMqN6eF/7TANBgkqhkiG\n" +
-        "9w0BAQUFAAOCAQEAAs5dL7N9wzRJkI4Aq4lC5t8j5ZadqnqUcgYLADzSv4ExytNH\n" +
-        "UY2nH6iVTihC0UPSsILWraoeApdT7Rphz/8DLQEBRGdeKWAptNM3EbiXtQaZT2uB\n" +
-        "pidL8UoafX0kch3f71Y1scpBEjvu5ZZLnjg0A8AL0tnsereOVdDpU98bKqdbbrnM\n" +
-        "FRmBlSf7xdaNca6JJHeEpga4E9Ty683CmccrSGXdU2tTCuHEJww+iOAUtPIZcsum\n" +
-        "U7/eYeY1pMyGLyIjbNgRY7nDzRwvM/BsbL9eh4/mSQj/4nncqJd22sVQpCggQiVK\n" +
-        "baB2sVGcVNBkK55bT8gPqnx8JypubyUvayzZGg==\n" +
-        "-----END CERTIFICATE-----";
-
-    public static void main(String args[]) throws Exception {
-
-        Exception reservedException = null;
-        try {
-            validate();
-        } catch (CertPathValidatorException cpve) {
-            reservedException = cpve;
-        }
-
-        if (reservedException == null) {
-            throw new Exception("Unable to block fraudulent certificate");
-        }
-
-        System.out.println(
-            "The expected untrusted cert exception: " + reservedException);
-    }
-
-    private static CertPath generateCertificatePath()
-            throws CertificateException, IOException {
-
-        // generate certificate from cert strings
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-
-        // generate certification path
-        List<Certificate> list = new ArrayList();
-
-        try (ByteArrayInputStream is =
-                new ByteArrayInputStream(targetCertStr.getBytes())) {
-            list.add(cf.generateCertificate(is));
-        }
-
-        try (ByteArrayInputStream is =
-                new ByteArrayInputStream(intermediateCertStr.getBytes())) {
-            list.add(cf.generateCertificate(is));
-        }
-
-        try (ByteArrayInputStream is =
-                new ByteArrayInputStream(compromisedCertStr.getBytes())) {
-            list.add(cf.generateCertificate(is));
-        }
-
-        try (ByteArrayInputStream is =
-                new ByteArrayInputStream(untrustedCrossCertStr.getBytes())) {
-            list.add(cf.generateCertificate(is));
-        }
-
-        return cf.generateCertPath(list);
-    }
-
-    private static Set<TrustAnchor> generateTrustAnchors()
-            throws CertificateException, IOException {
-        // generate certificate from cert string
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-
-        Certificate trustedCert = null;
-        try (ByteArrayInputStream is =
-                new ByteArrayInputStream(trustedCertStr.getBytes())) {
-            trustedCert = cf.generateCertificate(is);
-        }
-
-        // generate a trust anchor
-        TrustAnchor anchor =
-            new TrustAnchor((X509Certificate)trustedCert, null);
-
-        return Collections.singleton(anchor);
-    }
-
-    private static void validate()
-            throws CertPathValidatorException, Exception {
-
-        CertPath path = generateCertificatePath();
-        Set<TrustAnchor> anchors = generateTrustAnchors();
-
-        PKIXParameters params = new PKIXParameters(anchors);
-
-        // disable certificate revocation checking
-        params.setRevocationEnabled(false);
-
-        // set the validation time
-        params.setDate(new Date(111, 11, 25));   // 2011-12-25
-
-        CertPathValidator validator = CertPathValidator.getInstance("PKIX");
-
-        validator.validate(path, params);
-    }
-}
-
diff --git a/jdk/test/sun/security/tools/policytool/ChangeUI.html b/jdk/test/sun/security/tools/policytool/ChangeUI.html
index feb9da2..d025716 100644
--- a/jdk/test/sun/security/tools/policytool/ChangeUI.html
+++ b/jdk/test/sun/security/tools/policytool/ChangeUI.html
@@ -4,7 +4,7 @@
 <applet width=100 height=100 code=ChangeUI.class>
 </applet>
 
-<b>ATTENTION:</b> policytool now contains no platform-specific codes anymore and 
+<b>ATTENTION:</b> policytool now contains no platform-specific codes anymore and
 should behaves exactly the same across all platforms. This also means:
 <ol>
     <li>You may only need to test it on one platform</li>
@@ -16,7 +16,8 @@
 reading these instructions.<br><br>
 
 First, policytool will be invoked.<br><br>
-<ol>
+<ol start="0">
+<li>If testing on Windows, create a temporary directory. (Example: C:\foo\tmp)
 <li>Add new policy entry
 <li>Add permission:
     <pre>
@@ -27,7 +28,7 @@
         <li>Press OK</li>
         <li>Confirm the file name warning dialog appears</li>
         <li>Choose Retain, confirm the permission edit dialog is closed</li>
-        <li>Double click the newly craeted FilePermission entry to edit it</li>
+        <li>Double click the newly created FilePermission entry to edit it</li>
         <li>Press OK</li>
         <li>Confirm the file name warning dialog appears</li>
         <li>Choose Edit, confirm the permission edit dialog is still opened</li>
@@ -54,15 +55,17 @@
     AllPermission
     </pre>
 <li>Add a new Principal, say, KerberosPrincipal with Principal Name as aaa
-<li>Confirm there is 1 entry in the Pricipals list
+<li>Confirm there is 1 entry in the Principals list
 <li>Confirm there are 3 entries in the permission list
 <li>Press cancel
 <li>Double click the policy entry to edit it
-<li>Confirm there is ZERO entry in the Pricipals list
+<li>Confirm there are ZERO entries in the Principals list
 <li>Confirm there are 2 entries in the permission list
 <li>Press cancel
-<li>Save as /tmp/p
-<li>Confirm that the file /tmp/p looks like
+<li>Save as "/tmp/p"<br>
+If testing on Windows, save in the temporary directory created in Step 0.
+(Example: Save as "C:\foo\tmp\p.policy")
+<li>Confirm that the file /tmp/p (or C:\foo\tmp\p.policy) looks like
 <pre>
 /* AUTOMATICALLY GENERATED ON Tue Jul 19 16:27:30 CST 2005*/
 /* DO NOT EDIT */
diff --git a/jdk/test/sun/security/tools/policytool/UpdatePermissions.html b/jdk/test/sun/security/tools/policytool/UpdatePermissions.html
index 5ae3cbc..2a59b59 100644
--- a/jdk/test/sun/security/tools/policytool/UpdatePermissions.html
+++ b/jdk/test/sun/security/tools/policytool/UpdatePermissions.html
@@ -10,6 +10,8 @@
 First, policytool will be invoked.<br><br>
 
 Then, follow these steps:<br>
+0) If testing on Windows, create a temporary directory.
+(Example: C:\foo\tmp)<br><br>
 1) Click on the "Add Policy Entry" button in the
 main policytool window.<br><br>
 
@@ -29,13 +31,18 @@
 select "Save As".<br><br>
 
 8) In the SaveAs window, enter "/tmp/ptool.test" as the file name
-and click "OK".<br><br>
+and click "OK".<br>
+If testing on Windows, use the temporary directory created in Step 0.
+(Example: Save as "C:\foo\tmp\ptool.test")<br><br>
 
-9) cat /tmp/ptool.test<br><br>
+9) cat /tmp/ptool.test<br>
+If testing on Windows, check the contents of the file created in the previous
+step.<br><br>
+
 
 10) check to make sure that the new entry is in the policy file.<br><br>
 
-11) repeat steps 1-9 for:<br>
+11) repeat steps 1-10 for:<br>
 	AWTPermission:		readDisplayPixels<br>
 	NetPermission:		specifyStreamHandler<br>
 	RuntimePermission:	setContextClassLoader,
@@ -46,7 +53,8 @@
 
 In the confirmation dialog pop-up, click "OK".<br><br>
 
-Exit policytool.<br><br>
+Exit policytool. If testing on Windows, delete the temporary directory and its
+contents created during this test.<br><br>
 
 Press "Pass" if ... press "Fail" otherwise.<br><br>
 
diff --git a/jdk/test/sun/security/tools/policytool/i18n.html b/jdk/test/sun/security/tools/policytool/i18n.html
index 73d8d57..6c70d24 100644
--- a/jdk/test/sun/security/tools/policytool/i18n.html
+++ b/jdk/test/sun/security/tools/policytool/i18n.html
@@ -17,7 +17,8 @@
 <p>
 Press "Pass" if ... press "Fail" otherwise.
 <p>
-<ol>
+<ol start="0">
+<li> If testing on Windows, create a temporary directory. (Example: C:\foo\tmp)
 <li> Pull down the 'File' and 'KeyStore' menus and check values
 <li> Pull down 'File' menu and select 'View Warning Log'.  Confirm FileNotFound.
 <li> Pull down 'File' menu and select 'New'.
@@ -54,14 +55,17 @@
 <li> Do not remove the entry, click 'Cancel'.
 <li> Pull down 'File' menu and select 'Exit'.  Confirm Save option.
 	Click 'Cancel'.
-<li> Select 'File' menu value 'Save', enter "/tmp/policy1" as the filename,
-	and check status message
+<li> Select 'File' menu value 'Save' and enter "/tmp/policy1" as the filename.<br>
+     If testing on Windows, use the temporary directory created in Step 0.
+        (Example: Save as "C:\foo\tmp\policy1")<br>
+     Check status message.
 <li> Select 'File' menu value 'New'
 <li> Click 'Add Policy Entry', type in "hello" for 'SignedBy' field,
 	click 'Done'.  Confirm warning.
 <li> Select 'File' menu value 'Open' and confirm save option
 	(do not save changes)
-<li> Type "/tmp/policy1" for the filename and confirm warning message
+<li> Type "/tmp/policy1" (if Windows, "C:\foo\tmp\policy1") for the filename
+        and confirm warning message<br>
 <li> Pull down 'File' menu, select 'View Warning Log'
 	and confirm KeyStore alias warning
 <li> Pull down 'KeyStore' menu and select 'Edit'
@@ -80,11 +84,13 @@
 <li> Pull down 'KeyStore' menu and select 'Edit'
 <li> Confirm URL, Type, Provider, and Password URL values.
 <li> Click OK
-<li> Pull down 'File' menu and select 'Save As'.  Enter /tmp/policy2.
-	Confirm status message.
+<li> Pull down 'File' menu and select 'Save As'.  Enter "/tmp/policy2"
+        (if Windows, "C:\foo\tmp\policy2").
+	Confirm status message.<br>
 <li> Pull down 'File' menu and select 'New'.
-<li> Pull down 'File' menu and select 'Open'.  Enter /tmp/policy2.
-	Confirm warning message.
+<li> Pull down 'File' menu and select 'Open'.  Enter "/tmp/policy2"
+        (if Windows, "C:\foo\tmp\policy2").
+	Confirm warning message.<br>
 <li> Click on 'Add Policy Entry', enter Codebase 'http://foo',
 	SignedBy 'bar'.  Click on 'Done' and confirm alias warning.
 <li> Double-Click on just created policy entry, confirm edit window appears.
@@ -115,6 +121,8 @@
 <li> Confirm entries in main window listing.
 <li> Select 'File' menu value 'Exit'
 <li> Save Changes, confirm status message.
+<li> If testing on Windows, delete the temporary directory and its contents
+        created during this test.
 </ol>
 <p>
 
diff --git a/jdk/test/sun/tools/jinfo/Basic.sh b/jdk/test/sun/tools/jinfo/Basic.sh
index 0fdcb9e..e12bbb3 100644
--- a/jdk/test/sun/tools/jinfo/Basic.sh
+++ b/jdk/test/sun/tools/jinfo/Basic.sh
@@ -43,8 +43,7 @@
 
 failed=0
 
-# Skip SA options for now, see 7175133
-runSA=false
+runSA=true
 
 if [ $isMacos = true ]; then
     runSA=false
diff --git a/jdk/test/sun/util/calendar/zi/Rule.java b/jdk/test/sun/util/calendar/zi/Rule.java
index 8e3a118..e8c79da 100644
--- a/jdk/test/sun/util/calendar/zi/Rule.java
+++ b/jdk/test/sun/util/calendar/zi/Rule.java
@@ -106,6 +106,7 @@
         final int y = year;
         RuleRec[] recs = new RuleRec[rules.size()];
         rules.toArray(recs);
+
         Arrays.sort(recs, new Comparator<RuleRec>() {
                 public int compare(RuleRec r1, RuleRec r2) {
                     int n = r1.getMonthNum() - r2.getMonthNum();
@@ -117,7 +118,7 @@
                                                 r1.getDay(), r1.getTime().getTime());
                     long t2 = Time.getLocalTime(y, r2.getMonth(),
                                                 r2.getDay(), r2.getTime().getTime());
-                    return (int)(t1 - t2);
+                    return Long.compare(t1, t2);
                 }
                 public boolean equals(Object o) {
                     return this == o;
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/VERSION b/jdk/test/sun/util/calendar/zi/tzdata/VERSION
index 85db871..8ad1064 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/VERSION
+++ b/jdk/test/sun/util/calendar/zi/tzdata/VERSION
@@ -21,4 +21,4 @@
 # or visit www.oracle.com if you need additional information or have any
 # questions.
 #
-tzdata2012i
+tzdata2013c
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/africa b/jdk/test/sun/util/calendar/zi/tzdata/africa
index 7db9b3d..2f5d3c5 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/africa
+++ b/jdk/test/sun/util/calendar/zi/tzdata/africa
@@ -27,9 +27,9 @@
 
 # This data is by no means authoritative; if you think you know better,
 # go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
+# tz@iana.org for general use in the future).
 
-# From Paul Eggert (2006-03-22):
+# From Paul Eggert (2013-02-21):
 #
 # A good source for time zone historical data outside the U.S. is
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
@@ -48,6 +48,10 @@
 # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
 # I found in the UCLA library.
 #
+# For data circa 1899, a common source is:
+# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+# <http://www.jstor.org/stable/1774359>.
+#
 # A reliable and entertaining source about time zones is
 # Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
 #
@@ -139,8 +143,12 @@
 			1:00	-	WAT
 
 # Botswana
+# From Paul Eggert (2013-02-21):
+# Milne says they were regulated by the Cape Town Signal in 1899;
+# assume they switched to 2:00 when Cape Town did.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Gaborone	1:43:40 -	LMT	1885
+			1:30	-	SAST	1903 Mar
 			2:00	-	CAT	1943 Sep 19 2:00
 			2:00	1:00	CAST	1944 Mar 19 2:00
 			2:00	-	CAT
@@ -212,6 +220,11 @@
 
 # Egypt
 
+# Milne says Cairo used 2:05:08.9, the local mean time of the Abbasizeh
+# observatory; round to nearest.  Milne also says that the official time for
+# Egypt was mean noon at the Great Pyramid, 2:04:30.5, but apparently this
+# did not apply to Cairo, Alexandria, or Port Said.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Egypt	1940	only	-	Jul	15	0:00	1:00	S
 Rule	Egypt	1940	only	-	Oct	 1	0:00	0	-
@@ -352,7 +365,7 @@
 Rule	Egypt	2010	only	-	Sep	lastThu	23:00s	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Cairo	2:05:00 -	LMT	1900 Oct
+Zone	Africa/Cairo	2:05:09 -	LMT	1900 Oct
 			2:00	Egypt	EE%sT
 
 # Equatorial Guinea
@@ -447,6 +460,20 @@
 
 # Libya
 
+# From Even Scharning (2012-11-10):
+# Libya set their time one hour back at 02:00 on Saturday November 10.
+# http://www.libyaherald.com/2012/11/04/clocks-to-go-back-an-hour-on-saturday/
+# Here is an official source [in Arabic]: http://ls.ly/fb6Yc
+#
+# Steffen Thorsen forwarded a translation (2012-11-10) in
+# http://mm.icann.org/pipermail/tz/2012-November/018451.html
+#
+# From Tim Parenti (2012-11-11):
+# Treat the 2012-11-10 change as a zone change from UTC+2 to UTC+1.
+# The DST rules planned for 2013 and onward roughly mirror those of Europe
+# (either two days before them or five days after them, so as to fall on
+# lastFri instead of lastSun).
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Libya	1951	only	-	Oct	14	2:00	1:00	S
 Rule	Libya	1952	only	-	Jan	 1	0:00	0	-
@@ -461,17 +488,21 @@
 Rule	Libya	1986	only	-	Oct	 3	0:00	0	-
 Rule	Libya	1987	1989	-	Apr	 1	0:00	1:00	S
 Rule	Libya	1987	1989	-	Oct	 1	0:00	0	-
+Rule	Libya	1997	only	-	Apr	 4	0:00	1:00	S
+Rule	Libya	1997	only	-	Oct	 4	0:00	0	-
+Rule	Libya	2013	max	-	Mar	lastFri	1:00	1:00	S
+Rule	Libya	2013	max	-	Oct	lastFri	2:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Tripoli	0:52:44 -	LMT	1920
 			1:00	Libya	CE%sT	1959
 			2:00	-	EET	1982
 			1:00	Libya	CE%sT	1990 May  4
-# The following entries are from Shanks & Pottenger;
+# The 1996 and 1997 entries are from Shanks & Pottenger;
 # the IATA SSIM data contain some obvious errors.
 			2:00	-	EET	1996 Sep 30
-			1:00	-	CET	1997 Apr  4
-			1:00	1:00	CEST	1997 Oct  4
-			2:00	-	EET
+			1:00	Libya	CE%sT	1997 Oct  4
+			2:00	-	EET	2012 Nov 10 2:00
+			1:00	Libya	CE%sT
 
 # Madagascar
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -838,6 +869,41 @@
 # 3:00 am Friday, July 20, 2012 and will again be advanced by 60 minutes
 # August 20, 2012 from 2:00 am.
 
+# From Paul Eggert (2013-03-06):
+# Morocco's daylight-saving transitions due to Ramadan seem to be
+# announced a bit in advance.  On 2012-07-11 the Moroccan government
+# announced that year's Ramadan daylight-saving transitions would be
+# 2012-07-20 and 2012-08-20; see
+# <http://www.mmsp.gov.ma/fr/actualites.aspx?id=288>.
+#
+# To estimate what the Moroccan government will do in future years,
+# transition dates for 2013 through 2021 were determined by running
+# the following program under GNU Emacs 24.3:
+#
+# (let ((islamic-year 1434))
+#   (while (< islamic-year 1444)
+#     (let ((a
+#	     (calendar-gregorian-from-absolute
+#	      (calendar-islamic-to-absolute (list 9 1 islamic-year))))
+#	    (b
+#	     (calendar-gregorian-from-absolute
+#	      (calendar-islamic-to-absolute (list 10 1 islamic-year)))))
+#	(insert
+#	 (format
+#	  (concat "Rule\tMorocco\t%d\tonly\t-\t%s\t %2d\t 3:00\t0\t-\n"
+#		  "Rule\tMorocco\t%d\tonly\t-\t%s\t %2d\t 2:00\t1:00\tS\n")
+#	  (car (cdr (cdr a))) (calendar-month-name (car a) t) (car (cdr a))
+#	  (car (cdr (cdr b))) (calendar-month-name (car b) t) (car (cdr b)))))
+#     (setq islamic-year (+ 1 islamic-year))))
+#
+# with the results hand-edited for 2020-2022, when the normal spring-forward
+# date falls during the estimated Ramadan.
+#
+# From 2023 through 2038 Ramadan is not predicted to overlap with
+# daylight saving time.  Starting in 2039 there will be overlap again,
+# but 32-bit time_t values roll around in 2038 so for now do not worry
+# about dates after 2038.
+
 # RULE	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 
 Rule	Morocco	1939	only	-	Sep	12	 0:00	1:00	S
@@ -863,10 +929,28 @@
 Rule	Morocco	2010	only	-	Aug	 8	 0:00	0	-
 Rule	Morocco	2011	only	-	Apr	 3	 0:00	1:00	S
 Rule	Morocco	2011	only	-	Jul	 31	 0	0	-
-Rule	Morocco	2012	max	-	Apr	 lastSun 2:00	1:00	S
+Rule	Morocco	2012	2019	-	Apr	 lastSun 2:00	1:00	S
 Rule	Morocco	2012	max	-	Sep	 lastSun 3:00	0	-
 Rule	Morocco	2012	only	-	Jul	 20	 3:00	0	-
 Rule	Morocco	2012	only	-	Aug	 20	 2:00	1:00	S
+Rule	Morocco	2013	only	-	Jul	  9	 3:00	0	-
+Rule	Morocco	2013	only	-	Aug	  8	 2:00	1:00	S
+Rule	Morocco	2014	only	-	Jun	 29	 3:00	0	-
+Rule	Morocco	2014	only	-	Jul	 29	 2:00	1:00	S
+Rule	Morocco	2015	only	-	Jun	 18	 3:00	0	-
+Rule	Morocco	2015	only	-	Jul	 18	 2:00	1:00	S
+Rule	Morocco	2016	only	-	Jun	  7	 3:00	0	-
+Rule	Morocco	2016	only	-	Jul	  7	 2:00	1:00	S
+Rule	Morocco	2017	only	-	May	 27	 3:00	0	-
+Rule	Morocco	2017	only	-	Jun	 26	 2:00	1:00	S
+Rule	Morocco	2018	only	-	May	 16	 3:00	0	-
+Rule	Morocco	2018	only	-	Jun	 15	 2:00	1:00	S
+Rule	Morocco	2019	only	-	May	  6	 3:00	0	-
+Rule	Morocco	2019	only	-	Jun	  5	 2:00	1:00	S
+Rule	Morocco	2020	only	-	May	 24	 2:00	1:00	S
+Rule	Morocco	2021	only	-	May	 13	 2:00	1:00	S
+Rule	Morocco	2022	only	-	May	  3	 2:00	1:00	S
+Rule	Morocco	2023	max	-	Apr	 lastSun 2:00	1:00	S
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Africa/Casablanca	-0:30:20 -	LMT	1913 Oct 26
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/antarctica b/jdk/test/sun/util/calendar/zi/tzdata/antarctica
index 64b71d5..daa03ea 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/antarctica
+++ b/jdk/test/sun/util/calendar/zi/tzdata/antarctica
@@ -73,38 +73,8 @@
 Rule	ChileAQ	2010	only	-	Apr	Sun>=1	3:00u	0	-
 Rule	ChileAQ	2011	only	-	May	Sun>=2	3:00u	0	-
 Rule	ChileAQ	2011	only	-	Aug	Sun>=16	4:00u	1:00	S
-Rule	ChileAQ	2012	only	-	Apr	Sun>=23	3:00u	0	-
-Rule	ChileAQ	2012	only	-	Sep	Sun>=2	4:00u	1:00	S
-Rule	ChileAQ	2013	max	-	Mar	Sun>=9	3:00u	0	-
-Rule	ChileAQ	2013	max	-	Oct	Sun>=9	4:00u	1:00	S
-
-# These rules are stolen from the `australasia' file.
-Rule	AusAQ	1917	only	-	Jan	 1	0:01	1:00	-
-Rule	AusAQ	1917	only	-	Mar	25	2:00	0	-
-Rule	AusAQ	1942	only	-	Jan	 1	2:00	1:00	-
-Rule	AusAQ	1942	only	-	Mar	29	2:00	0	-
-Rule	AusAQ	1942	only	-	Sep	27	2:00	1:00	-
-Rule	AusAQ	1943	1944	-	Mar	lastSun	2:00	0	-
-Rule	AusAQ	1943	only	-	Oct	 3	2:00	1:00	-
-Rule	ATAQ	1967	only	-	Oct	Sun>=1	2:00s	1:00	-
-Rule	ATAQ	1968	only	-	Mar	lastSun	2:00s	0	-
-Rule	ATAQ	1968	1985	-	Oct	lastSun	2:00s	1:00	-
-Rule	ATAQ	1969	1971	-	Mar	Sun>=8	2:00s	0	-
-Rule	ATAQ	1972	only	-	Feb	lastSun	2:00s	0	-
-Rule	ATAQ	1973	1981	-	Mar	Sun>=1	2:00s	0	-
-Rule	ATAQ	1982	1983	-	Mar	lastSun	2:00s	0	-
-Rule	ATAQ	1984	1986	-	Mar	Sun>=1	2:00s	0	-
-Rule	ATAQ	1986	only	-	Oct	Sun>=15	2:00s	1:00	-
-Rule	ATAQ	1987	1990	-	Mar	Sun>=15	2:00s	0	-
-Rule	ATAQ	1987	only	-	Oct	Sun>=22	2:00s	1:00	-
-Rule	ATAQ	1988	1990	-	Oct	lastSun	2:00s	1:00	-
-Rule	ATAQ	1991	1999	-	Oct	Sun>=1	2:00s	1:00	-
-Rule	ATAQ	1991	2005	-	Mar	lastSun	2:00s	0	-
-Rule	ATAQ	2000	only	-	Aug	lastSun	2:00s	1:00	-
-Rule	ATAQ	2001	max	-	Oct	Sun>=1	2:00s	1:00	-
-Rule	ATAQ	2006	only	-	Apr	Sun>=1	2:00s	0	-
-Rule	ATAQ	2007	only	-	Mar	lastSun	2:00s	0	-
-Rule	ATAQ	2008	max	-	Apr	Sun>=1	2:00s	0	-
+Rule	ChileAQ	2012	max	-	Apr	Sun>=23	3:00u	0	-
+Rule	ChileAQ	2012	max	-	Sep	Sun>=2	4:00u	1:00	S
 
 # Argentina - year-round bases
 # Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05
@@ -147,10 +117,7 @@
 # </a>
 
 # From Steffen Thorsen (2010-03-10):
-# We got these changes from the Australian Antarctic Division:
-# - Macquarie Island will stay on UTC+11 for winter and therefore not
-# switch back from daylight savings time when other parts of Australia do
-# on 4 April.
+# We got these changes from the Australian Antarctic Division: ...
 #
 # - Casey station reverted to its normal time of UTC+8 on 5 March 2010.
 # The change to UTC+11 is being considered as a regular summer thing but
@@ -161,9 +128,6 @@
 #
 # - Mawson station stays on UTC+5.
 #
-# In addition to the Rule changes for Casey/Davis, it means that Macquarie
-# will no longer be like Hobart and will have to have its own Zone created.
-#
 # Background:
 # <a href="http://www.timeanddate.com/news/time/antartica-time-changes-2010.html">
 # http://www.timeanddate.com/news/time/antartica-time-changes-2010.html
@@ -190,12 +154,6 @@
 			6:00	-	MAWT	2009 Oct 18 2:00
 						# Mawson Time
 			5:00	-	MAWT
-Zone Antarctica/Macquarie 0	-	zzz	1911
-			10:00	-	EST	1916 Oct 1 2:00
-			10:00	1:00	EST	1917 Feb
-			10:00	AusAQ	EST	1967
-			10:00	ATAQ	EST	2010 Apr 4 3:00
-			11:00	-	MIST	# Macquarie Island Time
 # References:
 # <a href="http://www.antdiv.gov.au/aad/exop/sfo/casey/casey_aws.html">
 # Casey Weather (1998-02-26)
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/asia b/jdk/test/sun/util/calendar/zi/tzdata/asia
index 9ef3ef8..7818c02 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/asia
+++ b/jdk/test/sun/util/calendar/zi/tzdata/asia
@@ -27,9 +27,9 @@
 
 # This data is by no means authoritative; if you think you know better,
 # go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
+# tz@iana.org for general use in the future).
 
-# From Paul Eggert (2006-03-22):
+# From Paul Eggert (2013-02-21):
 #
 # A good source for time zone historical data outside the U.S. is
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
@@ -48,6 +48,10 @@
 # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
 # I found in the UCLA library.
 #
+# For data circa 1899, a common source is:
+# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+# <http://www.jstor.org/stable/1774359>.
+#
 # A reliable and entertaining source about time zones is
 # Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
 #
@@ -302,9 +306,12 @@
 			8:00	-	BNT
 
 # Burma / Myanmar
+
+# Milne says 6:24:40 was the meridian of the time ball observatory at Rangoon.
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Rangoon	6:24:40 -	LMT	1880		# or Yangon
-			6:24:36	-	RMT	1920	   # Rangoon Mean Time?
+			6:24:40	-	RMT	1920	   # Rangoon Mean Time?
 			6:30	-	BURT	1942 May   # Burma Time
 			9:00	-	JST	1945 May 3
 			6:30	-	MMT		   # Myanmar Time
@@ -407,7 +414,8 @@
 			8:00	PRC	C%sT
 # Zhongyuan Time ("Central plain Time")
 # most of China
-Zone	Asia/Shanghai	8:05:52	-	LMT	1928
+# Milne gives 8:05:56.7; round to nearest.
+Zone	Asia/Shanghai	8:05:57	-	LMT	1928
 			8:00	Shang	C%sT	1949
 			8:00	PRC	C%sT
 # Long-shu Time (probably due to Long and Shu being two names of that area)
@@ -504,6 +512,10 @@
 			8:00	PRC	C%sT
 
 
+# Hong Kong (Xianggang)
+
+# Milne gives 7:36:41.7; round this.
+
 # From Lee Yiu Chung (2009-10-24):
 # I found there are some mistakes for the...DST rule for Hong
 # Kong. [According] to the DST record from Hong Kong Observatory (actually,
@@ -570,7 +582,6 @@
 # The Japanese surrender of Hong Kong was signed 1945-09-15.
 # For lack of anything better, use start of those days as the transition times.
 
-# Hong Kong (Xianggang)
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	HK	1941	only	-	Apr	1	3:30	1:00	S
 Rule	HK	1941	only	-	Sep	30	3:30	0	-
@@ -592,7 +603,7 @@
 Rule	HK	1979	only	-	May	Sun>=8	3:30	1:00	S
 Rule	HK	1979	only	-	Oct	Sun>=16	3:30	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Hong_Kong	7:36:36 -	LMT	1904 Oct 30
+Zone	Asia/Hong_Kong	7:36:42 -	LMT	1904 Oct 30
 			8:00	HK	HK%sT	1941 Dec 25
 			9:00	-	JST	1945 Sep 15
 			8:00	HK	HK%sT
@@ -669,6 +680,9 @@
 ###############################################################################
 
 # Cyprus
+#
+# Milne says the Eastern Telegraph Company used 2:14:00.  Stick with LMT.
+#
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Cyprus	1975	only	-	Apr	13	0:00	1:00	S
 Rule	Cyprus	1975	only	-	Oct	12	0:00	0	-
@@ -1222,7 +1236,6 @@
 Rule	Zion	2012	only	-	Sep	23	2:00	0	S
 
 # From Ephraim Silverberg (2012-10-18):
-
 # Yesterday, the Interior Ministry Committee, after more than a year
 # past, approved sending the proposed June 2011 changes to the Time
 # Decree Law back to the Knesset for second and third (final) votes
@@ -1235,6 +1248,10 @@
 # later (i.e. at 02:00 the first Monday after October 2).
 # [Rosh Hashana holidays are factored in until 2100.]
 
+# From Ephraim Silverberg (2012-11-05):
+# The Knesset passed today (in second and final readings) the amendment to the
+# Time Decree Law making the changes ... law.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Zion	2013	max	-	Mar	Fri>=23	2:00	1:00	D
 Rule	Zion	2013	2026	-	Oct	Sun>=2	2:00	0	S
@@ -1824,8 +1841,11 @@
 			5:45	-	NPT	# Nepal Time
 
 # Oman
+
+# Milne says 3:54:24 was the meridian of the Muscat Tidal Observatory.
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Muscat	3:54:20 -	LMT	1920
+Zone	Asia/Muscat	3:54:24 -	LMT	1920
 			4:00	-	GST
 
 # Pakistan
@@ -2072,8 +2092,7 @@
 # occurred before our cutoff date of 1970.
 # However, as we get more information, we may need to add entries
 # for parts of the West Bank as they transitioned from Israel's rules
-# to Palestine's rules.  If you have more info about this, please
-# send it to tz@elsie.nci.nih.gov for incorporation into future editions.
+# to Palestine's rules.
 
 # From IINS News Service - Israel - 1998-03-23 10:38:07 Israel time,
 # forwarded by Ephraim Silverberg:
@@ -2295,11 +2314,20 @@
 # http://www.timeanddate.com/news/time/gaza-west-bank-dst-2012.html
 # </a>
 
-# From Arthur David Olson (2012-03-27):
-# The timeanddate article for 2012 says that "the end date has not yet been
-# announced" and that "Last year, both...paused daylight saving time during...
-# Ramadan. It is not yet known [for] 2012."
-# For now, assume both switch back on the last Friday in September. XXX
+# From Steffen Thorsen (2013-03-26):
+# The following news sources tells that Palestine will "start daylight saving
+# time from midnight on Friday, March 29, 2013" (translated).
+# [These are in Arabic and are for Gaza and for Ramallah, respectively.]
+# http://www.samanews.com/index.php?act=Show&id=154120
+# http://safa.ps/details/news/99844/%D8%B1%D8%A7%D9%85-%D8%A7%D9%84%D9%84%D9%87-%D8%A8%D8%AF%D8%A1-%D8%A7%D9%84%D8%AA%D9%88%D9%82%D9%8A%D8%AA-%D8%A7%D9%84%D8%B5%D9%8A%D9%81%D9%8A-29-%D8%A7%D9%84%D8%AC%D8%A7%D8%B1%D9%8A.html
+
+# From Paul Eggert (2013-04-15):
+# For future dates, guess the last Thursday in March at 24:00 through
+# the first Friday on or after September 21 at 01:00.  This is consistent with
+# the predictions in today's editions of the following URLs,
+# which are for Gaza and Hebron respectively:
+# http://www.timeanddate.com/worldclock/timezone.html?n=702
+# http://www.timeanddate.com/worldclock/timezone.html?n=2364
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule EgyptAsia	1957	only	-	May	10	0:00	1:00	S
@@ -2313,19 +2341,20 @@
 Rule Palestine	1999	2003	-	Oct	Fri>=15	0:00	0	-
 Rule Palestine	2004	only	-	Oct	 1	1:00	0	-
 Rule Palestine	2005	only	-	Oct	 4	2:00	0	-
-Rule Palestine	2006	2008	-	Apr	 1	0:00	1:00	S
+Rule Palestine	2006	2007	-	Apr	 1	0:00	1:00	S
 Rule Palestine	2006	only	-	Sep	22	0:00	0	-
 Rule Palestine	2007	only	-	Sep	Thu>=8	2:00	0	-
-Rule Palestine	2008	only	-	Aug	lastFri	0:00	0	-
-Rule Palestine	2009	only	-	Mar	lastFri	0:00	1:00	S
-Rule Palestine	2009	only	-	Sep	Fri>=1	2:00	0	-
-Rule Palestine	2010	only	-	Mar	lastSat	0:01	1:00	S
+Rule Palestine	2008	2009	-	Mar	lastFri	0:00	1:00	S
+Rule Palestine	2008	only	-	Sep	 1	0:00	0	-
+Rule Palestine	2009	only	-	Sep	Fri>=1	1:00	0	-
+Rule Palestine	2010	only	-	Mar	26	0:00	1:00	S
 Rule Palestine	2010	only	-	Aug	11	0:00	0	-
-
-# From Arthur David Olson (2011-09-20):
-# 2011 transitions per http://www.timeanddate.com as of 2011-09-20.
-# From Paul Eggert (2012-10-12):
-# 2012 transitions per http://www.timeanddate.com as of 2012-10-12.
+Rule Palestine	2011	only	-	Apr	 1	0:01	1:00	S
+Rule Palestine	2011	only	-	Aug	 1	0:00	0	-
+Rule Palestine	2011	only	-	Aug	30	0:00	1:00	S
+Rule Palestine	2011	only	-	Sep	30	0:00	0	-
+Rule Palestine	2012	max	-	Mar	lastThu	24:00	1:00	S
+Rule Palestine	2012	max	-	Sep	Fri>=21	1:00	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Gaza	2:17:52	-	LMT	1900 Oct
@@ -2333,26 +2362,20 @@
 			2:00 EgyptAsia	EE%sT	1967 Jun  5
 			2:00	Zion	I%sT	1996
 			2:00	Jordan	EE%sT	1999
-			2:00 Palestine	EE%sT	2011 Apr  2 12:01
-			2:00	1:00	EEST	2011 Aug  1
-			2:00	-	EET	2012 Mar 30
-			2:00	1:00	EEST	2012 Sep 21 1:00
-			2:00	-	EET
+			2:00 Palestine	EE%sT	2008 Aug 29 0:00
+			2:00	-	EET	2008 Sep
+			2:00 Palestine	EE%sT	2010
+			2:00	-	EET	2010 Mar 27 0:01
+			2:00 Palestine	EE%sT	2011 Aug  1
+			2:00	-	EET	2012
+			2:00 Palestine	EE%sT
 
 Zone	Asia/Hebron	2:20:23	-	LMT	1900 Oct
 			2:00	Zion	EET	1948 May 15
 			2:00 EgyptAsia	EE%sT	1967 Jun  5
 			2:00	Zion	I%sT	1996
 			2:00	Jordan	EE%sT	1999
-			2:00 Palestine	EE%sT	2008 Aug
-			2:00 	1:00	EEST	2008 Sep
-			2:00 Palestine	EE%sT	2011 Apr  1 12:01
-			2:00	1:00	EEST	2011 Aug  1
-			2:00	-	EET	2011 Aug 30
-			2:00	1:00	EEST	2011 Sep 30 3:00
-			2:00	-	EET	2012 Mar 30
-			2:00	1:00	EEST	2012 Sep 21 1:00
-			2:00	-	EET
+			2:00 Palestine	EE%sT
 
 # Paracel Is
 # no information
@@ -2421,6 +2444,13 @@
 # no information
 
 # Sri Lanka
+
+# From Paul Eggert (2013-02-21):
+# Milne says "Madras mean time use from May 1, 1898.  Prior to this Colombo
+# mean time, 5h. 4m. 21.9s. F., was used."  But 5:04:21.9 differs considerably
+# from Colombo's meridian 5:19:24, so for now ignore Milne and stick with
+# Shanks and Pottenger.
+
 # From Paul Eggert (1996-09-03):
 # "Sri Lanka advances clock by an hour to avoid blackout"
 # (www.virtual-pc.com/lankaweb/news/items/240596-2.html, 1996-05-24,
@@ -2720,6 +2750,12 @@
 
 # Vietnam
 
+# From Paul Eggert (2013-02-21):
+# Milne gives 7:16:56 for the meridian of Saigon in 1899, as being
+# used in Lower Laos, Cambodia, and Annam.  But this is quite a ways
+# from Saigon's location.  For now, ignore this and stick with Shanks
+# and Pottenger.
+
 # From Arthur David Olson (2008-03-18):
 # The English-language name of Vietnam's most populous city is "Ho Chi Min City";
 # we use Ho_Chi_Minh below to avoid a name of more than 14 characters.
@@ -2733,6 +2769,10 @@
 			7:00	-	ICT
 
 # Yemen
+
+# Milne says 2:59:54 was the meridian of the saluting battery at Aden,
+# and that Yemen was at 1:55:56, the meridian of the Hagia Sophia.
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Aden	3:00:48	-	LMT	1950
+Zone	Asia/Aden	2:59:54	-	LMT	1950
 			3:00	-	AST
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/australasia b/jdk/test/sun/util/calendar/zi/tzdata/australasia
index 7f83448..db954a8 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/australasia
+++ b/jdk/test/sun/util/calendar/zi/tzdata/australasia
@@ -241,9 +241,26 @@
 # no times are set
 #
 # Macquarie
-# permanent occupation (scientific station) since 1948;
-# sealing and penguin oil station operated 1888/1917
-# like Australia/Hobart
+# Permanent occupation (scientific station) 1911-1915 and since 25 March 1948;
+# sealing and penguin oil station operated Nov 1899 to Apr 1919.  See the
+# Tasmania Parks & Wildlife Service history of sealing at Macquarie Island
+# <http://www.parks.tas.gov.au/index.aspx?base=1828>
+# <http://www.parks.tas.gov.au/index.aspx?base=1831>.
+# Guess that it was like Australia/Hobart while inhabited before 2010.
+#
+# From Steffen Thorsen (2010-03-10):
+# We got these changes from the Australian Antarctic Division:
+# - Macquarie Island will stay on UTC+11 for winter and therefore not
+# switch back from daylight savings time when other parts of Australia do
+# on 4 April.
+Zone Antarctica/Macquarie 0	-	zzz	1899 Nov
+			10:00	-	EST	1916 Oct 1 2:00
+			10:00	1:00	EST	1917 Feb
+			10:00	Aus	EST	1919 Apr
+			0	-	zzz	1948 Mar 25
+			10:00	Aus	EST	1967
+			10:00	AT	EST	2010 Apr 4 3:00
+			11:00	-	MIST	# Macquarie I Standard Time
 
 # Christmas
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -269,6 +286,9 @@
 			6:30	-	CCT	# Cocos Islands Time
 
 # Fiji
+
+# Milne gives 11:55:44 for Suva.
+
 # From Alexander Krivenyshev (2009-11-10):
 # According to Fiji Broadcasting Corporation,  Fiji plans to re-introduce DST
 # from November 29th 2009  to April 25th 2010.
@@ -362,7 +382,7 @@
 Rule	Fiji	2011	only	-	Mar	Sun>=1	3:00	0	-
 Rule	Fiji	2012	max	-	Jan	Sun>=18	3:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Pacific/Fiji	11:53:40 -	LMT	1915 Oct 26	# Suva
+Zone	Pacific/Fiji	11:55:44 -	LMT	1915 Oct 26	# Suva
 			12:00	Fiji	FJ%sT	# Fiji Time
 
 # French Polynesia
@@ -803,9 +823,9 @@
 
 # This data is by no means authoritative; if you think you know better,
 # go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
+# tz@iana.org for general use in the future).
 
-# From Paul Eggert (2006-03-22):
+# From Paul Eggert (2013-02-21):
 # A good source for time zone historical data outside the U.S. is
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
 # San Diego: ACS Publications, Inc. (2003).
@@ -823,6 +843,10 @@
 # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
 # I found in the UCLA library.
 #
+# For data circa 1899, a common source is:
+# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+# <http://www.jstor.org/stable/1774359>.
+#
 # A reliable and entertaining source about time zones is
 # Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
 #
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/europe b/jdk/test/sun/util/calendar/zi/tzdata/europe
index 9a0d0b9..268504d 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/europe
+++ b/jdk/test/sun/util/calendar/zi/tzdata/europe
@@ -27,7 +27,7 @@
 
 # This data is by no means authoritative; if you think you know better,
 # go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
+# tz@iana.org for general use in the future).
 
 # From Paul Eggert (2006-03-22):
 # A good source for time zone historical data outside the U.S. is
@@ -53,6 +53,12 @@
 #	William Willett, The Waste of Daylight, 19th edition
 #	</a> (1914-03)
 #
+#	Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+#	<http://www.jstor.org/stable/1774359>.  He writes:
+#	"It is requested that corrections and additions to these tables
+#	may be sent to Mr. John Milne, Royal Geographical Society,
+#	Savile Row, London."  Nowadays please email them to tz@iana.org.
+#
 #	Brazil's Departamento Servico da Hora (DSH),
 #	<a href="http://pcdsh01.on.br/HISTHV.htm">
 #	History of Summer Time
@@ -689,6 +695,8 @@
 
 # Austria
 
+# Milne says Vienna time was 1:05:21.
+
 # From Paul Eggert (2006-03-22): Shanks & Pottenger give 1918-06-16 and
 # 1945-11-18, but the Austrian Federal Office of Metrology and
 # Surveying (BEV) gives 1918-09-16 and for Vienna gives the "alleged"
@@ -706,7 +714,7 @@
 Rule	Austria	1980	only	-	Apr	 6	0:00	1:00	S
 Rule	Austria	1980	only	-	Sep	28	0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Vienna	1:05:20 -	LMT	1893 Apr
+Zone	Europe/Vienna	1:05:21 -	LMT	1893 Apr
 			1:00	C-Eur	CE%sT	1920
 			1:00	Austria	CE%sT	1940 Apr  1 2:00s
 			1:00	C-Eur	CE%sT	1945 Apr  2 2:00s
@@ -1262,6 +1270,21 @@
 			1:00	Germany	CE%sT	1980
 			1:00	EU	CE%sT
 
+# From Tobias Conradi (2011-09-12):
+# Busingen <http://www.buesingen.de>, surrounded by the Swiss canton
+# Schaffhausen, did not start observing DST in 1980 as the rest of DE
+# (West Germany at that time) and DD (East Germany at that time) did.
+# DD merged into DE, the area is currently covered by code DE in ISO 3166-1,
+# which in turn is covered by the zone Europe/Berlin.
+#
+# Source for the time in Busingen 1980:
+# http://www.srf.ch/player/video?id=c012c029-03b7-4c2b-9164-aa5902cd58d3
+
+# From Arthur David Olson (2012-03-03):
+# Busingen and Zurich have shared clocks since 1970.
+
+Link	Europe/Zurich	Europe/Busingen
+
 # Georgia
 # Please see the "asia" file for Asia/Tbilisi.
 # Herodotus (Histories, IV.45) says Georgia north of the Phasis (now Rioni)
@@ -2066,6 +2089,70 @@
 
 # Russia
 
+# From Alexander Krivenyshev (2011-09-15):
+# Based on last Russian Government Decree # 725 on August 31, 2011
+# (Government document
+# <a href="http://www.government.ru/gov/results/16355/print/">
+# http://www.government.ru/gov/results/16355/print/
+# </a>
+# in Russian)
+# there are few corrections have to be made for some Russian time zones...
+# All updated Russian Time Zones were placed in table and translated to English
+# by WorldTimeZone.com at the link below:
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_russia36.htm">
+# http://www.worldtimezone.com/dst_news/dst_news_russia36.htm
+# </a>
+
+# From Sanjeev Gupta (2011-09-27):
+# Scans of [Decree #23 of January 8, 1992] are available at:
+# <a href="http://government.consultant.ru/page.aspx?1223966">
+# http://government.consultant.ru/page.aspx?1223966
+# They are in Cyrillic letters (presumably Russian).
+
+# From Arthur David Olson (2012-05-09):
+# Regarding the instant when clocks in time-zone-shifting parts of Russia
+# changed in September 2011:
+#
+# One source is
+# < a href="http://government.ru/gov/results/16355/>
+# http://government.ru/gov/results/16355/
+# </a>
+# which, according to translate.google.com, begins "Decree of August 31,
+# 2011 No 725" and contains no other dates or "effective date" information.
+#
+# Another source is
+# <a href="http://www.rg.ru/2011/09/06/chas-zona-dok.html">
+# http://www.rg.ru/2011/09/06/chas-zona-dok.html
+# </a>
+# which, according to translate.google.com, begins "Resolution of the
+# Government of the Russian Federation on August 31, 2011 N 725" and also
+# contains "Date first official publication: September 6, 2011 Posted on:
+# in the 'RG' - Federal Issue number 5573 September 6, 2011" but which
+# does not contain any "effective date" information.
+#
+# Another source is
+# <a href="http://en.wikipedia.org/wiki/Oymyakonsky_District#cite_note-RuTime-7">
+# http://en.wikipedia.org/wiki/Oymyakonsky_District#cite_note-RuTime-7
+# </a>
+# which, in note 8, contains "Resolution #725 of August 31, 2011...
+# Effective as of after 7 days following the day of the official publication"
+# but which does not contain any reference to September 6, 2011.
+#
+# The Wikipedia article refers to
+# <a href="http://base.consultant.ru/cons/cgi/online.cgi?req=doc;base=LAW;n=118896">
+# http://base.consultant.ru/cons/cgi/online.cgi?req=doc;base=LAW;n=118896
+# </a>
+# which seems to copy the text of the government.ru page.
+#
+# Tobias Conradi combines Wikipedia's
+# "as of after 7 days following the day of the official publication"
+# with www.rg.ru's "Date of first official publication: September 6, 2011" to get
+# September 13, 2011 as the cutover date (unusually, a Tuesday, as Tobias Conradi notes).
+#
+# None of the sources indicates a time of day for changing clocks.
+#
+# Go with 2011-09-13 0:00s.
+
 # From Paul Eggert (2006-03-22):
 # Except for Moscow after 1919-07-01, I invented the time zone abbreviations.
 # Moscow time zone abbreviations after 1919-07-01, and Moscow rules after 1991,
@@ -2293,14 +2380,32 @@
 # [parts of] Respublika Sakha (Yakutiya).
 
 # From Oscar van Vlijmen (2009-11-29):
-# The Sakha districts are: Bulunskij, Verkhoyanskij, Tomponskij, Ust'-Majskij,
-# Ust'-Yanskij.
+# The Sakha districts are: Bulunskij, Verkhoyanskij, ... Ust'-Yanskij.
 Zone Asia/Vladivostok	 8:47:44 -	LMT	1922 Nov 15
 			 9:00	-	VLAT	1930 Jun 21 # Vladivostok Time
 			10:00	Russia	VLA%sT	1991 Mar 31 2:00s
 			 9:00	Russia	VLA%sST	1992 Jan 19 2:00s
 			10:00	Russia	VLA%sT	2011 Mar 27 2:00s
 			11:00	-	VLAT
+
+# From Arthur David Olson (2012-05-09):
+# Tomponskij and Ust'-Majskij switched from Vladivostok time to Yakutsk time
+# in 2011.
+#
+# From Paul Eggert (2012-11-25):
+# Shanks and Pottenger (2003) has Khandyga on Yakutsk time.
+# Make a wild guess that it switched to Vladivostok time in 2004.
+# This transition is no doubt wrong, but we have no better info.
+#
+Zone Asia/Khandyga	 9:02:13 -	LMT	1919 Dec 15
+			 8:00	-	YAKT	1930 Jun 21 # Yakutsk Time
+			 9:00	Russia	YAK%sT	1991 Mar 31 2:00s
+			 8:00	Russia	YAK%sT	1992 Jan 19 2:00s
+			 9:00	Russia	YAK%sT	2004
+			10:00	Russia	VLA%sT	2011 Mar 27 2:00s
+			11:00	-	VLAT	2011 Sep 13 0:00s # Decree 725?
+			10:00	-	YAKT
+
 #
 # Sakhalinskaya oblast'.
 # The Zone name should be Yuzhno-Sakhalinsk, but that's too long.
@@ -2319,14 +2424,26 @@
 
 # From Oscar van Vlijmen (2009-11-29):
 # The Sakha districts are: Abyjskij, Allaikhovskij, Verkhhhnekolymskij, Momskij,
-# Nizhnekolymskij, Ojmyakonskij, Srednekolymskij.
+# Nizhnekolymskij, ... Srednekolymskij.
 Zone Asia/Magadan	10:03:12 -	LMT	1924 May  2
 			10:00	-	MAGT	1930 Jun 21 # Magadan Time
 			11:00	Russia	MAG%sT	1991 Mar 31 2:00s
 			10:00	Russia	MAG%sT	1992 Jan 19 2:00s
 			11:00	Russia	MAG%sT	2011 Mar 27 2:00s
 			12:00	-	MAGT
-#
+
+# From Arthur David Olson (2012-05-09):
+# Ojmyakonskij and the Kuril Islands switched from
+# Magadan time to Vladivostok time in 2011.
+Zone Asia/Ust-Nera	 9:32:54 -	LMT	1919 Dec 15
+			 8:00	-	YAKT	1930 Jun 21 # Yakutsk Time
+			 9:00	Russia	YAKT	1981 Apr  1
+			11:00	Russia	MAG%sT	1991 Mar 31 2:00s
+			10:00	Russia	MAG%sT	1992 Jan 19 2:00s
+			11:00	Russia	MAG%sT	2011 Mar 27 2:00s
+			12:00	-	MAGT	2011 Sep 13 0:00s # Decree 725?
+			11:00	-	VLAT
+
 # From Oscar van Vlijmen (2001-08-25): [This region consists of]
 # Kamchatskaya oblast', Koryakskij avtonomnyj okrug.
 #
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/northamerica b/jdk/test/sun/util/calendar/zi/tzdata/northamerica
index c303326..858bf81 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/northamerica
+++ b/jdk/test/sun/util/calendar/zi/tzdata/northamerica
@@ -29,7 +29,7 @@
 
 # This data is by no means authoritative; if you think you know better,
 # go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
+# tz@iana.org for general use in the future).
 
 # From Paul Eggert (1999-03-22):
 # A reliable and entertaining source about time zones is
@@ -1042,6 +1042,9 @@
 #	William Willett, The Waste of Daylight, 19th edition
 #	</a> (1914-03)
 #
+#	Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+#	<http://www.jstor.org/stable/1774359>.
+#
 # See the `europe' file for Greenland.
 
 # Canada
@@ -2577,6 +2580,8 @@
 
 # Bahamas
 #
+# For 1899 Milne gives -5:09:29.5; round that.
+#
 # From Sue Williams (2006-12-07):
 # The Bahamas announced about a month ago that they plan to change their DST
 # rules to sync with the U.S. starting in 2007....
@@ -2586,11 +2591,14 @@
 Rule	Bahamas	1964	1975	-	Oct	lastSun	2:00	0	S
 Rule	Bahamas	1964	1975	-	Apr	lastSun	2:00	1:00	D
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Nassau	-5:09:24 -	LMT	1912 Mar 2
+Zone	America/Nassau	-5:09:30 -	LMT	1912 Mar 2
 			-5:00	Bahamas	E%sT	1976
 			-5:00	US	E%sT
 
 # Barbados
+
+# For 1899 Milne gives -3:58:29.2; round that.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Barb	1977	only	-	Jun	12	2:00	1:00	D
 Rule	Barb	1977	1978	-	Oct	Sun>=1	2:00	0	S
@@ -2598,8 +2606,8 @@
 Rule	Barb	1979	only	-	Sep	30	2:00	0	S
 Rule	Barb	1980	only	-	Sep	25	2:00	0	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Barbados	-3:58:28 -	LMT	1924		# Bridgetown
-			-3:58:28 -	BMT	1932	  # Bridgetown Mean Time
+Zone America/Barbados	-3:58:29 -	LMT	1924		# Bridgetown
+			-3:58:29 -	BMT	1932	  # Bridgetown Mean Time
 			-4:00	Barb	A%sT
 
 # Belize
@@ -2617,6 +2625,9 @@
 
 # Bermuda
 
+# For 1899 Milne gives -4:19:18.3 as the meridian of the clock tower,
+# Bermuda dockyard, Ireland I; round that.
+
 # From Dan Jones, reporting in The Royal Gazette (2006-06-26):
 
 # Next year, however, clocks in the US will go forward on the second Sunday
@@ -2626,7 +2637,7 @@
 # http://www.theroyalgazette.com/apps/pbcs.dll/article?AID=/20060529/NEWS/105290135
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Atlantic/Bermuda	-4:19:04 -	LMT	1930 Jan  1 2:00    # Hamilton
+Zone Atlantic/Bermuda	-4:19:18 -	LMT	1930 Jan  1 2:00    # Hamilton
 			-4:00	-	AST	1974 Apr 28 2:00
 			-4:00	Bahamas	A%sT	1976
 			-4:00	US	A%sT
@@ -2638,6 +2649,9 @@
 			-5:00	-	EST
 
 # Costa Rica
+
+# Milne gives -5:36:13.3 as San Jose mean time; round to nearest.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	CR	1979	1980	-	Feb	lastSun	0:00	1:00	D
 Rule	CR	1979	1980	-	Jun	Sun>=1	0:00	0	S
@@ -2648,14 +2662,19 @@
 Rule	CR	1992	only	-	Mar	15	0:00	0	S
 # There are too many San Joses elsewhere, so we'll use `Costa Rica'.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Costa_Rica	-5:36:20 -	LMT	1890		# San Jose
-			-5:36:20 -	SJMT	1921 Jan 15 # San Jose Mean Time
+Zone America/Costa_Rica	-5:36:13 -	LMT	1890		# San Jose
+			-5:36:13 -	SJMT	1921 Jan 15 # San Jose Mean Time
 			-6:00	CR	C%sT
 # Coco
 # no information; probably like America/Costa_Rica
 
 # Cuba
 
+# From Paul Eggert (2013-02-21):
+# Milne gives -5:28:50.45 for the observatory at Havana, -5:29:23.57
+# for the port, and -5:30 for meteorological observations.
+# For now, stick with Shanks & Pottenger.
+
 # From Arthur David Olson (1999-03-29):
 # The 1999-03-28 exhibition baseball game held in Havana, Cuba, between
 # the Cuban National Team and the Baltimore Orioles was carried live on
@@ -3004,24 +3023,21 @@
 # apparently using the same start and end date as USA/Canada.
 # So this means they have already changed their time.
 #
-# (Sources in French):
-# <a href="http://www.alterpresse.org/spip.php?article12510">
 # http://www.alterpresse.org/spip.php?article12510
-# </a>
-# <a href="http://radiovision2000haiti.net/home/?p=13253">
 # http://radiovision2000haiti.net/home/?p=13253
-# </a>
 #
-# Our coverage:
-# <a href="http://www.timeanddate.com/news/time/haiti-dst-2012.html">
-# http://www.timeanddate.com/news/time/haiti-dst-2012.html
-# </a>
-
 # From Arthur David Olson (2012-03-11):
 # The alterpresse.org source seems to show a US-style leap from 2:00 a.m. to
 # 3:00 a.m. rather than the traditional Haitian jump at midnight.
-# Assume a US-style fall back as well XXX.
-# Do not yet assume that the change carries forward past 2012 XXX.
+# Assume a US-style fall back as well.
+
+# From Steffen Thorsen (2013-03-10):
+# It appears that Haiti is observing DST this year as well, same rules
+# as US/Canada.  They did it last year as well, and it looks like they
+# are going to observe DST every year now...
+#
+# http://radiovision2000haiti.net/public/haiti-avis-changement-dheure-dimanche/
+# http://www.canalplushaiti.net/?p=6714
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Haiti	1983	only	-	May	8	0:00	1:00	D
@@ -3033,8 +3049,8 @@
 Rule	Haiti	1988	1997	-	Oct	lastSun	1:00s	0	S
 Rule	Haiti	2005	2006	-	Apr	Sun>=1	0:00	1:00	D
 Rule	Haiti	2005	2006	-	Oct	lastSun	0:00	0	S
-Rule	Haiti	2012	only	-	Mar	Sun>=8	2:00	1:00	D
-Rule	Haiti	2012	only	-	Nov	Sun>=1	2:00	0	S
+Rule	Haiti	2012	max	-	Mar	Sun>=8	2:00	1:00	D
+Rule	Haiti	2012	max	-	Nov	Sun>=1	2:00	0	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Port-au-Prince -4:49:20 -	LMT	1890
 			-4:49	-	PPMT	1917 Jan 24 12:00 # P-a-P MT
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/southamerica b/jdk/test/sun/util/calendar/zi/tzdata/southamerica
index 0d6797e..d1865d3 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/southamerica
+++ b/jdk/test/sun/util/calendar/zi/tzdata/southamerica
@@ -27,13 +27,17 @@
 
 # This data is by no means authoritative; if you think you know better,
 # go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
+# tz@iana.org for general use in the future).
 
 # From Paul Eggert (2006-03-22):
 # A good source for time zone historical data outside the U.S. is
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
 # San Diego: ACS Publications, Inc. (2003).
 #
+# For data circa 1899, a common source is:
+# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+# <http://www.jstor.org/stable/1774359>.
+#
 # Gwillim Law writes that a good source
 # for recent time zone data is the International Air Transport
 # Association's Standard Schedules Information Manual (IATA SSIM),
@@ -404,21 +408,11 @@
 # <a/>
 # is the official page for the Province Government).
 #
-# There's also a note in only one of the major national papers (La Nación) at
-# <a href="http://www.lanacion.com.ar/nota.asp?nota_id=1107912">
+# There's also a note in only one of the major national papers ...
 # http://www.lanacion.com.ar/nota.asp?nota_id=1107912
-# </a>
 #
-# The press release says:
-#  (...) anunció que el próximo domingo a las 00:00 los puntanos deberán
-# atrasar una hora sus relojes.
-#
-# A partir de entonces, San Luis establecerá el huso horario propio de
-# la Provincia. De esta manera, durante el periodo del calendario anual
-# 2009, el cambio horario quedará comprendido entre las 00:00 del tercer
-# domingo de marzo y las 24:00 del segundo sábado de octubre.
-# Quick&dirty translation
-# (...) announced that next Sunday, at 00:00, Puntanos (the San Luis
+# The press release says [quick and dirty translation]:
+# ... announced that next Sunday, at 00:00, Puntanos (the San Luis
 # inhabitants) will have to turn back one hour their clocks
 #
 # Since then, San Luis will establish its own Province timezone. Thus,
@@ -480,6 +474,9 @@
 # rules...San Luis is still using "Western ARgentina Time" and it got
 # stuck on Summer daylight savings time even though the summer is over.
 
+# From Paul Eggert (2013-02-21):
+# Milne says Cordoba time was -4:16:48.2.  Round to the nearest second.
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 #
 # Buenos Aires (BA), Capital Federal (CF),
@@ -835,9 +832,9 @@
 
 # From Guilherme Bernardes Rodrigues (2011-10-07):
 # There is news in the media, however there is still no decree about it.
-# I just send a e-mail to Zulmira Brandão at
+# I just send a e-mail to Zulmira Brandao at
 # <a href="http://pcdsh01.on.br/">http://pcdsh01.on.br/</a> the
-# oficial agency about time in Brazil, and she confirmed that the old rule is
+# official agency about time in Brazil, and she confirmed that the old rule is
 # still in force.
 
 # From Guilherme Bernardes Rodrigues (2011-10-14)
@@ -1266,9 +1263,13 @@
 # b. Saturday, September 1, 2012, clocks should go forward 60 minutes; that is,
 # at 23:59:59, instead of passing to 0:00, the time should be adjusted to be
 # 01:00 on September 2.
-#
-# Note that...this is yet another "temporary" change that will be reevaluated
-# AGAIN in 2013.
+
+# From Steffen Thorsen (2013-02-15):
+# According to several news sources, Chile has extended DST this year,
+# they will end DST later and start DST earlier than planned.  They
+# hope to save energy.  The new end date is 2013-04-28 00:00 and new
+# start date is 2013-09-08 00:00....
+# http://www.gob.cl/informa/2013/02/15/gobierno-anuncia-fechas-de-cambio-de-hora-para-el-ano-2013.htm
 
 # NOTE: ChileAQ rules for Antarctic bases are stored separately in the
 # 'antarctica' file.
@@ -1311,10 +1312,8 @@
 Rule	Chile	2010	only	-	Apr	Sun>=1	3:00u	0	-
 Rule	Chile	2011	only	-	May	Sun>=2	3:00u	0	-
 Rule	Chile	2011	only	-	Aug	Sun>=16	4:00u	1:00	S
-Rule	Chile	2012	only	-	Apr	Sun>=23	3:00u	0	-
-Rule	Chile	2012	only	-	Sep	Sun>=2	4:00u	1:00	S
-Rule	Chile	2013	max	-	Mar	Sun>=9	3:00u	0	-
-Rule	Chile	2013	max	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	Chile	2012	max	-	Apr	Sun>=23	3:00u	0	-
+Rule	Chile	2012	max	-	Sep	Sun>=2	4:00u	1:00	S
 # IATA SSIM anomalies: (1992-02) says 1992-03-14;
 # (1996-09) says 1998-03-08.  Ignore these.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -1336,17 +1335,23 @@
 # San Felix, and Antarctic bases, are like America/Santiago.
 
 # Colombia
+
+# Milne gives 4:56:16.4 for Bogota time in 1899; round to nearest.  He writes,
+# "A variation of fifteen minutes in the public clocks of Bogota is not rare."
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	CO	1992	only	-	May	 3	0:00	1:00	S
 Rule	CO	1993	only	-	Apr	 4	0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Bogota	-4:56:20 -	LMT	1884 Mar 13
-			-4:56:20 -	BMT	1914 Nov 23 # Bogota Mean Time
+Zone	America/Bogota	-4:56:16 -	LMT	1884 Mar 13
+			-4:56:16 -	BMT	1914 Nov 23 # Bogota Mean Time
 			-5:00	CO	CO%sT	# Colombia Time
 # Malpelo, Providencia, San Andres
 # no information; probably like America/Bogota
 
 # Curacao
+
+# Milne gives 4:35:46.9 for Curacao mean time; round to nearest.
 #
 # From Paul Eggert (2006-03-22):
 # Shanks & Pottenger say that The Bottom and Philipsburg have been at
@@ -1363,7 +1368,7 @@
 # though, as far as we know.
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	America/Curacao	-4:35:44 -	LMT	1912 Feb 12	# Willemstad
+Zone	America/Curacao	-4:35:47 -	LMT	1912 Feb 12	# Willemstad
 			-4:30	-	ANT	1965 # Netherlands Antilles Time
 			-4:00	-	AST
 
@@ -1377,6 +1382,8 @@
 
 # Ecuador
 #
+# Milne says the Sentral and South American Telegraph Company used -5:24:15.
+#
 # From Paul Eggert (2007-03-04):
 # Apparently Ecuador had a failed experiment with DST in 1992.
 # <http://midena.gov.ec/content/view/1261/208/> (2007-02-27) and
@@ -1582,7 +1589,16 @@
 # forward 60 minutes, in all the territory of the Paraguayan Republic.
 # ...
 Rule	Para	2010	max	-	Oct	Sun>=1	0:00	1:00	S
-Rule	Para	2010	max	-	Apr	Sun>=8	0:00	0	-
+Rule	Para	2010	2012	-	Apr	Sun>=8	0:00	0	-
+#
+# From Steffen Thorsen (2013-03-07):
+# Paraguay will end DST on 2013-03-24 00:00....
+# http://www.ande.gov.py/interna.php?id=1075
+#
+# From Carlos Raul Perasso (2013-03-15):
+# The change in Paraguay is now final.  Decree number 10780
+# http://www.presidencia.gov.py/uploads/pdf/presidencia-3b86ff4b691c79d4f5927ca964922ec74772ce857c02ca054a52a37b49afc7fb.pdf
+Rule	Para	2013	max	-	Mar	Sun>=22	0:00	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Asuncion	-3:50:40 -	LMT	1890
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/zone.tab b/jdk/test/sun/util/calendar/zi/tzdata/zone.tab
index ef380cd..cbcdc07 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/zone.tab
+++ b/jdk/test/sun/util/calendar/zi/tzdata/zone.tab
@@ -65,7 +65,6 @@
 AQ	-7824+10654	Antarctica/Vostok	Vostok Station, Lake Vostok
 AQ	-6640+14001	Antarctica/DumontDUrville	Dumont-d'Urville Station, Terre Adelie
 AQ	-690022+0393524	Antarctica/Syowa	Syowa Station, E Ongul I
-AQ	-5430+15857	Antarctica/Macquarie	Macquarie Island Station, Macquarie Island
 AR	-3436-05827	America/Argentina/Buenos_Aires	Buenos Aires (BA, CF)
 AR	-3124-06411	America/Argentina/Cordoba	most locations (CB, CC, CN, ER, FM, MN, SE, SF)
 AR	-2447-06525	America/Argentina/Salta	(SA, LP, NQ, RN)
@@ -81,6 +80,7 @@
 AS	-1416-17042	Pacific/Pago_Pago
 AT	+4813+01620	Europe/Vienna
 AU	-3133+15905	Australia/Lord_Howe	Lord Howe Island
+AU	-5430+15857	Antarctica/Macquarie	Macquarie Island
 AU	-4253+14719	Australia/Hobart	Tasmania - most locations
 AU	-3956+14352	Australia/Currie	Tasmania - King Island
 AU	-3749+14458	Australia/Melbourne	Victoria
@@ -182,7 +182,8 @@
 CX	-1025+10543	Indian/Christmas
 CY	+3510+03322	Asia/Nicosia
 CZ	+5005+01426	Europe/Prague
-DE	+5230+01322	Europe/Berlin
+DE	+5230+01322	Europe/Berlin	most locations
+DE	+4742+00841	Europe/Busingen	Busingen
 DJ	+1136+04309	Africa/Djibouti
 DK	+5540+01235	Europe/Copenhagen
 DM	+1518-06124	America/Dominica
@@ -364,8 +365,10 @@
 RU	+5601+09250	Asia/Krasnoyarsk	Moscow+04 - Yenisei River
 RU	+5216+10420	Asia/Irkutsk	Moscow+05 - Lake Baikal
 RU	+6200+12940	Asia/Yakutsk	Moscow+06 - Lena River
+RU	+623923+1353314	Asia/Khandyga	Moscow+06 - Tomponsky, Ust-Maysky
 RU	+4310+13156	Asia/Vladivostok	Moscow+07 - Amur River
 RU	+4658+14242	Asia/Sakhalin	Moscow+07 - Sakhalin Island
+RU	+643337+1431336	Asia/Ust-Nera	Moscow+07 - Oymyakonsky
 RU	+5934+15048	Asia/Magadan	Moscow+08 - Magadan
 RU	+5301+15839	Asia/Kamchatka	Moscow+08 - Kamchatka
 RU	+6445+17729	Asia/Anadyr	Moscow+08 - Bering Sea
diff --git a/jdk/test/tools/pack200/AttributeTests.java b/jdk/test/tools/pack200/AttributeTests.java
index c128918..bcf4c7c 100644
--- a/jdk/test/tools/pack200/AttributeTests.java
+++ b/jdk/test/tools/pack200/AttributeTests.java
@@ -21,12 +21,9 @@
  * questions.
  */
 import java.io.File;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import static java.nio.file.StandardOpenOption.*;
 /*
  * @test
  * @bug 6746111 8005252 8008262
@@ -58,8 +55,7 @@
         scratch.add("}");
         File cwd = new File(".");
         File javaFile = new File(cwd, javaFileName);
-        Files.write(javaFile.toPath(), scratch, Charset.defaultCharset(),
-                CREATE, TRUNCATE_EXISTING);
+        Utils.createFile(javaFile, scratch);
 
         Utils.compiler(javaFile.getName(), "-parameters");
 
diff --git a/jdk/test/tools/pack200/BandIntegrity.java b/jdk/test/tools/pack200/BandIntegrity.java
new file mode 100644
index 0000000..1145972
--- /dev/null
+++ b/jdk/test/tools/pack200/BandIntegrity.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary test ensures the proper sequencing of bands, dump bands as well.
+ * @compile -XDignore.symbol.file Utils.java BandIntegrity.java
+ * @run main BandIntegrity
+ * @author ksrini
+ */
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/*
+ * This makes use of the optDebugBands to ensure the bands are read in the
+ * same sequence as it was written. The caveat is that this works only with
+ * the java unpacker, therefore it will work only with --repack such that
+ * the java packer and unpacker must be called in the same java instance.
+ */
+public class BandIntegrity {
+        public static void main(String... args)  throws IOException {
+        File testFile = new File("test.jar");
+        Utils.jar("cvf", testFile.getName(),
+                "-C", Utils.TEST_CLS_DIR.getAbsolutePath(),
+                ".");
+        List<String> scratch = new ArrayList<>();
+        // band debugging works only with java unpacker
+        scratch.add("com.sun.java.util.jar.pack.disable.native=true");
+        scratch.add("com.sun.java.util.jar.pack.debug.bands=true");
+        // while at it, might as well exercise this functionality
+        scratch.add("com.sun.java.util.jar.pack.dump.bands=true");
+        scratch.add("pack.unknown.attribute=error");
+        File configFile = new File("pack.conf");
+        Utils.createFile(configFile, scratch);
+        File outFile = new File("out.jar");
+        Utils.repack(testFile, outFile, true,
+                     "-v", "--config-file=" + configFile.getName());
+    }
+}
diff --git a/jdk/test/tools/pack200/InstructionTests.java b/jdk/test/tools/pack200/InstructionTests.java
index 7015ae9..171fe4e 100644
--- a/jdk/test/tools/pack200/InstructionTests.java
+++ b/jdk/test/tools/pack200/InstructionTests.java
@@ -21,11 +21,8 @@
  * questions.
  */
 import java.io.File;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.List;
-import static java.nio.file.StandardOpenOption.*;
 
 /*
  * @test
@@ -59,8 +56,7 @@
         scratch.add("}");
         File cwd = new File(".");
         File javaFile = new File(cwd, javaFileName);
-        Files.write(javaFile.toPath(), scratch, Charset.defaultCharset(),
-                CREATE, TRUNCATE_EXISTING);
+        Utils.createFile(javaFile, scratch);
 
         // -g to compare LVT and LNT entries
         Utils.compiler("-g", javaFile.getName());
@@ -69,8 +65,7 @@
         scratch.clear();
         scratch.add("com.sun.java.util.jar.pack.class.format.error=error");
         scratch.add("pack.unknown.attribute=error");
-        Files.write(propsFile.toPath(), scratch, Charset.defaultCharset(),
-                CREATE, TRUNCATE_EXISTING);
+        Utils.createFile(propsFile, scratch);
         // jar the file up
         File testjarFile = new File(cwd, "test" + Utils.JAR_FILE_EXT);
         Utils.jar("cvf", testjarFile.getName(), ".");
diff --git a/jdk/test/tools/pack200/Utils.java b/jdk/test/tools/pack200/Utils.java
index f3d1d46..df34264 100644
--- a/jdk/test/tools/pack200/Utils.java
+++ b/jdk/test/tools/pack200/Utils.java
@@ -32,6 +32,7 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.PrintStream;
+import java.nio.charset.Charset;
 import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -45,6 +46,7 @@
 import java.util.zip.ZipFile;
 
 import static java.nio.file.StandardCopyOption.*;
+import static java.nio.file.StandardOpenOption.*;
 
 /**
  *
@@ -70,6 +72,7 @@
     static final String JAR_FILE_EXT    = ".jar";
 
     static final File   TEST_SRC_DIR = new File(System.getProperty("test.src"));
+    static final File   TEST_CLS_DIR = new File(System.getProperty("test.classes"));
     static final String VERIFIER_DIR_NAME = "pack200-verifier";
     static final File   VerifierJar = new File(VERIFIER_DIR_NAME + JAR_FILE_EXT);
 
@@ -86,6 +89,10 @@
             return;
         }
         File srcDir = new File(TEST_SRC_DIR, VERIFIER_DIR_NAME);
+        if (!srcDir.exists()) {
+            // if not available try one level above
+            srcDir = new File(TEST_SRC_DIR.getParentFile(), VERIFIER_DIR_NAME);
+        }
         List<File> javaFileList = findFiles(srcDir, createFilter(JAVA_FILE_EXT));
         File tmpFile = File.createTempFile("javac", ".tmp");
         File classesDir = new File("xclasses");
@@ -205,6 +212,10 @@
                 : name;
 
     }
+   static void createFile(File outFile, List<String> content) throws IOException {
+        Files.write(outFile.getAbsoluteFile().toPath(), content,
+                Charset.defaultCharset(), CREATE_NEW, TRUNCATE_EXISTING);
+    }
 
     /*
      * Suppose a path is provided which consists of a full path
diff --git a/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java
index db7d046..02b0a7e 100644
--- a/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java
+++ b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java
@@ -69,6 +69,9 @@
 import com.sun.tools.classfile.StackMapTable_attribute.*;
 import com.sun.tools.classfile.StackMap_attribute;
 import com.sun.tools.classfile.Synthetic_attribute;
+import com.sun.tools.classfile.TypeAnnotation;
+import com.sun.tools.classfile.TypeAnnotation.Position;
+import static com.sun.tools.classfile.TypeAnnotation.TargetType.THROWS;
 import java.util.*;
 import java.io.*;
 import java.util.jar.JarEntry;
@@ -851,6 +854,7 @@
     }
 }
 
+
 class AttributeVisitor implements Attribute.Visitor<Element, Element> {
     final ClassFile cf;
     final ClassReader x;
@@ -1088,23 +1092,26 @@
         }
         return null; // already added to parent
     }
+    private void parseAnnotation(Annotation anno, Element p) {
+        Element ea = new Element("Annotation");
+        ea.setAttr("name", "" + x.getCpString(anno.type_index));
+        for (Annotation.element_value_pair evp : anno.element_value_pairs) {
+            Element evpe = new Element("Element");
+            evpe.setAttr("tag", "" + evp.value.tag);
+            evpe.setAttr("value", x.getCpString(evp.element_name_index));
+            Element child = aev.visit(evp.value, evpe);
+            if (child != null) {
+                evpe.add(child);
+            }
+            ea.add(evpe);
+        }
+        ea.trimToSize();
+        p.add(ea);
+    }
 
     private void parseAnnotations(Annotation[] ra, Element p) {
-         for (Annotation anno : ra) {
-            Element ea = new Element("Member");
-            ea.setAttr("name", "" + x.getCpString(anno.type_index));
-            for (Annotation.element_value_pair evp : anno.element_value_pairs) {
-                Element evpe = new Element("Element");
-                evpe.setAttr("tag", "" + evp.value.tag);
-                evpe.setAttr("value", x.getCpString(evp.element_name_index));
-                Element child = aev.visit(evp.value, evpe);
-                if (child != null) {
-                    evpe.add(child);
-                }
-                ea.add(evpe);
-            }
-            ea.trimToSize();
-            p.add(ea);
+        for (Annotation anno : ra) {
+            parseAnnotation(anno, p);
         }
     }
 
@@ -1150,6 +1157,145 @@
         return null;
     }
 
+    private void parsePosition(Position ap, Element p) {
+        Element te = new Element();
+        switch (ap.type) {
+            case CLASS_TYPE_PARAMETER: // 0x00
+                te.setName("CLASS_TYPE_PARAMETER");
+                te.setAttr("idx", "" + ap.parameter_index);
+                break;
+            case METHOD_TYPE_PARAMETER: // 0x01
+                te.setName("METHOD_TYPE_PARAMETER");
+                te.setAttr("idx", "" + ap.parameter_index);
+                break;
+            case CLASS_EXTENDS: // 0x10
+                te.setName("CLASS_EXTENDS");
+                te.setAttr("idx", "" + ap.type_index);
+                break;
+            case CLASS_TYPE_PARAMETER_BOUND: // 0x11
+                te.setName("CLASS_TYPE_PARAMETER_BOUND");
+                te.setAttr("idx1", "" + ap.parameter_index);
+                te.setAttr("idx2", "" + ap.bound_index);
+                break;
+            case METHOD_TYPE_PARAMETER_BOUND: // 0x12
+                te.setName("METHOD_TYPE_PARAMETER_BOUND");
+                te.setAttr("idx1", "" + ap.parameter_index);
+                te.setAttr("idx2", "" + ap.bound_index);
+                break;
+            case FIELD: // 0x13
+                te.setName("FIELD");
+                break;
+            case METHOD_RETURN: // 0x14
+                te.setName("METHOD_RETURN");
+                break;
+            case METHOD_RECEIVER: // 0x15
+                te.setName("METHOD_RECEIVER");
+                break;
+            case METHOD_FORMAL_PARAMETER: // 0x16
+                te.setName("METHOD_FORMAL_PARAMETER");
+                te.setAttr("idx", "" + ap.parameter_index);
+                break;
+            case THROWS: // 0x17
+                te.setName("THROWS");
+                te.setAttr("idx", "" + ap.type_index);
+                break;
+            case LOCAL_VARIABLE: // 0x40
+                te.setName("LOCAL_VARIABLE");
+                for (int i = 0; i < ap.lvarIndex.length; i++) {
+                    te.setAttr("lvar_idx_" + i, "" + ap.lvarIndex[i]);
+                    te.setAttr("lvar_len_" + i, "" + ap.lvarLength[i]);
+                    te.setAttr("lvar_off_" + i, "" + ap.lvarOffset[i]);
+                }
+                break;
+            case RESOURCE_VARIABLE: // 0x41
+                te.setName("RESOURCE_VARIABLE");
+                for (int i = 0; i < ap.lvarIndex.length ; i++) {
+                    te.setAttr("lvar_idx_" + i, "" + ap.lvarIndex[i]);
+                    te.setAttr("lvar_len_" + i, "" + ap.lvarLength[i]);
+                    te.setAttr("lvar_off_" + i, "" + ap.lvarOffset[i]);
+                }
+                break;
+            case EXCEPTION_PARAMETER: // 0x42
+                te.setName("EXCEPTION_PARAMETER");
+                te.setAttr("idx", "" + ap.exception_index);
+                break;
+            case INSTANCEOF: // 0x43
+                te.setName("INSTANCE_OF");
+                te.setAttr("off", "" + ap.offset);
+                break;
+            case NEW: // 0x44
+                te.setName("NEW");
+                te.setAttr("off", "" + ap.offset);
+                break;
+            case CONSTRUCTOR_REFERENCE: // 0x45
+                te.setName("CONSTRUCTOR_REFERENCE_RECEIVER");
+                te.setAttr("off", "" + ap.offset);
+                break;
+            case METHOD_REFERENCE: // 0x46
+                te.setName("METHOD_REFERENCE_RECEIVER");
+                te.setAttr("off", "" + ap.offset);
+                break;
+            case CAST: // 0x47
+                te.setName("CAST");
+                te.setAttr("off", "" + ap.offset);
+                te.setAttr("idx", "" + ap.type_index);
+                break;
+            case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: // 0x48
+                te.setName("CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT");
+                te.setAttr("off", "" + ap.offset);
+                te.setAttr("idx", "" + ap.type_index);
+                break;
+            case METHOD_INVOCATION_TYPE_ARGUMENT: // 0x49
+                te.setName("METHOD_INVOCATION_TYPE_ARGUMENT");
+                te.setAttr("off", "" + ap.offset);
+                te.setAttr("idx", "" + ap.type_index);
+                break;
+            case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT: // 0x4A
+                te.setName("CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT");
+                te.setAttr("off", "" + ap.offset);
+                te.setAttr("idx", "" + ap.type_index);
+                break;
+            case METHOD_REFERENCE_TYPE_ARGUMENT: // 0x4B
+                te.setName("METHOD_REFERENCE_TYPE_ARGUMENT");
+                te.setAttr("off", "" + ap.offset);
+                te.setAttr("idx", "" + ap.type_index);
+                break;
+            default:
+                throw new RuntimeException("not implemented");
+        }
+        te.trimToSize();
+        p.add(te);
+    }
+    private void parseTypeAnnotations(TypeAnnotation pa, Element p) {
+        Element pta = new Element("RuntimeVisibleTypeAnnotation");
+        p.add(pta);
+        Position pos = pa.position;
+        parsePosition(pos, pta);
+        parseAnnotation(pa.annotation, pta);
+    }
+
+    @Override
+    public Element visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute rvta, Element p) {
+        Element e = new Element(x.getCpString(rvta.attribute_name_index));
+        for (TypeAnnotation pa : rvta.annotations) {
+            parseTypeAnnotations(pa, e);
+        }
+        e.sort();
+        p.add(e);
+        return null;
+    }
+
+    @Override
+    public Element visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute rita, Element p) {
+        Element e = new Element(x.getCpString(rita.attribute_name_index));
+        for (TypeAnnotation pa : rita.annotations) {
+            parseTypeAnnotations(pa, e);
+        }
+        e.sort();
+        p.add(e);
+        return null;
+    }
+
     @Override
     public Element visitSignature(Signature_attribute s, Element p) {
         String aname = x.getCpString(s.attribute_name_index);
@@ -1216,21 +1362,6 @@
         p.add(e);
         return null;
     }
-
-    /*
-     * TODO
-     * add these two for now to keep the compiler happy, we will implement
-     * these along with the JSR-308 changes.
-     */
-    @Override
-    public Element visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute rvta, Element p) {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    @Override
-    public Element visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute rita, Element p) {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
 }
 
 class StackMapVisitor implements StackMapTable_attribute.stack_map_frame.Visitor<Element, Void> {
diff --git a/jdk/test/tools/pack200/typeannos/Lambda.java b/jdk/test/tools/pack200/typeannos/Lambda.java
new file mode 100644
index 0000000..ed2553b
--- /dev/null
+++ b/jdk/test/tools/pack200/typeannos/Lambda.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @Xtest
+ * @bug 8008077
+ * @summary new type annotation location: lambda expressions
+ * @compile Lambda.java
+ * @author Werner Dietl
+ */
+
+import java.lang.annotation.*;
+
+public class Lambda {
+
+    interface LambdaInt {
+        <S, T> void generic(S p1, T p2);
+    }
+
+    static class LambdaImpl implements LambdaInt {
+        <S, T> LambdaImpl(S p1, T p2) {}
+        public <S, T> void generic(S p1, T p2) {}
+    }
+
+    LambdaInt getMethodRefTA(LambdaImpl r) {
+        return r::<@TA Object, @TB Object>generic;
+    }
+
+    LambdaInt getConstructorRefTA() {
+        return LambdaImpl::<@TA Object, @TB Object>new;
+    }
+
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TA { }
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TB { }
diff --git a/jdk/test/tools/pack200/typeannos/Readme.txt b/jdk/test/tools/pack200/typeannos/Readme.txt
new file mode 100644
index 0000000..c3c2fcf
--- /dev/null
+++ b/jdk/test/tools/pack200/typeannos/Readme.txt
@@ -0,0 +1,11 @@
+This directory contains tests which exercises all possible TypeAnnotations
+structure. These tests are borrowed from 
+langtools/test/tools.javac/annotations/typeAnnotations. 
+
+The reason it is copied over is that we need to test pack200 and these 
+annotation may not be present in any of the JDK/JRE jars, yet we need to test
+all these cases.
+
+
+Therefore it would be a good practice to sync these tests with the  original
+if there are any changes.
diff --git a/jdk/test/tools/pack200/typeannos/TargetTypes.java b/jdk/test/tools/pack200/typeannos/TargetTypes.java
new file mode 100644
index 0000000..0af6db1
--- /dev/null
+++ b/jdk/test/tools/pack200/typeannos/TargetTypes.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.lang.annotation.*;
+import static java.lang.annotation.ElementType.*;
+
+import java.util.*;
+import java.io.*;
+
+/*
+ * @Xtest
+ * @summary compiler accepts all values
+ * @author Mahmood Ali
+ * @author Yuri Gaevsky
+ * @compile TargetTypes.java
+ */
+
+@Target({TYPE_USE, TYPE_PARAMETER, TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@interface A {}
+
+/** wildcard bound */
+class T0x1C {
+    void m0x1C(List<? extends @A String> lst) {}
+}
+
+/** wildcard bound generic/array */
+class T0x1D<T> {
+    void m0x1D(List<? extends @A List<int[]>> lst) {}
+}
+
+/** typecast */
+class T0x00 {
+    void m0x00(Long l1) {
+        Object l2 = (@A Long) l1;
+    }
+}
+
+/** typecast generic/array */
+class T0x01<T> {
+    void m0x01(List<T> list) {
+        List<T> l = (List<@A T>) list;
+    }
+}
+
+/** instanceof */
+class T0x02 {
+    boolean m0x02(String s) {
+        return (s instanceof @A String);
+    }
+}
+
+/** object creation (new) */
+class T0x04 {
+    void m0x04() {
+        new @A ArrayList<String>();
+    }
+}
+
+/** local variable */
+class T0x08 {
+    void m0x08() {
+      @A String s = null;
+    }
+}
+
+/** method parameter generic/array */
+class T0x0D {
+    void m0x0D(HashMap<@A Object, List<@A List<@A Class>>> s1) {}
+}
+
+/** method receiver */
+class T0x06 {
+    void m0x06(@A T0x06 this) {}
+}
+
+/** method return type generic/array */
+class T0x0B {
+    Class<@A Object> m0x0B() { return null; }
+}
+
+/** field generic/array */
+class T0x0F {
+    HashMap<@A Object, @A Object> c1;
+}
+
+/** method type parameter */
+class T0x20<T, U> {
+    <@A T, @A U> void m0x20() {}
+}
+
+/** class type parameter */
+class T0x22<@A T, @A U> {
+}
+
+/** class type parameter bound */
+class T0x10<T extends @A Object> {
+}
+
+/** method type parameter bound */
+class T0x12<T> {
+    <T extends @A Object> void m0x12() {}
+}
+
+/** class type parameter bound generic/array */
+class T0x11<T extends List<@A T>> {
+}
+
+
+/** method type parameter bound generic/array */
+class T0x13 {
+    static <T extends Comparable<@A T>> T m0x13() {
+        return null;
+    }
+}
+
+/** class extends/implements generic/array */
+class T0x15<T> extends ArrayList<@A T> {
+}
+
+/** type test (instanceof) generic/array */
+class T0x03<T> {
+    void m0x03(T typeObj, Object obj) {
+        boolean ok = obj instanceof String @A [];
+    }
+}
+
+/** object creation (new) generic/array */
+class T0x05<T> {
+    void m0x05() {
+        new ArrayList<@A T>();
+    }
+}
+
+/** local variable generic/array */
+class T0x09<T> {
+    void g() {
+        List<@A String> l = null;
+    }
+
+    void a() {
+        String @A [] as = null;
+    }
+}
+
+/** type argument in constructor call generic/array */
+class T0x19 {
+    <T> T0x19() {}
+
+    void g() {
+       new <List<@A String>> T0x19();
+    }
+}
+
+/** type argument in method call generic/array */
+class T0x1B<T> {
+    void m0x1B() {
+        Collections.<T @A []>emptyList();
+    }
+}
+
+/** type argument in constructor call */
+class T0x18<T> {
+    <T> T0x18() {}
+
+    void m() {
+        new <@A Integer> T0x18();
+    }
+}
+
+/** type argument in method call */
+class T0x1A<T,U> {
+    public static <T, U> T m() { return null; }
+    static void m0x1A() {
+        T0x1A.<@A Integer, @A Short>m();
+    }
+}
+
+/** class extends/implements */
+class T0x14 extends @A Object implements @A Serializable, @A Cloneable {
+}
+
+/** exception type in throws */
+class T0x16 {
+    void m0x16() throws @A Exception {}
+}
+
+/** resource variables **/
+class ResourceVariables {
+    void m() throws Exception {
+        try (@A InputStream is = new @A FileInputStream("x")){}
+    }
+}
+
+/** exception parameters **/
+class ExceptionParameters {
+    void multipleExceptions() {
+        try {
+            new Object();
+        } catch (@A Exception e) {}
+        try {
+            new Object();
+        } catch (@A Exception e) {}
+        try {
+            new Object();
+        } catch (@A Exception e) {}
+    }
+}
diff --git a/jdk/test/tools/pack200/typeannos/TestTypeAnnotations.java b/jdk/test/tools/pack200/typeannos/TestTypeAnnotations.java
new file mode 100644
index 0000000..598185a
--- /dev/null
+++ b/jdk/test/tools/pack200/typeannos/TestTypeAnnotations.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8001163
+ * @summary tests simple TypeAnnotations in classfiles
+ * @compile -XDignore.symbol.file ../Utils.java
+ *          TestTypeAnnotations.java TargetTypes.java
+ *          TypeUseTarget.java Lambda.java
+ * @run main TestTypeAnnotations
+ * @author ksrini
+ */
+import java.io.File;
+import java.io.IOException;
+
+public class TestTypeAnnotations {
+    public static void main(String... args)  throws IOException {
+        File testFile = new File("ta.jar");
+        Utils.jar("cvf", testFile.getName(),
+                "-C", Utils.TEST_CLS_DIR.getAbsolutePath(),
+                ".");
+        Utils.testWithRepack(testFile, "--unknown-attribute=error");
+    }
+}
diff --git a/jdk/test/tools/pack200/typeannos/TypeUseTarget.java b/jdk/test/tools/pack200/typeannos/TypeUseTarget.java
new file mode 100644
index 0000000..fcad51c
--- /dev/null
+++ b/jdk/test/tools/pack200/typeannos/TypeUseTarget.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @Xtest
+ * @bug 6843077 8006775
+ * @summary check that type annotations may appear on all type declarations
+ * @author Mahmood Ali
+ * @compile TypeUseTarget.java
+ */
+
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+@B
+class TypeUseTarget<K extends @B Object> {
+  @B String @B [] field;
+
+  @B String test(@B TypeUseTarget<K> this, @B String param, @B String @B ... vararg) {
+    @B Object o = new @B String @B [3];
+    TypeUseTarget<@B String> target;
+    return (@B String) null;
+  }
+
+  <K> @B String genericMethod(K k) { return null; }
+  @Decl <K> @B String genericMethod1(K k) { return null; }
+  @B @Decl <K> String genericMethod2(K k) { return null; }
+  @Decl @B <K> String genericMethod3(K k) { return null; }
+  <K> @Decl String genericMethod4(K k) { return null; }
+  <K> @B @Decl String genericMethod5(K k) { return null; }
+}
+
+@B
+interface MyInterface { }
+
+@B
+@interface MyAnnotation { }
+
+@Target(ElementType.TYPE_USE)
+@interface B { }
+
+@interface Decl { }
diff --git a/langtools/.hgtags b/langtools/.hgtags
index fae5686..04454fd 100644
--- a/langtools/.hgtags
+++ b/langtools/.hgtags
@@ -211,3 +211,4 @@
 1329f9c38d93c8caf339d7687df8371d06fe9e56 jdk8-b87
 a1e10f3adc47c8602a72e43a41403a642e73e0b1 jdk8-b88
 ec434cfd2752a7742c875c2fe7d556d8b81c0f3a jdk8-b89
+e19283cd30a43fca94d8f7639c73ef66db493b1e jdk8-b90
diff --git a/langtools/make/tools/genstubs/GenStubs.java b/langtools/make/tools/genstubs/GenStubs.java
index 5ff9f35..0ff475c 100644
--- a/langtools/make/tools/genstubs/GenStubs.java
+++ b/langtools/make/tools/genstubs/GenStubs.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -37,6 +37,7 @@
 import com.sun.tools.javac.code.Flags;
 import com.sun.tools.javac.code.TypeTag;
 import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
 import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
 import com.sun.tools.javac.tree.JCTree.JCIdent;
@@ -208,6 +209,21 @@
          * methods: remove method bodies, make methods native
          */
         @Override
+        public void visitClassDef(JCClassDecl tree) {
+            long prevClassMods = currClassMods;
+            currClassMods = tree.mods.flags;
+            try {
+                super.visitClassDef(tree);;
+            } finally {
+                currClassMods = prevClassMods;
+            }
+        }
+        private long currClassMods = 0;
+
+        /**
+         * methods: remove method bodies, make methods native
+         */
+        @Override
         public void visitMethodDef(JCMethodDecl tree) {
             tree.mods = translate(tree.mods);
             tree.restype = translate(tree.restype);
@@ -215,7 +231,11 @@
             tree.params = translateVarDefs(tree.params);
             tree.thrown = translate(tree.thrown);
             if (tree.restype != null && tree.body != null) {
-                tree.mods.flags |= Flags.NATIVE;
+                if ((currClassMods & Flags.INTERFACE) != 0) {
+                    tree.mods.flags &= ~Flags.DEFAULT;
+                } else {
+                    tree.mods.flags |= Flags.NATIVE;
+                }
                 tree.body = null;
             }
             result = tree;
diff --git a/langtools/makefiles/BuildLangtools.gmk b/langtools/makefiles/BuildLangtools.gmk
index cd96a60..2fab4b9 100644
--- a/langtools/makefiles/BuildLangtools.gmk
+++ b/langtools/makefiles/BuildLangtools.gmk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -123,10 +123,10 @@
              genstubs.GenStubs
         # We fetch source from the JDK...
         JDKS=$(JDK_TOPDIR)/src/share/classes
-        # Build the list of classes to generate stubs from. java/util/Objects.java isn't
+        # Build the list of classes to generate stubs from. java/util/function/Predicate.java isn't
         # currently needed, but is used as a demo for now.
 	 STUBSOURCES:=$(shell $(FIND) $(JDKS) -name "*.java" | $(GREP) \
-		    -e "$(JDKS)/java/util/Objects.java")
+		    -e "$(JDKS)/java/util/function/Predicate.java")
         # Rewrite the file names into class names because the GenStubs tool require this.
         STUBCLASSES:=$(subst /,.,$(patsubst $(JDKS)/%.java,%,$(STUBSOURCES)))
 
diff --git a/langtools/src/share/classes/com/sun/source/tree/VariableTree.java b/langtools/src/share/classes/com/sun/source/tree/VariableTree.java
index 7fba7df..86fce99 100644
--- a/langtools/src/share/classes/com/sun/source/tree/VariableTree.java
+++ b/langtools/src/share/classes/com/sun/source/tree/VariableTree.java
@@ -33,6 +33,7 @@
  * For example:
  * <pre>
  *   <em>modifiers</em> <em>type</em> <em>name</em> <em>initializer</em> ;
+ *   <em>modifiers</em> <em>type</em> <em>qualified-name</em>.this
  * </pre>
  *
  * @jls sections 8.3 and 14.4
@@ -45,6 +46,7 @@
 public interface VariableTree extends StatementTree {
     ModifiersTree getModifiers();
     Name getName();
+    ExpressionTree getNameExpression();
     Tree getType();
     ExpressionTree getInitializer();
 }
diff --git a/langtools/src/share/classes/com/sun/source/util/DocTreePath.java b/langtools/src/share/classes/com/sun/source/util/DocTreePath.java
new file mode 100644
index 0000000..0720630
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/source/util/DocTreePath.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2006, 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 com.sun.source.util;
+
+import com.sun.source.doctree.DocCommentTree;
+import com.sun.source.doctree.DocTree;
+import java.util.Iterator;
+
+/**
+ * A path of tree nodes, typically used to represent the sequence of ancestor
+ * nodes of a tree node up to the top level DocCommentTree node.
+ *
+ * @since 1.8
+ */
+@jdk.Supported
+public class DocTreePath implements Iterable<DocTree> {
+    /**
+     * Gets a documentation tree path for a tree node within a compilation unit.
+     * @return null if the node is not found
+     */
+    public static DocTreePath getPath(TreePath treePath, DocCommentTree doc, DocTree target) {
+        return getPath(new DocTreePath(treePath, doc), target);
+    }
+
+    /**
+     * Gets a documentation tree path for a tree node within a subtree identified by a DocTreePath object.
+     * @return null if the node is not found
+     */
+    public static DocTreePath getPath(DocTreePath path, DocTree target) {
+        path.getClass();
+        target.getClass();
+
+        class Result extends Error {
+            static final long serialVersionUID = -5942088234594905625L;
+            DocTreePath path;
+            Result(DocTreePath path) {
+                this.path = path;
+            }
+        }
+
+        class PathFinder extends DocTreePathScanner<DocTreePath,DocTree> {
+            public DocTreePath scan(DocTree tree, DocTree target) {
+                if (tree == target) {
+                    throw new Result(new DocTreePath(getCurrentPath(), target));
+                }
+                return super.scan(tree, target);
+            }
+        }
+
+        if (path.getLeaf() == target) {
+            return path;
+        }
+
+        try {
+            new PathFinder().scan(path, target);
+        } catch (Result result) {
+            return result.path;
+        }
+        return null;
+    }
+
+    /**
+     * Creates a DocTreePath for a root node.
+     *
+     * @param treePath the TreePath from which the root node was created.
+     * @param t the DocCommentTree to create the path for.
+     */
+    public DocTreePath(TreePath treePath, DocCommentTree t) {
+        treePath.getClass();
+        t.getClass();
+
+        this.treePath = treePath;
+        this.docComment = t;
+        this.parent = null;
+        this.leaf = t;
+    }
+
+    /**
+     * Creates a DocTreePath for a child node.
+     */
+    public DocTreePath(DocTreePath p, DocTree t) {
+        if (t.getKind() == DocTree.Kind.DOC_COMMENT) {
+            throw new IllegalArgumentException("Use DocTreePath(TreePath, DocCommentTree) to construct DocTreePath for a DocCommentTree.");
+        } else {
+            treePath = p.treePath;
+            docComment = p.docComment;
+            parent = p;
+        }
+        leaf = t;
+    }
+
+    /**
+     * Get the TreePath associated with this path.
+     * @return TreePath for this DocTreePath
+     */
+    public TreePath getTreePath() {
+        return treePath;
+    }
+
+    /**
+     * Get the DocCommentTree associated with this path.
+     * @return DocCommentTree for this DocTreePath
+     */
+    public DocCommentTree getDocComment() {
+        return docComment;
+    }
+
+    /**
+     * Get the leaf node for this path.
+     * @return DocTree for this DocTreePath
+     */
+    public DocTree getLeaf() {
+        return leaf;
+    }
+
+    /**
+     * Get the path for the enclosing node, or null if there is no enclosing node.
+     * @return DocTreePath of parent
+     */
+    public DocTreePath getParentPath() {
+        return parent;
+    }
+
+    public Iterator<DocTree> iterator() {
+        return new Iterator<DocTree>() {
+            public boolean hasNext() {
+                return next != null;
+            }
+
+            public DocTree next() {
+                DocTree t = next.leaf;
+                next = next.parent;
+                return t;
+            }
+
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+
+            private DocTreePath next = DocTreePath.this;
+        };
+    }
+
+    private final TreePath treePath;
+    private final DocCommentTree docComment;
+    private final DocTree leaf;
+    private final DocTreePath parent;
+}
diff --git a/langtools/src/share/classes/com/sun/source/util/DocTreePathScanner.java b/langtools/src/share/classes/com/sun/source/util/DocTreePathScanner.java
new file mode 100644
index 0000000..326c155
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/source/util/DocTreePathScanner.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2006, 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 com.sun.source.util;
+
+import com.sun.source.doctree.DocTree;
+
+/**
+ * A DocTreeVisitor that visits all the child tree nodes, and provides
+ * support for maintaining a path for the parent nodes.
+ * To visit nodes of a particular type, just override the
+ * corresponding visitorXYZ method.
+ * Inside your method, call super.visitXYZ to visit descendant
+ * nodes.
+ *
+ * @since 1.8
+ */
+@jdk.Supported
+public class DocTreePathScanner<R, P> extends DocTreeScanner<R, P> {
+    /**
+     * Scan a tree from a position identified by a TreePath.
+     */
+    public R scan(DocTreePath path, P p) {
+        this.path = path;
+        try {
+            return path.getLeaf().accept(this, p);
+        } finally {
+            this.path = null;
+        }
+    }
+
+    /**
+     * Scan a single node.
+     * The current path is updated for the duration of the scan.
+     */
+    @Override
+    public R scan(DocTree tree, P p) {
+        if (tree == null)
+            return null;
+
+        DocTreePath prev = path;
+        path = new DocTreePath(path, tree);
+        try {
+            return tree.accept(this, p);
+        } finally {
+            path = prev;
+        }
+    }
+
+    /**
+     * Get the current path for the node, as built up by the currently
+     * active set of scan calls.
+     */
+    public DocTreePath getCurrentPath() {
+        return path;
+    }
+
+    private DocTreePath path;
+}
diff --git a/langtools/src/share/classes/com/sun/source/util/DocTrees.java b/langtools/src/share/classes/com/sun/source/util/DocTrees.java
index 94f68bb..affc5f3 100644
--- a/langtools/src/share/classes/com/sun/source/util/DocTrees.java
+++ b/langtools/src/share/classes/com/sun/source/util/DocTrees.java
@@ -67,10 +67,10 @@
     public abstract DocCommentTree getDocCommentTree(TreePath path);
 
     /**
-     * Gets the language model element referred to by a ReferenceTree that
-     * appears on the declaration identified by the given path.
+     * Gets the language model element referred to by the leaf node of the given
+     * {@link DocTreePath}, or null if unknown.
      */
-    public abstract Element getElement(TreePath path, ReferenceTree reference);
+    public abstract Element getElement(DocTreePath path);
 
     public abstract DocSourcePositions getSourcePositions();
 
diff --git a/langtools/src/share/classes/com/sun/source/util/TreeScanner.java b/langtools/src/share/classes/com/sun/source/util/TreeScanner.java
index ee05b22..a6d0466 100644
--- a/langtools/src/share/classes/com/sun/source/util/TreeScanner.java
+++ b/langtools/src/share/classes/com/sun/source/util/TreeScanner.java
@@ -149,6 +149,7 @@
     public R visitVariable(VariableTree node, P p) {
         R r = scan(node.getModifiers(), p);
         r = scanAndReduce(node.getType(), p, r);
+        r = scanAndReduce(node.getNameExpression(), p, r);
         r = scanAndReduce(node.getInitializer(), p, r);
         return r;
     }
diff --git a/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java
index be6d528..17c21c8 100644
--- a/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java
@@ -751,7 +751,7 @@
                 break;
             // exception parameter
             case EXCEPTION_PARAMETER:
-                out.writeByte(p.exception_index);
+                out.writeShort(p.exception_index);
                 break;
             // method receiver
             case METHOD_RECEIVER:
@@ -770,11 +770,11 @@
                 break;
             // class extends or implements clause
             case CLASS_EXTENDS:
-                out.writeByte(p.type_index);
+                out.writeShort(p.type_index);
                 break;
             // throws
             case THROWS:
-                out.writeByte(p.type_index);
+                out.writeShort(p.type_index);
                 break;
             // method parameter
             case METHOD_FORMAL_PARAMETER:
diff --git a/langtools/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java b/langtools/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java
index ec842d0..1369069 100644
--- a/langtools/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java
+++ b/langtools/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java
@@ -111,7 +111,7 @@
             break;
         // exception parameter
         case EXCEPTION_PARAMETER:
-            position.exception_index = cr.readUnsignedByte();
+            position.exception_index = cr.readUnsignedShort();
             break;
         // method receiver
         case METHOD_RECEIVER:
@@ -198,7 +198,7 @@
             break;
         // exception parameter
         case EXCEPTION_PARAMETER:
-            n += 1; // exception_index
+            n += 2; // exception_index
             break;
         // method receiver
         case METHOD_RECEIVER:
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java
index 4ec8af0..0468a8e 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java
@@ -60,17 +60,24 @@
      * @param htmltree the content tree to which the parameters will be added.
      * @return the display length required to write this information.
      */
-    protected int addTypeParameters(ExecutableMemberDoc member, Content htmltree) {
-        LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
-            LinkInfoImpl.CONTEXT_MEMBER_TYPE_PARAMS, member, false);
-        String typeParameters = writer.getTypeParameterLinks(linkInfo);
-        if (linkInfo.displayLength > 0) {
-            Content linkContent = new RawHtml(typeParameters);
-            htmltree.addContent(linkContent);
+    protected void addTypeParameters(ExecutableMemberDoc member, Content htmltree) {
+        Content typeParameters = getTypeParameters(member);
+        if (!typeParameters.isEmpty()) {
+            htmltree.addContent(typeParameters);
             htmltree.addContent(writer.getSpace());
-            writer.displayLength += linkInfo.displayLength + 1;
         }
-        return linkInfo.displayLength;
+    }
+
+    /**
+     * Get the type parameters for the executable member.
+     *
+     * @param member the member for which to get the type parameters.
+     * @return the type parameters.
+     */
+    protected Content getTypeParameters(ExecutableMemberDoc member) {
+        LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
+            LinkInfoImpl.Kind.MEMBER_TYPE_PARAMS, member);
+        return writer.getTypeParameterLinks(linkInfo);
     }
 
     /**
@@ -78,7 +85,7 @@
      */
     protected Content getDeprecatedLink(ProgramElementDoc member) {
         ExecutableMemberDoc emd = (ExecutableMemberDoc)member;
-        return writer.getDocLink(LinkInfoImpl.CONTEXT_MEMBER, (MemberDoc) emd,
+        return writer.getDocLink(LinkInfoImpl.Kind.MEMBER, (MemberDoc) emd,
                 emd.qualifiedName() + emd.flatSignature());
     }
 
@@ -90,16 +97,15 @@
      * @param member the member being linked to
      * @param tdSummary the content tree to which the link will be added
      */
-    protected void addSummaryLink(int context, ClassDoc cd, ProgramElementDoc member,
+    protected void addSummaryLink(LinkInfoImpl.Kind context, ClassDoc cd, ProgramElementDoc member,
             Content tdSummary) {
         ExecutableMemberDoc emd = (ExecutableMemberDoc)member;
         String name = emd.name();
-        Content strong = HtmlTree.STRONG(new RawHtml(
+        Content strong = HtmlTree.STRONG(
                 writer.getDocLink(context, cd, (MemberDoc) emd,
-                name, false)));
+                name, false));
         Content code = HtmlTree.CODE(strong);
-        writer.displayLength = name.length();
-        addParameters(emd, false, code);
+        addParameters(emd, false, code, name.length() - 1);
         tdSummary.addContent(code);
     }
 
@@ -112,9 +118,9 @@
      */
     protected void addInheritedSummaryLink(ClassDoc cd,
             ProgramElementDoc member, Content linksTree) {
-        linksTree.addContent(new RawHtml(
-                writer.getDocLink(LinkInfoImpl.CONTEXT_MEMBER, cd, (MemberDoc) member,
-                member.name(), false)));
+        linksTree.addContent(
+                writer.getDocLink(LinkInfoImpl.Kind.MEMBER, cd, (MemberDoc) member,
+                member.name(), false));
     }
 
     /**
@@ -126,11 +132,11 @@
      * @param tree the content tree to which the parameter information will be added.
      */
     protected void addParam(ExecutableMemberDoc member, Parameter param,
-        boolean isVarArg, Content tree) {
+            boolean isVarArg, Content tree) {
         if (param.type() != null) {
-            Content link = new RawHtml(writer.getLink(new LinkInfoImpl(
-                    configuration, LinkInfoImpl.CONTEXT_EXECUTABLE_MEMBER_PARAM,
-                    param.type(), isVarArg)));
+            Content link = writer.getLink(new LinkInfoImpl(
+                    configuration, LinkInfoImpl.Kind.EXECUTABLE_MEMBER_PARAM,
+                    param.type()).varargs(isVarArg));
             tree.addContent(link);
         }
         if(param.name().length() > 0) {
@@ -153,8 +159,8 @@
         tree.addContent(writer.getSpace());
         tree.addContent(rcvrType.typeName());
         LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
-                LinkInfoImpl.CONTEXT_CLASS_SIGNATURE, rcvrType);
-        tree.addContent(new RawHtml(writer.getTypeParameterLinks(linkInfo)));
+                LinkInfoImpl.Kind.CLASS_SIGNATURE, rcvrType);
+        tree.addContent(writer.getTypeParameterLinks(linkInfo));
         tree.addContent(writer.getSpace());
         tree.addContent("this");
     }
@@ -166,8 +172,8 @@
      * @param member the member to write parameters for.
      * @param htmltree the content tree to which the parameters information will be added.
      */
-    protected void addParameters(ExecutableMemberDoc member, Content htmltree) {
-        addParameters(member, true, htmltree);
+    protected void addParameters(ExecutableMemberDoc member, Content htmltree, int indentSize) {
+        addParameters(member, true, htmltree, indentSize);
     }
 
     /**
@@ -178,15 +184,11 @@
      * @param htmltree the content tree to which the parameters information will be added.
      */
     protected void addParameters(ExecutableMemberDoc member,
-            boolean includeAnnotations, Content htmltree) {
+            boolean includeAnnotations, Content htmltree, int indentSize) {
         htmltree.addContent("(");
         String sep = "";
         Parameter[] params = member.parameters();
-        String indent = makeSpace(writer.displayLength);
-        if (configuration.linksource) {
-            //add spaces to offset indentation changes caused by link.
-            indent+= makeSpace(member.name().length());
-        }
+        String indent = makeSpace(indentSize + 1);
         Type rcvrType = member.receiverType();
         if (includeAnnotations && rcvrType instanceof AnnotatedType) {
             AnnotationDesc[] descList = rcvrType.asAnnotatedType().annotations();
@@ -240,53 +242,30 @@
      * @param member the member to write exceptions for.
      * @param htmltree the content tree to which the exceptions information will be added.
      */
-    protected void addExceptions(ExecutableMemberDoc member, Content htmltree) {
+    protected void addExceptions(ExecutableMemberDoc member, Content htmltree, int indentSize) {
         Type[] exceptions = member.thrownExceptionTypes();
-        if(exceptions.length > 0) {
+        if (exceptions.length > 0) {
             LinkInfoImpl memberTypeParam = new LinkInfoImpl(configuration,
-                    LinkInfoImpl.CONTEXT_MEMBER, member, false);
-            int retlen = getReturnTypeLength(member);
-            writer.getTypeParameterLinks(memberTypeParam);
-            retlen += memberTypeParam.displayLength == 0 ?
-                0 : memberTypeParam.displayLength + 1;
-            String indent = makeSpace(modifierString(member).length() +
-                    member.name().length() + retlen - 4);
+                    LinkInfoImpl.Kind.MEMBER, member);
+            String indent = makeSpace(indentSize + 1 - 7);
             htmltree.addContent(DocletConstants.NL);
             htmltree.addContent(indent);
             htmltree.addContent("throws ");
-            indent += "       ";
-            Content link = new RawHtml(writer.getLink(new LinkInfoImpl(configuration,
-                    LinkInfoImpl.CONTEXT_MEMBER, exceptions[0])));
+            indent = makeSpace(indentSize + 1);
+            Content link = writer.getLink(new LinkInfoImpl(configuration,
+                    LinkInfoImpl.Kind.MEMBER, exceptions[0]));
             htmltree.addContent(link);
             for(int i = 1; i < exceptions.length; i++) {
                 htmltree.addContent(",");
                 htmltree.addContent(DocletConstants.NL);
                 htmltree.addContent(indent);
-                Content exceptionLink = new RawHtml(writer.getLink(new LinkInfoImpl(
-                        configuration, LinkInfoImpl.CONTEXT_MEMBER, exceptions[i])));
+                Content exceptionLink = writer.getLink(new LinkInfoImpl(
+                        configuration, LinkInfoImpl.Kind.MEMBER, exceptions[i]));
                 htmltree.addContent(exceptionLink);
             }
         }
     }
 
-    protected int getReturnTypeLength(ExecutableMemberDoc member) {
-        if (member instanceof MethodDoc) {
-            MethodDoc method = (MethodDoc)member;
-            Type rettype = method.returnType();
-            if (rettype.isPrimitive()) {
-                return rettype.typeName().length() +
-                       rettype.dimension().length();
-            } else {
-                LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
-                    LinkInfoImpl.CONTEXT_MEMBER, rettype);
-                writer.getLink(linkInfo);
-                return linkInfo.displayLength;
-            }
-        } else {   // it's a constructordoc
-            return -1;
-        }
-    }
-
     protected ClassDoc implementsMethodInIntfac(MethodDoc method,
                                                 ClassDoc[] intfacs) {
         for (int i = 0; i < intfacs.length; i++) {
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractIndexWriter.java
index 62dabe3..87a5bce 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractIndexWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractIndexWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -139,9 +139,8 @@
      * @param dlTree the content tree to which the description will be added
      */
     protected void addDescription(ClassDoc cd, Content dlTree) {
-        Content link = new RawHtml(
-                getLink(new LinkInfoImpl(configuration,
-                        LinkInfoImpl.CONTEXT_INDEX, cd, true)));
+        Content link = getLink(new LinkInfoImpl(configuration,
+                        LinkInfoImpl.Kind.INDEX, cd).strong(true));
         Content dt = HtmlTree.DT(link);
         dt.addContent(" - ");
         addClassInfo(cd, dt);
@@ -152,7 +151,7 @@
     }
 
     /**
-     * Add the classkind(class, interface, exception, error of the class
+     * Add the classkind (class, interface, exception), error of the class
      * passed.
      *
      * @param cd the class being documented
@@ -161,8 +160,9 @@
     protected void addClassInfo(ClassDoc cd, Content contentTree) {
         contentTree.addContent(getResource("doclet.in",
                 Util.getTypeName(configuration, cd, false),
-                getPackageLinkString(cd.containingPackage(),
-                Util.getPackageName(cd.containingPackage()), false)));
+                getPackageLink(cd.containingPackage(),
+                    Util.getPackageName(cd.containingPackage()))
+                ));
     }
 
     /**
@@ -175,11 +175,8 @@
         String name = (member instanceof ExecutableMemberDoc)?
             member.name() + ((ExecutableMemberDoc)member).flatSignature() :
             member.name();
-        if (name.indexOf("<") != -1 || name.indexOf(">") != -1) {
-                name = Util.escapeHtmlChars(name);
-        }
         Content span = HtmlTree.SPAN(HtmlStyle.strong,
-                getDocLink(LinkInfoImpl.CONTEXT_INDEX, member, name));
+                getDocLink(LinkInfoImpl.Kind.INDEX, member, name));
         Content dt = HtmlTree.DT(span);
         dt.addContent(" - ");
         addMemberDesc(member, dt);
@@ -253,7 +250,7 @@
                         getResource("doclet.Method_in", classdesc));
             }
         }
-        addPreQualifiedClassLink(LinkInfoImpl.CONTEXT_INDEX, containing,
+        addPreQualifiedClassLink(LinkInfoImpl.Kind.INDEX, containing,
                 false, contentTree);
     }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java
index b8b0354..8ca5691 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -91,7 +91,7 @@
      *
      * @return a string for the table caption
      */
-    public abstract String getCaption();
+    public abstract Content getCaption();
 
     /**
      * Get the summary table header for the member.
@@ -143,7 +143,7 @@
      */
     protected void addSummaryLink(ClassDoc cd, ProgramElementDoc member,
             Content tdSummary) {
-        addSummaryLink(LinkInfoImpl.CONTEXT_MEMBER, cd, member, tdSummary);
+        addSummaryLink(LinkInfoImpl.Kind.MEMBER, cd, member, tdSummary);
     }
 
     /**
@@ -154,7 +154,7 @@
      * @param member the member to be documented
      * @param tdSummary the content tree to which the summary link will be added
      */
-    protected abstract void addSummaryLink(int context,
+    protected abstract void addSummaryLink(LinkInfoImpl.Kind context,
             ClassDoc cd, ProgramElementDoc member, Content tdSummary);
 
     /**
@@ -193,14 +193,13 @@
     protected abstract void addNavDetailLink(boolean link, Content liNav);
 
     /**
-     * Add the member name to the content tree and modifies the display length.
+     * Add the member name to the content tree.
      *
      * @param name the member name to be added to the content tree.
      * @param htmltree the content tree to which the name will be added.
      */
     protected void addName(String name, Content htmltree) {
         htmltree.addContent(name);
-        writer.displayLength += name.length();
     }
 
     /**
@@ -259,7 +258,7 @@
             return "";
         }
         StringBuilder sb = new StringBuilder(len);
-        for(int i = 0; i < len; i++) {
+        for (int i = 0; i < len; i++) {
             sb.append(' ');
     }
         return sb.toString();
@@ -286,19 +285,22 @@
         } else {
             if (member instanceof ExecutableMemberDoc &&
                     ((ExecutableMemberDoc) member).typeParameters().length > 0) {
+                Content typeParameters = ((AbstractExecutableMemberWriter) this).getTypeParameters(
+                        (ExecutableMemberDoc) member);
+                    code.addContent(typeParameters);
                 //Code to avoid ugly wrapping in member summary table.
-                int displayLength = ((AbstractExecutableMemberWriter) this).addTypeParameters(
-                        (ExecutableMemberDoc) member, code);
-                if (displayLength > 10) {
+                if (typeParameters.charCount() > 10) {
                     code.addContent(new HtmlTree(HtmlTag.BR));
+                } else {
+                    code.addContent(writer.getSpace());
                 }
-                code.addContent(new RawHtml(
+                code.addContent(
                         writer.getLink(new LinkInfoImpl(configuration,
-                        LinkInfoImpl.CONTEXT_SUMMARY_RETURN_TYPE, type))));
+                        LinkInfoImpl.Kind.SUMMARY_RETURN_TYPE, type)));
             } else {
-                code.addContent(new RawHtml(
+                code.addContent(
                         writer.getLink(new LinkInfoImpl(configuration,
-                        LinkInfoImpl.CONTEXT_SUMMARY_RETURN_TYPE, type))));
+                        LinkInfoImpl.Kind.SUMMARY_RETURN_TYPE, type)));
             }
 
         }
@@ -346,10 +348,10 @@
      * @param contentTree the content tree to which the deprecated information will be added.
      */
     protected void addDeprecatedInfo(ProgramElementDoc member, Content contentTree) {
-        String output = (new DeprecatedTaglet()).getTagletOutput(member,
-            writer.getTagletWriterInstance(false)).toString().trim();
+        Content output = (new DeprecatedTaglet()).getTagletOutput(member,
+            writer.getTagletWriterInstance(false));
         if (!output.isEmpty()) {
-            Content deprecatedContent = new RawHtml(output);
+            Content deprecatedContent = output;
             Content div = HtmlTree.DIV(HtmlStyle.block, deprecatedContent);
             contentTree.addContent(div);
         }
@@ -378,7 +380,7 @@
      * @return a header content for the section.
      */
     protected Content getHead(MemberDoc member) {
-        Content memberContent = new RawHtml(member.name());
+        Content memberContent = new StringContent(member.name());
         Content heading = HtmlTree.HEADING(HtmlConstants.MEMBER_HEADING, memberContent);
         return heading;
     }
@@ -412,7 +414,7 @@
             String tableSummary, String[] tableHeader, Content contentTree) {
         if (deprmembers.size() > 0) {
             Content table = HtmlTree.TABLE(0, 3, 0, tableSummary,
-                writer.getTableCaption(configuration.getText(headingKey)));
+                writer.getTableCaption(configuration.getResource(headingKey)));
             table.addContent(writer.getSummaryTableHeader(tableHeader, "col"));
             Content tbody = new HtmlTree(HtmlTag.TBODY);
             for (int i = 0; i < deprmembers.size(); i++) {
@@ -444,7 +446,7 @@
      * @param contentTree the content tree to which the use information will be added
      */
     protected void addUseInfo(List<? extends ProgramElementDoc> mems,
-            String heading, String tableSummary, Content contentTree) {
+            Content heading, String tableSummary, Content contentTree) {
         if (mems == null) {
             return;
         }
@@ -483,7 +485,7 @@
                     tdLast.addContent(name);
                 }
                 addSummaryLink(pgmdoc instanceof ClassDoc ?
-                    LinkInfoImpl.CONTEXT_CLASS_USE : LinkInfoImpl.CONTEXT_MEMBER,
+                    LinkInfoImpl.Kind.CLASS_USE : LinkInfoImpl.Kind.MEMBER,
                     cd, pgmdoc, tdLast);
                 writer.addSummaryLinkComment(this, pgmdoc, tdLast);
                 tr.addContent(tdLast);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java
index 7ccee48..95cd4a4 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java
@@ -158,10 +158,10 @@
             }
             body.addContent(div);
             if (configuration.showProfiles) {
-                String profileSummary = configuration.getText("doclet.Profiles");
-                String profilesTableSummary = configuration.getText("doclet.Member_Table_Summary",
-                configuration.getText("doclet.Profile_Summary"),
-                configuration.getText("doclet.profiles"));
+                Content profileSummary = configuration.getResource("doclet.Profiles");
+                Content profilesTableSummary = configuration.getResource("doclet.Member_Table_Summary",
+                        configuration.getResource("doclet.Profile_Summary"),
+                        configuration.getResource("doclet.profiles"));
                 addProfilesList(profileSummary, profilesTableSummary, body);
             }
             addPackagesList(packages, text, tableSummary, body);
@@ -217,7 +217,7 @@
      * @param profilesTableSummary the profiles table summary information
      * @param body the content tree to which the profiles list will be added
      */
-    protected void addProfilesList(String profileSummary, String profilesTableSummary,
+    protected void addProfilesList(Content profileSummary, Content profilesTableSummary,
             Content body) {
     }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractTreeWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractTreeWriter.java
index 53af067..8cc0b61 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractTreeWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractTreeWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -152,7 +152,7 @@
                     } else {
                         contentTree.addContent(", ");
                     }
-                    addPreQualifiedClassLink(LinkInfoImpl.CONTEXT_TREE,
+                    addPreQualifiedClassLink(LinkInfoImpl.Kind.TREE,
                             interfaces[i], contentTree);
                     counter++;
                 }
@@ -170,7 +170,7 @@
      * @param contentTree the content tree to which the information will be added
      */
     protected void addPartialInfo(ClassDoc cd, Content contentTree) {
-        addPreQualifiedStrongClassLink(LinkInfoImpl.CONTEXT_TREE, cd, contentTree);
+        addPreQualifiedStrongClassLink(LinkInfoImpl.Kind.TREE, cd, contentTree);
     }
 
     /**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java
index 85b8ce9..0d6846a 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -156,14 +156,13 @@
             if (!Util.isCoreClass(cd)) {
                 continue;
             }
-            String label = italicsClassName(cd, false);
+            Content label = italicsClassName(cd, false);
             Content linkContent;
-            if(wantFrames){
-                linkContent = new RawHtml(getLink(new LinkInfoImpl(configuration,
-                        LinkInfoImpl.ALL_CLASSES_FRAME, cd, label, "classFrame")));
+            if (wantFrames) {
+                linkContent = getLink(new LinkInfoImpl(configuration,
+                        LinkInfoImpl.Kind.ALL_CLASSES_FRAME, cd).label(label).target("classFrame"));
             } else {
-                linkContent = new RawHtml(getLink(new LinkInfoImpl(
-                        configuration, cd, label)));
+                linkContent = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.DEFAULT, cd).label(label));
             }
             Content li = HtmlTree.LI(linkContent);
             content.addContent(li);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java
index cf8fba1..ff8fc10 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -111,8 +111,8 @@
     /**
      * {@inheritDoc}
      */
-    public String getCaption() {
-        return configuration.getText("doclet.Annotation_Type_Optional_Members");
+    public Content getCaption() {
+        return configuration.getResource("doclet.Annotation_Type_Optional_Members");
     }
 
     /**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java
index daee94e..6583b89 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -105,9 +105,9 @@
         Content pre = new HtmlTree(HtmlTag.PRE);
         writer.addAnnotationInfo(member, pre);
         addModifiers(member, pre);
-        Content link = new RawHtml(
+        Content link =
                 writer.getLink(new LinkInfoImpl(configuration,
-                        LinkInfoImpl.CONTEXT_MEMBER, getType(member))));
+                        LinkInfoImpl.Kind.MEMBER, getType(member)));
         pre.addContent(link);
         pre.addContent(writer.getSpace());
         if (configuration.linksource) {
@@ -183,8 +183,8 @@
     /**
      * {@inheritDoc}
      */
-    public String getCaption() {
-        return configuration.getText("doclet.Annotation_Type_Required_Members");
+    public Content getCaption() {
+        return configuration.getResource("doclet.Annotation_Type_Required_Members");
     }
 
     /**
@@ -223,10 +223,10 @@
     /**
      * {@inheritDoc}
      */
-    protected void addSummaryLink(int context, ClassDoc cd, ProgramElementDoc member,
+    protected void addSummaryLink(LinkInfoImpl.Kind context, ClassDoc cd, ProgramElementDoc member,
             Content tdSummary) {
-        Content strong = HtmlTree.STRONG(new RawHtml(
-                writer.getDocLink(context, (MemberDoc) member, member.name(), false)));
+        Content strong = HtmlTree.STRONG(
+                writer.getDocLink(context, (MemberDoc) member, member.name(), false));
         Content code = HtmlTree.CODE(strong);
         tdSummary.addContent(code);
     }
@@ -251,7 +251,7 @@
      * {@inheritDoc}
      */
     protected Content getDeprecatedLink(ProgramElementDoc member) {
-        return writer.getDocLink(LinkInfoImpl.CONTEXT_MEMBER,
+        return writer.getDocLink(LinkInfoImpl.Kind.MEMBER,
                 (MemberDoc) member, ((MemberDoc)member).qualifiedName());
     }
 
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java
index a86312e..df4b5ea 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -116,9 +116,9 @@
     public Content getNavLinkPrevious() {
         Content li;
         if (prev != null) {
-            Content prevLink = new RawHtml(getLink(new LinkInfoImpl(configuration,
-                    LinkInfoImpl.CONTEXT_CLASS, prev.asClassDoc(), "",
-                    configuration.getText("doclet.Prev_Class"), true)));
+            Content prevLink = getLink(new LinkInfoImpl(configuration,
+                    LinkInfoImpl.Kind.CLASS, prev.asClassDoc())
+                    .label(configuration.getText("doclet.Prev_Class")).strong(true));
             li = HtmlTree.LI(prevLink);
         }
         else
@@ -134,9 +134,9 @@
     public Content getNavLinkNext() {
         Content li;
         if (next != null) {
-            Content nextLink = new RawHtml(getLink(new LinkInfoImpl(configuration,
-                    LinkInfoImpl.CONTEXT_CLASS, next.asClassDoc(), "",
-                    configuration.getText("doclet.Next_Class"), true)));
+            Content nextLink = getLink(new LinkInfoImpl(configuration,
+                    LinkInfoImpl.Kind.CLASS, next.asClassDoc())
+                    .label(configuration.getText("doclet.Next_Class")).strong(true));
             li = HtmlTree.LI(nextLink);
         }
         else
@@ -163,11 +163,11 @@
             div.addContent(pkgNameDiv);
         }
         LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
-                LinkInfoImpl.CONTEXT_CLASS_HEADER, annotationType, false);
+                LinkInfoImpl.Kind.CLASS_HEADER, annotationType);
         Content headerContent = new StringContent(header);
         Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING, true,
                 HtmlStyle.title, headerContent);
-        heading.addContent(new RawHtml(getTypeParameterLinks(linkInfo)));
+        heading.addContent(getTypeParameterLinks(linkInfo));
         div.addContent(heading);
         bodyTree.addContent(div);
         return bodyTree;
@@ -220,9 +220,9 @@
         addAnnotationInfo(annotationType, pre);
         pre.addContent(modifiers);
         LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
-                LinkInfoImpl.CONTEXT_CLASS_SIGNATURE, annotationType, false);
+                LinkInfoImpl.Kind.CLASS_SIGNATURE, annotationType);
         Content annotationName = new StringContent(annotationType.name());
-        Content parameterLinks = new RawHtml(getTypeParameterLinks(linkInfo));
+        Content parameterLinks = getTypeParameterLinks(linkInfo);
         if (configuration.linksource) {
             addSrcLink(annotationType, annotationName, pre);
             pre.addContent(parameterLinks);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java
index 8e2e14f..90da398 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -256,10 +256,10 @@
      */
     protected void addPackageList(Content contentTree) throws IOException {
         Content table = HtmlTree.TABLE(0, 3, 0, useTableSummary,
-                getTableCaption(configuration.getText(
+                getTableCaption(configuration.getResource(
                 "doclet.ClassUse_Packages.that.use.0",
-                getLink(new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_CLASS_USE_HEADER, classdoc,
-                false)))));
+                getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER, classdoc
+                )))));
         table.addContent(getSummaryTableHeader(packageTableHeader, "col"));
         Content tbody = new HtmlTree(HtmlTag.TBODY);
         Iterator<PackageDoc> it = pkgSet.iterator();
@@ -291,10 +291,10 @@
             return;
         }
         Content table = HtmlTree.TABLE(0, 3, 0, useTableSummary,
-                getTableCaption(configuration.getText(
+                getTableCaption(configuration.getResource(
                 "doclet.ClassUse_PackageAnnotation",
                 getLink(new LinkInfoImpl(configuration,
-                        LinkInfoImpl.CONTEXT_CLASS_USE_HEADER, classdoc, false)))));
+                        LinkInfoImpl.Kind.CLASS_USE_HEADER, classdoc)))));
         table.addContent(getSummaryTableHeader(packageTableHeader, "col"));
         Content tbody = new HtmlTree(HtmlTag.TBODY);
         Iterator<PackageDoc> it = pkgToPackageAnnotations.iterator();
@@ -331,11 +331,10 @@
         for (Iterator<PackageDoc> it = pkgSet.iterator(); it.hasNext();) {
             PackageDoc pkg = it.next();
             Content li = HtmlTree.LI(HtmlStyle.blockList, getMarkerAnchor(pkg.name()));
-            Content link = new RawHtml(
-                    configuration.getText("doclet.ClassUse_Uses.of.0.in.1",
-                    getLink(new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_CLASS_USE_HEADER,
-                    classdoc, false)),
-                    getPackageLinkString(pkg, Util.getPackageName(pkg), false)));
+            Content link = getResource("doclet.ClassUse_Uses.of.0.in.1",
+                    getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER,
+                    classdoc)),
+                    getPackageLink(pkg, Util.getPackageName(pkg)));
             Content heading = HtmlTree.HEADING(HtmlConstants.SUMMARY_HEADING, link);
             li.addContent(heading);
             addClassUse(pkg, li);
@@ -368,71 +367,71 @@
      * @param contentTree the content tree to which the class use information will be added
      */
     protected void addClassUse(PackageDoc pkg, Content contentTree) throws IOException {
-        String classLink = getLink(new LinkInfoImpl(configuration,
-            LinkInfoImpl.CONTEXT_CLASS_USE_HEADER, classdoc, false));
-        String pkgLink = getPackageLinkString(pkg, Util.getPackageName(pkg), false);
+        Content classLink = getLink(new LinkInfoImpl(configuration,
+            LinkInfoImpl.Kind.CLASS_USE_HEADER, classdoc));
+        Content pkgLink = getPackageLink(pkg, Util.getPackageName(pkg));
         classSubWriter.addUseInfo(pkgToClassAnnotations.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_Annotation", classLink,
+                configuration.getResource("doclet.ClassUse_Annotation", classLink,
                 pkgLink), classUseTableSummary, contentTree);
         classSubWriter.addUseInfo(pkgToClassTypeParameter.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_TypeParameter", classLink,
+                configuration.getResource("doclet.ClassUse_TypeParameter", classLink,
                 pkgLink), classUseTableSummary, contentTree);
         classSubWriter.addUseInfo(pkgToSubclass.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_Subclass", classLink,
+                configuration.getResource("doclet.ClassUse_Subclass", classLink,
                 pkgLink), subclassUseTableSummary, contentTree);
         classSubWriter.addUseInfo(pkgToSubinterface.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_Subinterface", classLink,
+                configuration.getResource("doclet.ClassUse_Subinterface", classLink,
                 pkgLink), subinterfaceUseTableSummary, contentTree);
         classSubWriter.addUseInfo(pkgToImplementingClass.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_ImplementingClass", classLink,
+                configuration.getResource("doclet.ClassUse_ImplementingClass", classLink,
                 pkgLink), classUseTableSummary, contentTree);
         fieldSubWriter.addUseInfo(pkgToField.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_Field", classLink,
+                configuration.getResource("doclet.ClassUse_Field", classLink,
                 pkgLink), fieldUseTableSummary, contentTree);
         fieldSubWriter.addUseInfo(pkgToFieldAnnotations.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_FieldAnnotations", classLink,
+                configuration.getResource("doclet.ClassUse_FieldAnnotations", classLink,
                 pkgLink), fieldUseTableSummary, contentTree);
         fieldSubWriter.addUseInfo(pkgToFieldTypeParameter.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_FieldTypeParameter", classLink,
+                configuration.getResource("doclet.ClassUse_FieldTypeParameter", classLink,
                 pkgLink), fieldUseTableSummary, contentTree);
         methodSubWriter.addUseInfo(pkgToMethodAnnotations.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_MethodAnnotations", classLink,
+                configuration.getResource("doclet.ClassUse_MethodAnnotations", classLink,
                 pkgLink), methodUseTableSummary, contentTree);
         methodSubWriter.addUseInfo(pkgToMethodParameterAnnotations.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_MethodParameterAnnotations", classLink,
+                configuration.getResource("doclet.ClassUse_MethodParameterAnnotations", classLink,
                 pkgLink), methodUseTableSummary, contentTree);
         methodSubWriter.addUseInfo(pkgToMethodTypeParameter.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_MethodTypeParameter", classLink,
+                configuration.getResource("doclet.ClassUse_MethodTypeParameter", classLink,
                 pkgLink), methodUseTableSummary, contentTree);
         methodSubWriter.addUseInfo(pkgToMethodReturn.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_MethodReturn", classLink,
+                configuration.getResource("doclet.ClassUse_MethodReturn", classLink,
                 pkgLink), methodUseTableSummary, contentTree);
         methodSubWriter.addUseInfo(pkgToMethodReturnTypeParameter.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_MethodReturnTypeParameter", classLink,
+                configuration.getResource("doclet.ClassUse_MethodReturnTypeParameter", classLink,
                 pkgLink), methodUseTableSummary, contentTree);
         methodSubWriter.addUseInfo(pkgToMethodArgs.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_MethodArgs", classLink,
+                configuration.getResource("doclet.ClassUse_MethodArgs", classLink,
                 pkgLink), methodUseTableSummary, contentTree);
         methodSubWriter.addUseInfo(pkgToMethodArgTypeParameter.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_MethodArgsTypeParameters", classLink,
+                configuration.getResource("doclet.ClassUse_MethodArgsTypeParameters", classLink,
                 pkgLink), methodUseTableSummary, contentTree);
         methodSubWriter.addUseInfo(pkgToMethodThrows.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_MethodThrows", classLink,
+                configuration.getResource("doclet.ClassUse_MethodThrows", classLink,
                 pkgLink), methodUseTableSummary, contentTree);
         constrSubWriter.addUseInfo(pkgToConstructorAnnotations.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_ConstructorAnnotations", classLink,
+                configuration.getResource("doclet.ClassUse_ConstructorAnnotations", classLink,
                 pkgLink), constructorUseTableSummary, contentTree);
         constrSubWriter.addUseInfo(pkgToConstructorParameterAnnotations.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_ConstructorParameterAnnotations", classLink,
+                configuration.getResource("doclet.ClassUse_ConstructorParameterAnnotations", classLink,
                 pkgLink), constructorUseTableSummary, contentTree);
         constrSubWriter.addUseInfo(pkgToConstructorArgs.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_ConstructorArgs", classLink,
+                configuration.getResource("doclet.ClassUse_ConstructorArgs", classLink,
                 pkgLink), constructorUseTableSummary, contentTree);
         constrSubWriter.addUseInfo(pkgToConstructorArgTypeParameter.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_ConstructorArgsTypeParameters", classLink,
+                configuration.getResource("doclet.ClassUse_ConstructorArgsTypeParameters", classLink,
                 pkgLink), constructorUseTableSummary, contentTree);
         constrSubWriter.addUseInfo(pkgToConstructorThrows.get(pkg.name()),
-                configuration.getText("doclet.ClassUse_ConstructorThrows", classLink,
+                configuration.getResource("doclet.ClassUse_ConstructorThrows", classLink,
                 pkgLink), constructorUseTableSummary, contentTree);
     }
 
@@ -450,7 +449,10 @@
         Content bodyTree = getBody(true, getWindowTitle(title));
         addTop(bodyTree);
         addNavLinks(true, bodyTree);
-        Content headContent = getResource("doclet.ClassUse_Title", cltype, clname);
+        ContentBuilder headContent = new ContentBuilder();
+        headContent.addContent(getResource("doclet.ClassUse_Title", cltype));
+        headContent.addContent(new HtmlTree(HtmlTag.BR));
+        headContent.addContent(clname);
         Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING,
                 true, HtmlStyle.title, headContent);
         Content div = HtmlTree.DIV(HtmlStyle.header, heading);
@@ -476,9 +478,9 @@
      * @return a content tree for the class page link
      */
     protected Content getNavLinkClass() {
-        Content linkContent = new RawHtml(getLink(new LinkInfoImpl(
-                configuration, LinkInfoImpl.CONTEXT_CLASS_USE_HEADER, classdoc,
-                "", configuration.getText("doclet.Class"), false)));
+        Content linkContent = getLink(new LinkInfoImpl(
+                configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER, classdoc)
+                .label(configuration.getText("doclet.Class")));
         Content li = HtmlTree.LI(linkContent);
         return li;
     }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java
index 36df531..47e9346 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java
@@ -124,9 +124,9 @@
     public Content getNavLinkPrevious() {
         Content li;
         if (prev != null) {
-            Content prevLink = new RawHtml(getLink(new LinkInfoImpl(configuration,
-                    LinkInfoImpl.CONTEXT_CLASS, prev, "",
-                    configuration.getText("doclet.Prev_Class"), true)));
+            Content prevLink = getLink(new LinkInfoImpl(configuration,
+                    LinkInfoImpl.Kind.CLASS, prev)
+                    .label(configuration.getText("doclet.Prev_Class")).strong(true));
             li = HtmlTree.LI(prevLink);
         }
         else
@@ -142,9 +142,9 @@
     public Content getNavLinkNext() {
         Content li;
         if (next != null) {
-            Content nextLink = new RawHtml(getLink(new LinkInfoImpl(configuration,
-                    LinkInfoImpl.CONTEXT_CLASS, next, "",
-                    configuration.getText("doclet.Next_Class"), true)));
+            Content nextLink = getLink(new LinkInfoImpl(configuration,
+                    LinkInfoImpl.Kind.CLASS, next)
+                    .label(configuration.getText("doclet.Next_Class")).strong(true));
             li = HtmlTree.LI(nextLink);
         }
         else
@@ -185,13 +185,13 @@
             div.addContent(pkgNameDiv);
         }
         LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
-                LinkInfoImpl.CONTEXT_CLASS_HEADER, classDoc, false);
+                LinkInfoImpl.Kind.CLASS_HEADER, classDoc);
         //Let's not link to ourselves in the header.
         linkInfo.linkToSelf = false;
         Content headerContent = new StringContent(header);
         Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING, true,
                 HtmlStyle.title, headerContent);
-        heading.addContent(new RawHtml(getTypeParameterLinks(linkInfo)));
+        heading.addContent(getTypeParameterLinks(linkInfo));
         div.addContent(heading);
         bodyTree.addContent(div);
         return bodyTree;
@@ -245,11 +245,11 @@
         addAnnotationInfo(classDoc, pre);
         pre.addContent(modifiers);
         LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
-                LinkInfoImpl.CONTEXT_CLASS_SIGNATURE, classDoc, false);
+                LinkInfoImpl.Kind.CLASS_SIGNATURE, classDoc);
         //Let's not link to ourselves in the signature.
         linkInfo.linkToSelf = false;
         Content className = new StringContent(classDoc.name());
-        Content parameterLinks = new RawHtml(getTypeParameterLinks(linkInfo));
+        Content parameterLinks = getTypeParameterLinks(linkInfo);
         if (configuration.linksource) {
             addSrcLink(classDoc, className, pre);
             pre.addContent(parameterLinks);
@@ -264,9 +264,9 @@
             if (superclass != null) {
                 pre.addContent(DocletConstants.NL);
                 pre.addContent("extends ");
-                Content link = new RawHtml(getLink(new LinkInfoImpl(configuration,
-                        LinkInfoImpl.CONTEXT_CLASS_SIGNATURE_PARENT_NAME,
-                        superclass)));
+                Content link = getLink(new LinkInfoImpl(configuration,
+                        LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME,
+                        superclass));
                 pre.addContent(link);
             }
         }
@@ -285,9 +285,9 @@
                 } else {
                     pre.addContent(", ");
                 }
-                Content link = new RawHtml(getLink(new LinkInfoImpl(configuration,
-                        LinkInfoImpl.CONTEXT_CLASS_SIGNATURE_PARENT_NAME,
-                        implIntfacs[i])));
+                Content link = getLink(new LinkInfoImpl(configuration,
+                        LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME,
+                        implIntfacs[i]));
                 pre.addContent(link);
                 counter++;
             }
@@ -360,22 +360,21 @@
     private Content getTreeForClassHelper(Type type) {
         Content li = new HtmlTree(HtmlTag.LI);
         if (type.equals(classDoc)) {
-            String typeParameters = getTypeParameterLinks(
-                    new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_TREE,
-                    classDoc, false));
+            Content typeParameters = getTypeParameterLinks(
+                    new LinkInfoImpl(configuration, LinkInfoImpl.Kind.TREE,
+                    classDoc));
             if (configuration.shouldExcludeQualifier(
                     classDoc.containingPackage().name())) {
                 li.addContent(type.asClassDoc().name());
-                li.addContent(new RawHtml(typeParameters));
+                li.addContent(typeParameters);
             } else {
                 li.addContent(type.asClassDoc().qualifiedName());
-                li.addContent(new RawHtml(typeParameters));
+                li.addContent(typeParameters);
             }
         } else {
-            Content link = new RawHtml(getLink(new LinkInfoImpl(configuration,
-                    LinkInfoImpl.CONTEXT_CLASS_TREE_PARENT,
-                    type instanceof ClassDoc ? (ClassDoc) type : type,
-                    configuration.getClassName(type.asClassDoc()), false)));
+            Content link = getLink(new LinkInfoImpl(configuration,
+                    LinkInfoImpl.Kind.CLASS_TREE_PARENT, type)
+                    .label(configuration.getClassName(type.asClassDoc())));
             li.addContent(link);
         }
         return li;
@@ -396,9 +395,8 @@
      */
     public void addTypeParamInfo(Content classInfoTree) {
         if (classDoc.typeParamTags().length > 0) {
-            TagletOutput output = (new ParamTaglet()).getTagletOutput(classDoc,
+            Content typeParam = (new ParamTaglet()).getTagletOutput(classDoc,
                     getTagletWriterInstance(false));
-            Content typeParam = new RawHtml(output.toString());
             Content dl = HtmlTree.DL(typeParam);
             classInfoTree.addContent(dl);
         }
@@ -419,7 +417,7 @@
                         "doclet.Subclasses");
                 Content dt = HtmlTree.DT(label);
                 Content dl = HtmlTree.DL(dt);
-                dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_SUBCLASSES,
+                dl.addContent(getClassLinks(LinkInfoImpl.Kind.SUBCLASSES,
                         subclasses));
                 classInfoTree.addContent(dl);
             }
@@ -437,7 +435,7 @@
                         "doclet.Subinterfaces");
                 Content dt = HtmlTree.DT(label);
                 Content dl = HtmlTree.DL(dt);
-                dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_SUBINTERFACES,
+                dl.addContent(getClassLinks(LinkInfoImpl.Kind.SUBINTERFACES,
                         subInterfaces));
                 classInfoTree.addContent(dl);
             }
@@ -461,7 +459,7 @@
                     "doclet.Implementing_Classes");
             Content dt = HtmlTree.DT(label);
             Content dl = HtmlTree.DL(dt);
-            dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_IMPLEMENTED_CLASSES,
+            dl.addContent(getClassLinks(LinkInfoImpl.Kind.IMPLEMENTED_CLASSES,
                     implcl));
             classInfoTree.addContent(dl);
         }
@@ -479,7 +477,7 @@
                     "doclet.All_Implemented_Interfaces");
             Content dt = HtmlTree.DT(label);
             Content dl = HtmlTree.DL(dt);
-            dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_IMPLEMENTED_INTERFACES,
+            dl.addContent(getClassLinks(LinkInfoImpl.Kind.IMPLEMENTED_INTERFACES,
                     interfaceArray));
             classInfoTree.addContent(dl);
         }
@@ -497,7 +495,7 @@
                     "doclet.All_Superinterfaces");
             Content dt = HtmlTree.DT(label);
             Content dl = HtmlTree.DL(dt);
-            dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_SUPER_INTERFACES,
+            dl.addContent(getClassLinks(LinkInfoImpl.Kind.SUPER_INTERFACES,
                     interfaceArray));
             classInfoTree.addContent(dl);
         }
@@ -520,8 +518,8 @@
             Content dt = HtmlTree.DT(label);
             Content dl = HtmlTree.DL(dt);
             Content dd = new HtmlTree(HtmlTag.DD);
-            dd.addContent(new RawHtml(getLink(new LinkInfoImpl(configuration,
-                    LinkInfoImpl.CONTEXT_CLASS, outerClass, false))));
+            dd.addContent(getLink(new LinkInfoImpl(configuration,
+                    LinkInfoImpl.Kind.CLASS, outerClass)));
             dl.addContent(dd);
             classInfoTree.addContent(dl);
         }
@@ -569,7 +567,7 @@
      * @param list the list of classes
      * @return a content tree for the class list
      */
-    private Content getClassLinks(int context, List<?> list) {
+    private Content getClassLinks(LinkInfoImpl.Kind context, List<?> list) {
         Object[] typeList = list.toArray();
         Content dd = new HtmlTree(HtmlTag.DD);
         for (int i = 0; i < list.size(); i++) {
@@ -578,12 +576,12 @@
                 dd.addContent(separator);
             }
             if (typeList[i] instanceof ClassDoc) {
-                Content link = new RawHtml(getLink(
-                        new LinkInfoImpl(configuration, context, (ClassDoc)(typeList[i]))));
+                Content link = getLink(
+                        new LinkInfoImpl(configuration, context, (ClassDoc)(typeList[i])));
                 dd.addContent(link);
             } else {
-                Content link = new RawHtml(getLink(
-                        new LinkInfoImpl(configuration, context, (Type)(typeList[i]))));
+                Content link = getLink(
+                        new LinkInfoImpl(configuration, context, (Type)(typeList[i])));
                 dd.addContent(link);
             }
         }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java
index e74c738..2b37dd6 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java
@@ -31,6 +31,7 @@
 import javax.tools.JavaFileManager;
 
 import com.sun.javadoc.*;
+import com.sun.tools.doclets.formats.html.markup.ContentBuilder;
 import com.sun.tools.doclets.internal.toolkit.*;
 import com.sun.tools.doclets.internal.toolkit.util.*;
 import com.sun.tools.doclint.DocLint;
@@ -562,4 +563,9 @@
         }
         return true;
     }
+
+    @Override
+    public Content newContent() {
+        return new ContentBuilder();
+    }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java
index afc0aeb..02dfdb3 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -184,13 +184,17 @@
      */
     public Content getConstantMembersHeader(ClassDoc cd) {
         //generate links backward only to public classes.
-        String classlink = (cd.isPublic() || cd.isProtected()) ?
+        Content classlink = (cd.isPublic() || cd.isProtected()) ?
             getLink(new LinkInfoImpl(configuration,
-                    LinkInfoImpl.CONTEXT_CONSTANT_SUMMARY, cd, false)) :
-            cd.qualifiedName();
+                    LinkInfoImpl.Kind.CONSTANT_SUMMARY, cd)) :
+            new StringContent(cd.qualifiedName());
         String name = cd.containingPackage().name();
         if (name.length() > 0) {
-            return getClassName(name + "." + classlink);
+            Content cb = new ContentBuilder();
+            cb.addContent(name);
+            cb.addContent(".");
+            cb.addContent(classlink);
+            return getClassName(cb);
         } else {
             return getClassName(classlink);
         }
@@ -202,7 +206,7 @@
      * @param classStr the class name to print.
      * @return the table caption and header
      */
-    protected Content getClassName(String classStr) {
+    protected Content getClassName(Content classStr) {
         Content table = HtmlTree.TABLE(0, 3, 0, constantsTableSummary,
                 getTableCaption(classStr));
         table.addContent(getSummaryTableHeader(constantsTableHeader, "col"));
@@ -260,8 +264,8 @@
             code.addContent(modifier);
             code.addContent(getSpace());
         }
-        Content type = new RawHtml(getLink(new LinkInfoImpl(configuration,
-                LinkInfoImpl.CONTEXT_CONSTANT_SUMMARY, member.type())));
+        Content type = getLink(new LinkInfoImpl(configuration,
+                LinkInfoImpl.Kind.CONSTANT_SUMMARY, member.type()));
         code.addContent(type);
         tdType.addContent(code);
         return tdType;
@@ -274,8 +278,8 @@
      * @return the name column of the constant table row
      */
     private Content getNameColumn(FieldDoc member) {
-        Content nameContent = new RawHtml(getDocLink(
-                LinkInfoImpl.CONTEXT_CONSTANT_SUMMARY, member, member.name(), false));
+        Content nameContent = getDocLink(
+                LinkInfoImpl.Kind.CONSTANT_SUMMARY, member, member.name(), false);
         Content code = HtmlTree.CODE(nameContent);
         return HtmlTree.TD(code);
     }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java
index 85cd1c5..4967370 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java
@@ -126,7 +126,6 @@
      * {@inheritDoc}
      */
     public Content getSignature(ConstructorDoc constructor) {
-        writer.displayLength = 0;
         Content pre = new HtmlTree(HtmlTag.PRE);
         writer.addAnnotationInfo(constructor, pre);
         addModifiers(constructor, pre);
@@ -136,8 +135,9 @@
         } else {
             addName(constructor.name(), pre);
         }
-        addParameters(constructor, pre);
-        addExceptions(constructor, pre);
+        int indent = pre.charCount();
+        addParameters(constructor, pre, indent);
+        addExceptions(constructor, pre, indent);
         return pre;
     }
 
@@ -225,8 +225,8 @@
     /**
      * {@inheritDoc}
      */
-    public String getCaption() {
-        return configuration.getText("doclet.Constructors");
+    public Content getCaption() {
+        return configuration.getResource("doclet.Constructors");
     }
 
     /**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java
index a37d8be..9643e87 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -101,8 +101,8 @@
         Content pre = new HtmlTree(HtmlTag.PRE);
         writer.addAnnotationInfo(enumConstant, pre);
         addModifiers(enumConstant, pre);
-        Content enumConstantLink = new RawHtml(writer.getLink(new LinkInfoImpl(
-                configuration, LinkInfoImpl.CONTEXT_MEMBER, enumConstant.type())));
+        Content enumConstantLink = writer.getLink(new LinkInfoImpl(
+                configuration, LinkInfoImpl.Kind.MEMBER, enumConstant.type()));
         pre.addContent(enumConstantLink);
         pre.addContent(" ");
         if (configuration.linksource) {
@@ -182,8 +182,8 @@
     /**
      * {@inheritDoc}
      */
-    public String getCaption() {
-        return configuration.getText("doclet.Enum_Constants");
+    public Content getCaption() {
+        return configuration.getResource("doclet.Enum_Constants");
     }
 
     /**
@@ -220,10 +220,10 @@
     /**
      * {@inheritDoc}
      */
-    protected void addSummaryLink(int context, ClassDoc cd, ProgramElementDoc member,
+    protected void addSummaryLink(LinkInfoImpl.Kind context, ClassDoc cd, ProgramElementDoc member,
             Content tdSummary) {
-        Content strong = HtmlTree.STRONG(new RawHtml(
-                writer.getDocLink(context, (MemberDoc) member, member.name(), false)));
+        Content strong = HtmlTree.STRONG(
+                writer.getDocLink(context, (MemberDoc) member, member.name(), false));
         Content code = HtmlTree.CODE(strong);
         tdSummary.addContent(code);
     }
@@ -254,7 +254,7 @@
      * {@inheritDoc}
      */
     protected Content getDeprecatedLink(ProgramElementDoc member) {
-        return writer.getDocLink(LinkInfoImpl.CONTEXT_MEMBER,
+        return writer.getDocLink(LinkInfoImpl.Kind.MEMBER,
                 (MemberDoc) member, ((FieldDoc)member).qualifiedName());
     }
 
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java
index dc55158..4f1dbbd 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -102,8 +102,8 @@
         Content pre = new HtmlTree(HtmlTag.PRE);
         writer.addAnnotationInfo(field, pre);
         addModifiers(field, pre);
-        Content fieldlink = new RawHtml(writer.getLink(new LinkInfoImpl(
-                configuration, LinkInfoImpl.CONTEXT_MEMBER, field.type())));
+        Content fieldlink = writer.getLink(new LinkInfoImpl(
+                configuration, LinkInfoImpl.Kind.MEMBER, field.type()));
         pre.addContent(fieldlink);
         pre.addContent(" ");
         if (configuration.linksource) {
@@ -132,12 +132,12 @@
                     (! (holder.isPublic() || Util.isLinkable(holder, configuration)))) {
                 writer.addInlineComment(field, fieldDocTree);
             } else {
-                Content link = new RawHtml(
-                        writer.getDocLink(LinkInfoImpl.CONTEXT_FIELD_DOC_COPY,
+                Content link =
+                        writer.getDocLink(LinkInfoImpl.Kind.FIELD_DOC_COPY,
                         holder, field,
                         holder.isIncluded() ?
                             holder.typeName() : holder.qualifiedTypeName(),
-                            false));
+                            false);
                 Content codeLink = HtmlTree.CODE(link);
                 Content strong = HtmlTree.STRONG(holder.isClass()?
                    writer.descfrmClassLabel : writer.descfrmInterfaceLabel);
@@ -203,8 +203,8 @@
     /**
      * {@inheritDoc}
      */
-    public String getCaption() {
-        return configuration.getText("doclet.Fields");
+    public Content getCaption() {
+        return configuration.getResource("doclet.Fields");
     }
 
     /**
@@ -239,8 +239,8 @@
      * {@inheritDoc}
      */
     public void addInheritedSummaryLabel(ClassDoc cd, Content inheritedTree) {
-        Content classLink = new RawHtml(writer.getPreQualifiedClassLink(
-                LinkInfoImpl.CONTEXT_MEMBER, cd, false));
+        Content classLink = writer.getPreQualifiedClassLink(
+                LinkInfoImpl.Kind.MEMBER, cd, false);
         Content label = new StringContent(cd.isClass() ?
             configuration.getText("doclet.Fields_Inherited_From_Class") :
             configuration.getText("doclet.Fields_Inherited_From_Interface"));
@@ -254,10 +254,10 @@
     /**
      * {@inheritDoc}
      */
-    protected void addSummaryLink(int context, ClassDoc cd, ProgramElementDoc member,
+    protected void addSummaryLink(LinkInfoImpl.Kind context, ClassDoc cd, ProgramElementDoc member,
             Content tdSummary) {
-        Content strong = HtmlTree.STRONG(new RawHtml(
-                writer.getDocLink(context, cd , (MemberDoc) member, member.name(), false)));
+        Content strong = HtmlTree.STRONG(
+                writer.getDocLink(context, cd , (MemberDoc) member, member.name(), false));
         Content code = HtmlTree.CODE(strong);
         tdSummary.addContent(code);
     }
@@ -267,9 +267,9 @@
      */
     protected void addInheritedSummaryLink(ClassDoc cd,
             ProgramElementDoc member, Content linksTree) {
-        linksTree.addContent(new RawHtml(
-                writer.getDocLink(LinkInfoImpl.CONTEXT_MEMBER, cd, (MemberDoc)member,
-                member.name(), false)));
+        linksTree.addContent(
+                writer.getDocLink(LinkInfoImpl.Kind.MEMBER, cd, (MemberDoc)member,
+                member.name(), false));
     }
 
     /**
@@ -284,7 +284,7 @@
      * {@inheritDoc}
      */
     protected Content getDeprecatedLink(ProgramElementDoc member) {
-        return writer.getDocLink(LinkInfoImpl.CONTEXT_MEMBER,
+        return writer.getDocLink(LinkInfoImpl.Kind.MEMBER,
                 (MemberDoc) member, ((FieldDoc)member).qualifiedName());
     }
 
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java
index b853cea..3d483cd 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java
@@ -121,7 +121,7 @@
                 getResource("doclet.Frame_Alert"));
         noframes.addContent(noframesHead);
         Content p = HtmlTree.P(getResource("doclet.Frame_Warning_Message",
-                getHyperLinkString(configuration.topFile,
+                getHyperLink(configuration.topFile,
                 configuration.getText("doclet.Non_Frame_Version"))));
         noframes.addContent(p);
         contentTree.addContent(noframes);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java
index 9d14671..2884d3b 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -113,7 +113,7 @@
                 getResource("doclet.Overview"));
             Content liOverview = HtmlTree.LI(HtmlStyle.blockList, overviewHeading);
             Content line3 = getResource("doclet.Help_line_3",
-                    getHyperLinkString(DocPaths.OVERVIEW_SUMMARY,
+                    getHyperLink(DocPaths.OVERVIEW_SUMMARY,
                     configuration.getText("doclet.Overview")));
             Content overviewPara = HtmlTree.P(line3);
             liOverview.addContent(overviewPara);
@@ -234,8 +234,9 @@
                     getResource("doclet.Help_line_16"));
             Content liTree = HtmlTree.LI(HtmlStyle.blockList, treeHead);
             Content line17 = getResource("doclet.Help_line_17_with_tree_link",
-                    getHyperLinkString(DocPaths.OVERVIEW_TREE,
-                    configuration.getText("doclet.Class_Hierarchy")));
+                    getHyperLink(DocPaths.OVERVIEW_TREE,
+                    configuration.getText("doclet.Class_Hierarchy")),
+                    HtmlTree.CODE(new StringContent("java.lang.Object")));
             Content treePara = HtmlTree.P(line17);
             liTree.addContent(treePara);
             HtmlTree tul = new HtmlTree(HtmlTag.UL);
@@ -252,19 +253,19 @@
                     getResource("doclet.Deprecated_API"));
             Content liDeprecated = HtmlTree.LI(HtmlStyle.blockList, dHead);
             Content line20 = getResource("doclet.Help_line_20_with_deprecated_api_link",
-                    getHyperLinkString(DocPaths.DEPRECATED_LIST,
+                    getHyperLink(DocPaths.DEPRECATED_LIST,
                     configuration.getText("doclet.Deprecated_API")));
             Content dPara = HtmlTree.P(line20);
             liDeprecated.addContent(dPara);
             ul.addContent(liDeprecated);
         }
         if (configuration.createindex) {
-            String indexlink;
+            Content indexlink;
             if (configuration.splitindex) {
-                indexlink = getHyperLinkString(DocPaths.INDEX_FILES.resolve(DocPaths.indexN(1)),
+                indexlink = getHyperLink(DocPaths.INDEX_FILES.resolve(DocPaths.indexN(1)),
                         configuration.getText("doclet.Index"));
             } else {
-                indexlink = getHyperLinkString(DocPaths.INDEX_ALL,
+                indexlink = getHyperLink(DocPaths.INDEX_ALL,
                         configuration.getText("doclet.Index"));
             }
             Content indexHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
@@ -293,7 +294,7 @@
                 getResource("doclet.All_Classes"));
         Content liAllClasses = HtmlTree.LI(HtmlStyle.blockList, allclassesHead);
         Content line27 = getResource("doclet.Help_line_27",
-                getHyperLinkString(DocPaths.ALLCLASSES_NOFRAME,
+                getHyperLink(DocPaths.ALLCLASSES_NOFRAME,
                 configuration.getText("doclet.All_Classes")));
         Content allclassesPara = HtmlTree.P(line27);
         liAllClasses.addContent(allclassesPara);
@@ -309,7 +310,7 @@
                 getResource("doclet.Constants_Summary"));
         Content liConst = HtmlTree.LI(HtmlStyle.blockList, constHead);
         Content line29 = getResource("doclet.Help_line_29",
-                getHyperLinkString(DocPaths.CONSTANT_VALUES,
+                getHyperLink(DocPaths.CONSTANT_VALUES,
                 configuration.getText("doclet.Constants_Summary")));
         Content constPara = HtmlTree.P(line29);
         liConst.addContent(constPara);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
index d30e804..ba62e7c 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
@@ -75,11 +75,6 @@
     public final DocPath filename;
 
     /**
-     * The display length used for indentation while generating the class page.
-     */
-    public int displayLength = 0;
-
-    /**
      * The global configuration information for this run.
      */
     public final ConfigurationImpl configuration;
@@ -251,15 +246,11 @@
         if (doc instanceof MethodDoc) {
             addMethodInfo((MethodDoc) doc, dl);
         }
-        TagletOutputImpl output = new TagletOutputImpl("");
+        Content output = new ContentBuilder();
         TagletWriter.genTagOuput(configuration.tagletManager, doc,
-            configuration.tagletManager.getCustomTags(doc),
+            configuration.tagletManager.getCustomTaglets(doc),
                 getTagletWriterInstance(false), output);
-        String outputString = output.toString().trim();
-        if (!outputString.isEmpty()) {
-            Content resultString = new RawHtml(outputString);
-            dl.addContent(resultString);
-        }
+        dl.addContent(output);
         htmltree.addContent(dl);
     }
 
@@ -271,11 +262,11 @@
      * @return true if there are tags to be printed else return false.
      */
     protected boolean hasSerializationOverviewTags(FieldDoc field) {
-        TagletOutputImpl output = new TagletOutputImpl("");
+        Content output = new ContentBuilder();
         TagletWriter.genTagOuput(configuration.tagletManager, field,
-            configuration.tagletManager.getCustomTags(field),
+            configuration.tagletManager.getCustomTaglets(field),
                 getTagletWriterInstance(false), output);
-        return (!output.toString().trim().isEmpty());
+        return !output.isEmpty();
     }
 
     /**
@@ -359,7 +350,7 @@
             int profileValue) {
         if(classes.length > 0) {
             Arrays.sort(classes);
-            Content caption = getTableCaption(label);
+            Content caption = getTableCaption(new RawHtml(label));
             Content table = HtmlTree.TABLE(HtmlStyle.packageSummary, 0, 3, 0,
                     tableSummary, caption);
             table.addContent(getSummaryTableHeader(tableHeader, "col"));
@@ -372,9 +363,8 @@
                     !configuration.isGeneratedDoc(classes[i])) {
                     continue;
                 }
-                Content classContent = new RawHtml(getLink(new LinkInfoImpl(
-                        configuration, LinkInfoImpl.CONTEXT_PACKAGE, classes[i],
-                        false)));
+                Content classContent = getLink(new LinkInfoImpl(
+                        configuration, LinkInfoImpl.Kind.PACKAGE, classes[i]));
                 Content tdClass = HtmlTree.TD(HtmlStyle.colFirst, classContent);
                 HtmlTree tr = HtmlTree.TR(tdClass);
                 if (i%2 == 0)
@@ -879,8 +869,7 @@
      * @param rawText the caption for the table which could be raw Html
      * @return a content tree for the caption
      */
-    public Content getTableCaption(String rawText) {
-        Content title = new RawHtml(rawText);
+    public Content getTableCaption(Content title) {
         Content captionSpan = HtmlTree.SPAN(title);
         Content space = getSpace();
         Content tabSpan = HtmlTree.SPAN(HtmlStyle.tabEnd, space);
@@ -948,7 +937,7 @@
             String tableSummary, String[] tableHeader, Content contentTree) {
         if (deprPkgs.size() > 0) {
             Content table = HtmlTree.TABLE(0, 3, 0, tableSummary,
-                    getTableCaption(configuration.getText(headingKey)));
+                    getTableCaption(configuration.getResource(headingKey)));
             table.addContent(getSummaryTableHeader(tableHeader, "col"));
             Content tbody = new HtmlTree(HtmlTag.TBODY);
             for (int i = 0; i < deprPkgs.size(); i++) {
@@ -1001,46 +990,10 @@
      *
      * @param pkg the package to link to.
      * @param label the label for the link.
-     * @param isStrong true if the label should be strong.
-     * @return the link to the given package.
+     * @return a content tree for the package link.
      */
-    public String getPackageLinkString(PackageDoc pkg, String label,
-                                 boolean isStrong) {
-        return getPackageLinkString(pkg, label, isStrong, "");
-    }
-
-    /**
-     * Return the link to the given package.
-     *
-     * @param pkg the package to link to.
-     * @param label the label for the link.
-     * @param isStrong true if the label should be strong.
-     * @param style  the font of the package link label.
-     * @return the link to the given package.
-     */
-    public String getPackageLinkString(PackageDoc pkg, String label, boolean isStrong,
-            String style) {
-        boolean included = pkg != null && pkg.isIncluded();
-        if (! included) {
-            PackageDoc[] packages = configuration.packages;
-            for (int i = 0; i < packages.length; i++) {
-                if (packages[i].equals(pkg)) {
-                    included = true;
-                    break;
-                }
-            }
-        }
-        if (included || pkg == null) {
-            return getHyperLinkString(pathString(pkg, DocPaths.PACKAGE_SUMMARY),
-                                label, isStrong, style);
-        } else {
-            DocLink crossPkgLink = getCrossPackageLink(Util.getPackageName(pkg));
-            if (crossPkgLink != null) {
-                return getHyperLinkString(crossPkgLink, label, isStrong, style);
-            } else {
-                return label;
-            }
-        }
+    public Content getPackageLink(PackageDoc pkg, String label) {
+        return getPackageLink(pkg, new StringContent(label));
     }
 
     /**
@@ -1074,9 +1027,9 @@
         }
     }
 
-    public String italicsClassName(ClassDoc cd, boolean qual) {
-        String name = (qual)? cd.qualifiedName(): cd.name();
-        return (cd.isInterface())?  italicsText(name): name;
+    public Content italicsClassName(ClassDoc cd, boolean qual) {
+        Content name = new StringContent((qual)? cd.qualifiedName(): cd.name());
+        return (cd.isInterface())?  HtmlTree.I(name): name;
     }
 
     /**
@@ -1109,11 +1062,9 @@
      *
      * @return the link for the given class.
      */
-    public String getLink(LinkInfoImpl linkInfo) {
+    public Content getLink(LinkInfoImpl linkInfo) {
         LinkFactoryImpl factory = new LinkFactoryImpl(this);
-        String link = factory.getLinkOutput(linkInfo).toString();
-        displayLength += linkInfo.displayLength;
-        return link;
+        return factory.getLink(linkInfo);
     }
 
     /**
@@ -1122,9 +1073,9 @@
      * @param linkInfo the information about the link.
      * @return the type for the given class.
      */
-    public String getTypeParameterLinks(LinkInfoImpl linkInfo) {
+    public Content getTypeParameterLinks(LinkInfoImpl linkInfo) {
         LinkFactoryImpl factory = new LinkFactoryImpl(this);
-        return factory.getTypeParameterLinks(linkInfo, false).toString();
+        return factory.getTypeParameterLinks(linkInfo, false);
     }
 
     /*************************************************************
@@ -1141,8 +1092,8 @@
      * @param style the style of the link.
      * @param code true if the label should be code font.
      */
-    public String getCrossClassLink(String qualifiedClassName, String refMemName,
-                                    String label, boolean strong, String style,
+    public Content getCrossClassLink(String qualifiedClassName, String refMemName,
+                                    Content label, boolean strong, String style,
                                     boolean code) {
         String className = "";
         String packageName = qualifiedClassName == null ? "" : qualifiedClassName;
@@ -1150,7 +1101,9 @@
         while ((periodIndex = packageName.lastIndexOf('.')) != -1) {
             className = packageName.substring(periodIndex + 1, packageName.length()) +
                 (className.length() > 0 ? "." + className : "");
-            String defaultLabel = code ? codeText(className) : className;
+            Content defaultLabel = new StringContent(className);
+            if (code)
+                defaultLabel = HtmlTree.CODE(defaultLabel);
             packageName = packageName.substring(0, periodIndex);
             if (getCrossPackageLink(packageName) != null) {
                 //The package exists in external documentation, so link to the external
@@ -1160,10 +1113,8 @@
                 //have to assume that it does.
                 DocLink link = configuration.extern.getExternalLink(packageName, pathToRoot,
                                 className + ".html", refMemName);
-                return getHyperLinkString(link,
-                    (label == null) || label.length() == 0 ? defaultLabel : label,
-
-
+                return getHyperLink(link,
+                    (label == null) || label.isEmpty() ? defaultLabel : label,
                     strong, style,
                     configuration.getText("doclet.Href_Class_Or_Interface_Title", packageName),
                     "");
@@ -1191,9 +1142,9 @@
      * @param cd the class doc to link to
      * @return a content tree for the link
      */
-    public Content getQualifiedClassLink(int context, ClassDoc cd) {
-        return new RawHtml(getLink(new LinkInfoImpl(configuration, context, cd,
-                configuration.getClassName(cd), "")));
+    public Content getQualifiedClassLink(LinkInfoImpl.Kind context, ClassDoc cd) {
+        return getLink(new LinkInfoImpl(configuration, context, cd)
+                .label(configuration.getClassName(cd)));
     }
 
     /**
@@ -1203,7 +1154,7 @@
      * @param cd the class doc to link to
      * @param contentTree the content tree to which the link will be added
      */
-    public void addPreQualifiedClassLink(int context, ClassDoc cd, Content contentTree) {
+    public void addPreQualifiedClassLink(LinkInfoImpl.Kind context, ClassDoc cd, Content contentTree) {
         addPreQualifiedClassLink(context, cd, false, contentTree);
     }
 
@@ -1216,15 +1167,15 @@
      * @param isStrong true if the link should be strong.
      * @return the link with the package portion of the label in plain text.
      */
-    public String getPreQualifiedClassLink(int context,
+    public Content getPreQualifiedClassLink(LinkInfoImpl.Kind context,
             ClassDoc cd, boolean isStrong) {
-        String classlink = "";
+        ContentBuilder classlink = new ContentBuilder();
         PackageDoc pd = cd.containingPackage();
-        if(pd != null && ! configuration.shouldExcludeQualifier(pd.name())) {
-            classlink = getPkgName(cd);
+        if (pd != null && ! configuration.shouldExcludeQualifier(pd.name())) {
+            classlink.addContent(getPkgName(cd));
         }
-        classlink += getLink(new LinkInfoImpl(configuration,
-                context, cd, cd.name(), isStrong));
+        classlink.addContent(getLink(new LinkInfoImpl(configuration,
+                context, cd).label(cd.name()).strong(isStrong)));
         return classlink;
     }
 
@@ -1238,14 +1189,14 @@
      * @param isStrong true if the link should be strong
      * @param contentTree the content tree to which the link with be added
      */
-    public void addPreQualifiedClassLink(int context,
+    public void addPreQualifiedClassLink(LinkInfoImpl.Kind context,
             ClassDoc cd, boolean isStrong, Content contentTree) {
         PackageDoc pd = cd.containingPackage();
         if(pd != null && ! configuration.shouldExcludeQualifier(pd.name())) {
             contentTree.addContent(getPkgName(cd));
         }
-        contentTree.addContent(new RawHtml(getLink(new LinkInfoImpl(configuration,
-                context, cd, cd.name(), isStrong))));
+        contentTree.addContent(getLink(new LinkInfoImpl(configuration,
+                context, cd).label(cd.name()).strong(isStrong)));
     }
 
     /**
@@ -1256,7 +1207,7 @@
      * @param cd the class to link to
      * @param contentTree the content tree to which the link with be added
      */
-    public void addPreQualifiedStrongClassLink(int context, ClassDoc cd, Content contentTree) {
+    public void addPreQualifiedStrongClassLink(LinkInfoImpl.Kind context, ClassDoc cd, Content contentTree) {
         addPreQualifiedClassLink(context, cd, true, contentTree);
     }
 
@@ -1268,8 +1219,9 @@
      * @param label the label for the link
      * @return a content tree for the doc link
      */
-    public Content getDocLink(int context, MemberDoc doc, String label) {
-        return getDocLink(context, doc.containingClass(), doc, label);
+    public Content getDocLink(LinkInfoImpl.Kind context, MemberDoc doc, String label) {
+        return getDocLink(context, doc.containingClass(), doc,
+                new StringContent(label));
     }
 
     /**
@@ -1281,8 +1233,8 @@
      * @param strong true if the link should be strong.
      * @return the link for the given member.
      */
-    public String getDocLink(int context, MemberDoc doc, String label,
-                boolean strong) {
+    public Content getDocLink(LinkInfoImpl.Kind context, MemberDoc doc, String label,
+            boolean strong) {
         return getDocLink(context, doc.containingClass(), doc, label, strong);
     }
 
@@ -1298,8 +1250,12 @@
      * @param strong true if the link should be strong.
      * @return the link for the given member.
      */
-    public String getDocLink(int context, ClassDoc classDoc, MemberDoc doc,
-        String label, boolean strong) {
+    public Content getDocLink(LinkInfoImpl.Kind context, ClassDoc classDoc, MemberDoc doc,
+            String label, boolean strong) {
+        return getDocLink(context, classDoc, doc, label, strong, false);
+    }
+    public Content getDocLink(LinkInfoImpl.Kind context, ClassDoc classDoc, MemberDoc doc,
+            Content label, boolean strong) {
         return getDocLink(context, classDoc, doc, label, strong, false);
     }
 
@@ -1316,18 +1272,28 @@
      * @param isProperty true if the doc parameter is a JavaFX property.
      * @return the link for the given member.
      */
-    public String getDocLink(int context, ClassDoc classDoc, MemberDoc doc,
-        String label, boolean strong, boolean isProperty) {
+    public Content getDocLink(LinkInfoImpl.Kind context, ClassDoc classDoc, MemberDoc doc,
+            String label, boolean strong, boolean isProperty) {
+        return getDocLink(context, classDoc, doc, new StringContent(check(label)), strong, isProperty);
+    }
+
+    String check(String s) {
+        if (s.matches(".*[&<>].*"))throw new IllegalArgumentException(s);
+        return s;
+    }
+
+    public Content getDocLink(LinkInfoImpl.Kind context, ClassDoc classDoc, MemberDoc doc,
+            Content label, boolean strong, boolean isProperty) {
         if (! (doc.isIncluded() ||
             Util.isLinkable(classDoc, configuration))) {
             return label;
         } else if (doc instanceof ExecutableMemberDoc) {
             ExecutableMemberDoc emd = (ExecutableMemberDoc)doc;
-            return getLink(new LinkInfoImpl(configuration, context, classDoc,
-                getAnchor(emd, isProperty), label, strong));
+            return getLink(new LinkInfoImpl(configuration, context, classDoc)
+                .label(label).where(getAnchor(emd, isProperty)).strong(strong));
         } else if (doc instanceof MemberDoc) {
-            return getLink(new LinkInfoImpl(configuration, context, classDoc,
-                doc.name(), label, strong));
+            return getLink(new LinkInfoImpl(configuration, context, classDoc)
+                .label(label).where(doc.name()).strong(strong));
         } else {
             return label;
         }
@@ -1344,20 +1310,20 @@
      * @param label the label for the link
      * @return the link for the given member
      */
-    public Content getDocLink(int context, ClassDoc classDoc, MemberDoc doc,
-        String label) {
+    public Content getDocLink(LinkInfoImpl.Kind context, ClassDoc classDoc, MemberDoc doc,
+            Content label) {
         if (! (doc.isIncluded() ||
             Util.isLinkable(classDoc, configuration))) {
-            return new StringContent(label);
+            return label;
         } else if (doc instanceof ExecutableMemberDoc) {
-            ExecutableMemberDoc emd = (ExecutableMemberDoc)doc;
-            return new RawHtml(getLink(new LinkInfoImpl(configuration, context, classDoc,
-                getAnchor(emd), label, false)));
+            ExecutableMemberDoc emd = (ExecutableMemberDoc) doc;
+            return getLink(new LinkInfoImpl(configuration, context, classDoc)
+                .label(label).where(getAnchor(emd)));
         } else if (doc instanceof MemberDoc) {
-            return new RawHtml(getLink(new LinkInfoImpl(configuration, context, classDoc,
-                doc.name(), label, false)));
+            return getLink(new LinkInfoImpl(configuration, context, classDoc)
+                .label(label).where(doc.name()));
         } else {
-            return new StringContent(label);
+            return label;
         }
     }
 
@@ -1385,24 +1351,24 @@
         return emd.name() + signatureParsed.toString();
     }
 
-    public String seeTagToString(SeeTag see) {
+    public Content seeTagToContent(SeeTag see) {
         String tagName = see.name();
         if (! (tagName.startsWith("@link") || tagName.equals("@see"))) {
-            return "";
+            return new ContentBuilder();
         }
 
         String seetext = replaceDocRootDir(see.text());
 
         //Check if @see is an href or "string"
         if (seetext.startsWith("<") || seetext.startsWith("\"")) {
-            return seetext;
+            return new RawHtml(seetext);
         }
 
         boolean plain = tagName.equalsIgnoreCase("@linkplain");
-        String label = plainOrCodeText(plain, see.label());
+        Content label = plainOrCode(plain, new RawHtml(see.label()));
 
         //The text from the @see tag.  We will output this text when a label is not specified.
-        String text = plainOrCodeText(plain, seetext);
+        Content text = plainOrCode(plain, new RawHtml(seetext));
 
         ClassDoc refClass = see.referencedClass();
         String refClassName = see.referencedClassName();
@@ -1415,16 +1381,16 @@
             if (refPackage != null && refPackage.isIncluded()) {
                 //@see is referencing an included package
                 if (label.isEmpty())
-                    label = plainOrCodeText(plain, refPackage.name());
-                return getPackageLinkString(refPackage, label, false);
+                    label = plainOrCode(plain, new StringContent(refPackage.name()));
+                return getPackageLink(refPackage, label);
             } else {
                 //@see is not referencing an included class or package.  Check for cross links.
-                String classCrossLink;
+                Content classCrossLink;
                 DocLink packageCrossLink = getCrossPackageLink(refClassName);
                 if (packageCrossLink != null) {
                     //Package cross link found
-                    return getHyperLinkString(packageCrossLink,
-                        (label.isEmpty() ? text : label), false);
+                    return getHyperLink(packageCrossLink,
+                        (label.isEmpty() ? text : label));
                 } else if ((classCrossLink = getCrossClassLink(refClassName,
                         refMemName, label, false, "", !plain)) != null) {
                     //Class cross link found (possibly to a member in the class)
@@ -1439,9 +1405,10 @@
         } else if (refMemName == null) {
             // Must be a class reference since refClass is not null and refMemName is null.
             if (label.isEmpty()) {
-                label = plainOrCodeText(plain, refClass.name());
+                label = plainOrCode(plain, new StringContent(refClass.name()));
             }
-            return getLink(new LinkInfoImpl(configuration, refClass, label));
+            return getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.DEFAULT, refClass)
+                    .label(label));
         } else if (refMem == null) {
             // Must be a member reference since refClass is not null and refMemName is not null.
             // However, refMem is null, so this referenced member does not exist.
@@ -1478,15 +1445,15 @@
                 }
             }
 
-            text = plainOrCodeText(plain, Util.escapeHtmlChars(refMemName));
+            text = plainOrCode(plain, new StringContent(refMemName));
 
-            return getDocLink(LinkInfoImpl.CONTEXT_SEE_TAG, containing,
+            return getDocLink(LinkInfoImpl.Kind.SEE_TAG, containing,
                 refMem, (label.isEmpty() ? text: label), false);
         }
     }
 
-    private String plainOrCodeText(boolean plain, String text) {
-        return (plain || text.isEmpty()) ? text : codeText(text);
+    private Content plainOrCode(boolean plain, Content body) {
+        return (plain || body.isEmpty()) ? body : HtmlTree.CODE(body);
     }
 
     /**
@@ -1497,7 +1464,7 @@
      * @param htmltree the content tree to which the comment will be added
      */
     public void addInlineComment(Doc doc, Tag tag, Content htmltree) {
-        addCommentTags(doc, tag.inlineTags(), false, false, htmltree);
+        addCommentTags(doc, tag, tag.inlineTags(), false, false, htmltree);
     }
 
     /**
@@ -1557,11 +1524,26 @@
      */
     private void addCommentTags(Doc doc, Tag[] tags, boolean depr,
             boolean first, Content htmltree) {
+        addCommentTags(doc, null, tags, depr, first, htmltree);
+    }
+
+    /**
+     * Adds the comment tags.
+     *
+     * @param doc the doc for which the comment tags will be generated
+     * @param holderTag the block tag context for the inline tags
+     * @param tags the first sentence tags for the doc
+     * @param depr true if it is deprecated
+     * @param first true if the first sentence tags should be added
+     * @param htmltree the documentation tree to which the comment tags will be added
+     */
+    private void addCommentTags(Doc doc, Tag holderTag, Tag[] tags, boolean depr,
+            boolean first, Content htmltree) {
         if(configuration.nocomment){
             return;
         }
         Content div;
-        Content result = new RawHtml(commentTagsToString(null, doc, tags, first));
+        Content result = commentTagsToContent(null, doc, tags, first);
         if (depr) {
             Content italic = HtmlTree.I(result);
             div = HtmlTree.DIV(HtmlStyle.block, italic);
@@ -1588,9 +1570,9 @@
      *               present in the text of interest for this doc
      * @param isFirstSentence  true if text is first sentence
      */
-    public String commentTagsToString(Tag holderTag, Doc doc, Tag[] tags,
+    public Content commentTagsToContent(Tag holderTag, Doc doc, Tag[] tags,
             boolean isFirstSentence) {
-        StringBuilder result = new StringBuilder();
+        Content result = new ContentBuilder();
         boolean textTagChange = false;
         // Array of all possible inline tags for this javadoc run
         configuration.tagletManager.checkTags(doc, tags, true);
@@ -1598,14 +1580,15 @@
             Tag tagelem = tags[i];
             String tagName = tagelem.name();
             if (tagelem instanceof SeeTag) {
-                result.append(seeTagToString((SeeTag)tagelem));
+                result.addContent(seeTagToContent((SeeTag) tagelem));
             } else if (! tagName.equals("Text")) {
-                int originalLength = result.length();
-                TagletOutput output = TagletWriter.getInlineTagOuput(
+                boolean wasEmpty = result.isEmpty();
+                Content output = TagletWriter.getInlineTagOuput(
                     configuration.tagletManager, holderTag,
                     tagelem, getTagletWriterInstance(isFirstSentence));
-                result.append(output == null ? "" : output.toString());
-                if (originalLength == 0 && isFirstSentence && tagelem.name().equals("@inheritDoc") && result.length() > 0) {
+                if (output != null)
+                    result.addContent(output);
+                if (wasEmpty && isFirstSentence && tagelem.name().equals("@inheritDoc") && !result.isEmpty()) {
                     break;
                 } else if (configuration.docrootparent.length() > 0 &&
                         tagelem.name().equals("@docRoot") &&
@@ -1637,17 +1620,11 @@
                 if (isFirstSentence) {
                     text = removeNonInlineHtmlTags(text);
                 }
-                StringTokenizer lines = new StringTokenizer(text, "\r\n", true);
-                StringBuilder textBuff = new StringBuilder();
-                while (lines.hasMoreTokens()) {
-                    StringBuilder line = new StringBuilder(lines.nextToken());
-                    Util.replaceTabs(configuration, line);
-                    textBuff.append(line.toString());
-                }
-                result.append(textBuff);
+                text = Util.replaceTabs(configuration, text);
+                result.addContent(new RawHtml(text));
             }
         }
-        return result.toString();
+        return result;
     }
 
     /**
@@ -1749,60 +1726,55 @@
         return text;
     }
 
-    public String removeNonInlineHtmlTags(String text) {
-        if (text.indexOf('<') < 0) {
-            return text;
+    static final Set<String> blockTags = new HashSet<String>();
+    static {
+        for (HtmlTag t: HtmlTag.values()) {
+            if (t.blockType == HtmlTag.BlockType.BLOCK)
+                blockTags.add(t.value);
         }
-        String noninlinetags[] = { "<ul>", "</ul>", "<ol>", "</ol>",
-                "<dl>", "</dl>", "<table>", "</table>",
-                "<tr>", "</tr>", "<td>", "</td>",
-                "<th>", "</th>", "<p>", "</p>",
-                "<li>", "</li>", "<dd>", "</dd>",
-                "<dir>", "</dir>", "<dt>", "</dt>",
-                "<h1>", "</h1>", "<h2>", "</h2>",
-                "<h3>", "</h3>", "<h4>", "</h4>",
-                "<h5>", "</h5>", "<h6>", "</h6>",
-                "<pre>", "</pre>", "<menu>", "</menu>",
-                "<listing>", "</listing>", "<hr>",
-                "<blockquote>", "</blockquote>",
-                "<center>", "</center>",
-                "<UL>", "</UL>", "<OL>", "</OL>",
-                "<DL>", "</DL>", "<TABLE>", "</TABLE>",
-                "<TR>", "</TR>", "<TD>", "</TD>",
-                "<TH>", "</TH>", "<P>", "</P>",
-                "<LI>", "</LI>", "<DD>", "</DD>",
-                "<DIR>", "</DIR>", "<DT>", "</DT>",
-                "<H1>", "</H1>", "<H2>", "</H2>",
-                "<H3>", "</H3>", "<H4>", "</H4>",
-                "<H5>", "</H5>", "<H6>", "</H6>",
-                "<PRE>", "</PRE>", "<MENU>", "</MENU>",
-                "<LISTING>", "</LISTING>", "<HR>",
-                "<BLOCKQUOTE>", "</BLOCKQUOTE>",
-                "<CENTER>", "</CENTER>"
-        };
-        for (int i = 0; i < noninlinetags.length; i++) {
-            text = replace(text, noninlinetags[i], "");
-        }
-        return text;
     }
 
-    public String replace(String text, String tobe, String by) {
-        while (true) {
-            int startindex = text.indexOf(tobe);
-            if (startindex < 0) {
-                return text;
-            }
-            int endindex = startindex + tobe.length();
-            StringBuilder replaced = new StringBuilder();
-            if (startindex > 0) {
-                replaced.append(text.substring(0, startindex));
-            }
-            replaced.append(by);
-            if (text.length() > endindex) {
-                replaced.append(text.substring(endindex));
-            }
-            text = replaced.toString();
+    public static String removeNonInlineHtmlTags(String text) {
+        final int len = text.length();
+
+        int startPos = 0;                     // start of text to copy
+        int lessThanPos = text.indexOf('<');  // position of latest '<'
+        if (lessThanPos < 0) {
+            return text;
         }
+
+        StringBuilder result = new StringBuilder();
+    main: while (lessThanPos != -1) {
+            int currPos = lessThanPos + 1;
+            if (currPos == len)
+                break;
+            char ch = text.charAt(currPos);
+            if (ch == '/') {
+                if (++currPos == len)
+                    break;
+                ch = text.charAt(currPos);
+            }
+            int tagPos = currPos;
+            while (isHtmlTagLetterOrDigit(ch)) {
+                if (++currPos == len)
+                    break main;
+                ch = text.charAt(currPos);
+            }
+            if (ch == '>' && blockTags.contains(text.substring(tagPos, currPos).toLowerCase())) {
+                result.append(text, startPos, lessThanPos);
+                startPos = currPos + 1;
+            }
+            lessThanPos = text.indexOf('<', currPos);
+        }
+        result.append(text.substring(startPos));
+
+        return result.toString();
+    }
+
+    private static boolean isHtmlTagLetterOrDigit(char ch) {
+        return ('a' <= ch && ch <= 'z') ||
+                ('A' <= ch && ch <= 'Z') ||
+                ('1' <= ch && ch <= '6');
     }
 
     /**
@@ -1906,7 +1878,7 @@
     }
 
     /**
-     * Adds the annotatation types for the given doc.
+     * Adds the annotation types for the given doc.
      *
      * @param indent the number of extra spaces to indent the annotations.
      * @param doc the doc to write annotations for.
@@ -1916,16 +1888,14 @@
      */
     private boolean addAnnotationInfo(int indent, Doc doc,
             AnnotationDesc[] descList, boolean lineBreak, Content htmltree) {
-        List<String> annotations = getAnnotations(indent, descList, lineBreak);
+        List<Content> annotations = getAnnotations(indent, descList, lineBreak);
         String sep ="";
-        if (annotations.size() == 0) {
+        if (annotations.isEmpty()) {
             return false;
         }
-        Content annotationContent;
-        for (Iterator<String> iter = annotations.iterator(); iter.hasNext();) {
+        for (Content annotation: annotations) {
             htmltree.addContent(sep);
-            annotationContent = new RawHtml(iter.next());
-            htmltree.addContent(annotationContent);
+            htmltree.addContent(annotation);
             sep = " ";
         }
         return true;
@@ -1941,7 +1911,7 @@
      * @return an array of strings representing the annotations being
      *         documented.
      */
-    private List<String> getAnnotations(int indent, AnnotationDesc[] descList, boolean linkBreak) {
+    private List<Content> getAnnotations(int indent, AnnotationDesc[] descList, boolean linkBreak) {
         return getAnnotations(indent, descList, linkBreak, true);
     }
 
@@ -1960,10 +1930,10 @@
      * @return an array of strings representing the annotations being
      *         documented.
      */
-    public List<String> getAnnotations(int indent, AnnotationDesc[] descList, boolean linkBreak,
+    public List<Content> getAnnotations(int indent, AnnotationDesc[] descList, boolean linkBreak,
             boolean isJava5DeclarationLocation) {
-        List<String> results = new ArrayList<String>();
-        StringBuilder annotation;
+        List<Content> results = new ArrayList<Content>();
+        ContentBuilder annotation;
         for (int i = 0; i < descList.length; i++) {
             AnnotationTypeDoc annotationDoc = descList[i].annotationType();
             // If an annotation is not documented, do not add it to the list. If
@@ -1980,10 +1950,10 @@
             if  (Util.isDeclarationAnnotation(annotationDoc, isJava5DeclarationLocation)) {
                 continue;
             }*/
-            annotation = new StringBuilder();
+            annotation = new ContentBuilder();
             isAnnotationDocumented = false;
             LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
-                LinkInfoImpl.CONTEXT_ANNOTATION, annotationDoc);
+                LinkInfoImpl.Kind.ANNOTATION, annotationDoc);
             AnnotationDesc.ElementValuePair[] pairs = descList[i].elementValues();
             // If the annotation is synthesized, do not print the container.
             if (descList[i].isSynthesized()) {
@@ -1999,8 +1969,8 @@
                     }
                     String sep = "";
                     for (AnnotationValue av : annotationTypeValues) {
-                        annotation.append(sep);
-                        annotation.append(annotationValueToString(av));
+                        annotation.addContent(sep);
+                        annotation.addContent(annotationValueToContent(av));
                         sep = " ";
                     }
                 }
@@ -2016,8 +1986,8 @@
                     annotationTypeValues.addAll(Arrays.asList(annotationArray));
                     String sep = "";
                     for (AnnotationValue av : annotationTypeValues) {
-                        annotation.append(sep);
-                        annotation.append(annotationValueToString(av));
+                        annotation.addContent(sep);
+                        annotation.addContent(annotationValueToContent(av));
                         sep = " ";
                     }
                 }
@@ -2032,8 +2002,8 @@
                 addAnnotations(annotationDoc, linkInfo, annotation, pairs,
                         indent, linkBreak);
             }
-            annotation.append(linkBreak ? DocletConstants.NL : "");
-            results.add(annotation.toString());
+            annotation.addContent(linkBreak ? DocletConstants.NL : "");
+            results.add(annotation);
         }
         return results;
     }
@@ -2049,26 +2019,26 @@
      * @param linkBreak if true, add new line between each member value
      */
     private void addAnnotations(AnnotationTypeDoc annotationDoc, LinkInfoImpl linkInfo,
-            StringBuilder annotation, AnnotationDesc.ElementValuePair[] pairs,
+            ContentBuilder annotation, AnnotationDesc.ElementValuePair[] pairs,
             int indent, boolean linkBreak) {
-        linkInfo.label = "@" + annotationDoc.name();
-        annotation.append(getLink(linkInfo));
+        linkInfo.label = new StringContent("@" + annotationDoc.name());
+        annotation.addContent(getLink(linkInfo));
         if (pairs.length > 0) {
-            annotation.append('(');
+            annotation.addContent("(");
             for (int j = 0; j < pairs.length; j++) {
                 if (j > 0) {
-                    annotation.append(",");
+                    annotation.addContent(",");
                     if (linkBreak) {
-                        annotation.append(DocletConstants.NL);
+                        annotation.addContent(DocletConstants.NL);
                         int spaces = annotationDoc.name().length() + 2;
                         for (int k = 0; k < (spaces + indent); k++) {
-                            annotation.append(' ');
+                            annotation.addContent(" ");
                         }
                     }
                 }
-                annotation.append(getDocLink(LinkInfoImpl.CONTEXT_ANNOTATION,
+                annotation.addContent(getDocLink(LinkInfoImpl.Kind.ANNOTATION,
                         pairs[j].element(), pairs[j].element().name(), false));
-                annotation.append('=');
+                annotation.addContent("=");
                 AnnotationValue annotationValue = pairs[j].value();
                 List<AnnotationValue> annotationTypeValues = new ArrayList<AnnotationValue>();
                 if (annotationValue.value() instanceof AnnotationValue[]) {
@@ -2078,17 +2048,17 @@
                 } else {
                     annotationTypeValues.add(annotationValue);
                 }
-                annotation.append(annotationTypeValues.size() == 1 ? "" : "{");
+                annotation.addContent(annotationTypeValues.size() == 1 ? "" : "{");
                 String sep = "";
                 for (AnnotationValue av : annotationTypeValues) {
-                    annotation.append(sep);
-                    annotation.append(annotationValueToString(av));
+                    annotation.addContent(sep);
+                    annotation.addContent(annotationValueToContent(av));
                     sep = ",";
                 }
-                annotation.append(annotationTypeValues.size() == 1 ? "" : "}");
+                annotation.addContent(annotationTypeValues.size() == 1 ? "" : "}");
                 isContainerDocumented = false;
             }
-            annotation.append(")");
+            annotation.addContent(")");
         }
     }
 
@@ -2123,34 +2093,34 @@
         return false;
     }
 
-    private String annotationValueToString(AnnotationValue annotationValue) {
+    private Content annotationValueToContent(AnnotationValue annotationValue) {
         if (annotationValue.value() instanceof Type) {
             Type type = (Type) annotationValue.value();
             if (type.asClassDoc() != null) {
                 LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
-                    LinkInfoImpl.CONTEXT_ANNOTATION, type);
-                    linkInfo.label = (type.asClassDoc().isIncluded() ?
-                        type.typeName() :
-                        type.qualifiedTypeName()) + type.dimension() + ".class";
+                    LinkInfoImpl.Kind.ANNOTATION, type);
+                linkInfo.label = new StringContent((type.asClassDoc().isIncluded() ?
+                    type.typeName() :
+                    type.qualifiedTypeName()) + type.dimension() + ".class");
                 return getLink(linkInfo);
             } else {
-                return type.typeName() + type.dimension() + ".class";
+                return new StringContent(type.typeName() + type.dimension() + ".class");
             }
         } else if (annotationValue.value() instanceof AnnotationDesc) {
-            List<String> list = getAnnotations(0,
+            List<Content> list = getAnnotations(0,
                 new AnnotationDesc[]{(AnnotationDesc) annotationValue.value()},
                     false);
-            StringBuilder buf = new StringBuilder();
-            for (String s: list) {
-                buf.append(s);
+            ContentBuilder buf = new ContentBuilder();
+            for (Content c: list) {
+                buf.addContent(c);
             }
-            return buf.toString();
+            return buf;
         } else if (annotationValue.value() instanceof MemberDoc) {
-            return getDocLink(LinkInfoImpl.CONTEXT_ANNOTATION,
+            return getDocLink(LinkInfoImpl.Kind.ANNOTATION,
                 (MemberDoc) annotationValue.value(),
                 ((MemberDoc) annotationValue.value()).name(), false);
          } else {
-            return annotationValue.toString();
+            return new StringContent(annotationValue.toString());
          }
     }
 
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java
index bc0e1de..8918889 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -46,7 +46,7 @@
  * @author Bhavesh Patel (Modified)
  */
 public class HtmlSerialFieldWriter extends FieldWriterImpl
-    implements SerializedFormWriter.SerialFieldWriter {
+        implements SerializedFormWriter.SerialFieldWriter {
     ProgramElementDoc[] members = null;
 
     private boolean printedOverallAnchor = false;
@@ -129,8 +129,8 @@
         if (fieldType == null) {
             pre.addContent(fieldTypeStr);
         } else {
-            Content fieldContent = new RawHtml(writer.getLink(new LinkInfoImpl(
-                    configuration, LinkInfoImpl.CONTEXT_SERIAL_MEMBER, fieldType)));
+            Content fieldContent = writer.getLink(new LinkInfoImpl(
+                    configuration, LinkInfoImpl.Kind.SERIAL_MEMBER, fieldType));
             pre.addContent(fieldContent);
         }
         pre.addContent(fieldDimensions + " ");
@@ -186,17 +186,13 @@
      * @param contentTree the tree to which the member tags info will be added
      */
     public void addMemberTags(FieldDoc field, Content contentTree) {
-        TagletOutputImpl output = new TagletOutputImpl("");
+        Content tagContent = new ContentBuilder();
         TagletWriter.genTagOuput(configuration.tagletManager, field,
-                configuration.tagletManager.getCustomTags(field),
-                writer.getTagletWriterInstance(false), output);
-        String outputString = output.toString().trim();
+                configuration.tagletManager.getCustomTaglets(field),
+                writer.getTagletWriterInstance(false), tagContent);
         Content dlTags = new HtmlTree(HtmlTag.DL);
-        if (!outputString.isEmpty()) {
-            Content tagContent = new RawHtml(outputString);
-            dlTags.addContent(tagContent);
-        }
-        contentTree.addContent(dlTags);
+        dlTags.addContent(tagContent);
+        contentTree.addContent(dlTags);  // TODO: what if empty?
     }
 
     /**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialMethodWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialMethodWriter.java
index d71b437..4e5da21 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialMethodWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialMethodWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -146,19 +146,15 @@
      * @param methodsContentTree the tree to which the member tags info will be added
      */
     public void addMemberTags(MethodDoc member, Content methodsContentTree) {
-        TagletOutputImpl output = new TagletOutputImpl("");
+        Content tagContent = new ContentBuilder();
         TagletManager tagletManager =
             configuration.tagletManager;
         TagletWriter.genTagOuput(tagletManager, member,
-            tagletManager.getSerializedFormTags(),
-            writer.getTagletWriterInstance(false), output);
-        String outputString = output.toString().trim();
+            tagletManager.getSerializedFormTaglets(),
+            writer.getTagletWriterInstance(false), tagContent);
         Content dlTags = new HtmlTree(HtmlTag.DL);
-        if (!outputString.isEmpty()) {
-            Content tagContent = new RawHtml(outputString);
-            dlTags.addContent(tagContent);
-        }
-        methodsContentTree.addContent(dlTags);
+        dlTags.addContent(tagContent);
+        methodsContentTree.addContent(dlTags);  // TODO: what if empty?
         MethodDoc method = member;
         if (method.name().compareTo("writeExternal") == 0
                 && method.tags("serialData").length == 0) {
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java
index e4346ea..abad36d 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java
@@ -28,6 +28,9 @@
 import java.util.List;
 
 import com.sun.javadoc.*;
+import com.sun.tools.doclets.formats.html.markup.ContentBuilder;
+import com.sun.tools.doclets.formats.html.markup.RawHtml;
+import com.sun.tools.doclets.formats.html.markup.StringContent;
 import com.sun.tools.doclets.internal.toolkit.*;
 import com.sun.tools.doclets.internal.toolkit.util.*;
 import com.sun.tools.doclets.internal.toolkit.util.links.*;
@@ -54,16 +57,16 @@
     /**
      * {@inheritDoc}
      */
-    protected LinkOutput getOutputInstance() {
-        return new LinkOutputImpl();
+    protected Content newContent() {
+        return new ContentBuilder();
     }
 
     /**
      * {@inheritDoc}
      */
-    protected LinkOutput getClassLink(LinkInfo linkInfo) {
+    protected Content getClassLink(LinkInfo linkInfo) {
         LinkInfoImpl classLinkInfo = (LinkInfoImpl) linkInfo;
-        boolean noLabel = linkInfo.label == null || linkInfo.label.length() == 0;
+        boolean noLabel = linkInfo.label == null || linkInfo.label.isEmpty();
         ClassDoc classDoc = classLinkInfo.classDoc;
         //Create a tool tip if we are linking to a class or interface.  Don't
         //create one if we are linking to a member.
@@ -73,100 +76,94 @@
                     classLinkInfo.type != null &&
                     !classDoc.qualifiedTypeName().equals(classLinkInfo.type.qualifiedTypeName())) :
             "";
-        StringBuilder label = new StringBuilder(
-            classLinkInfo.getClassLinkLabel(m_writer.configuration));
-        classLinkInfo.displayLength += label.length();
+        Content label = classLinkInfo.getClassLinkLabel(m_writer.configuration);
         Configuration configuration = m_writer.configuration;
-        LinkOutputImpl linkOutput = new LinkOutputImpl();
+        Content link = new ContentBuilder();
         if (classDoc.isIncluded()) {
             if (configuration.isGeneratedDoc(classDoc)) {
                 DocPath filename = getPath(classLinkInfo);
                 if (linkInfo.linkToSelf ||
                                 !(DocPath.forName(classDoc)).equals(m_writer.filename)) {
-                        linkOutput.append(m_writer.getHyperLinkString(
+                        link.addContent(m_writer.getHyperLink(
                                 filename.fragment(classLinkInfo.where),
-                            label.toString(),
+                            label,
                             classLinkInfo.isStrong, classLinkInfo.styleName,
                             title, classLinkInfo.target));
                         if (noLabel && !classLinkInfo.excludeTypeParameterLinks) {
-                            linkOutput.append(getTypeParameterLinks(linkInfo).toString());
+                            link.addContent(getTypeParameterLinks(linkInfo));
                         }
-                        return linkOutput;
+                        return link;
                 }
             }
         } else {
-            String crossLink = m_writer.getCrossClassLink(
+            Content crossLink = m_writer.getCrossClassLink(
                 classDoc.qualifiedName(), classLinkInfo.where,
-                label.toString(), classLinkInfo.isStrong, classLinkInfo.styleName,
+                label, classLinkInfo.isStrong, classLinkInfo.styleName,
                 true);
             if (crossLink != null) {
-                linkOutput.append(crossLink);
+                link.addContent(crossLink);
                 if (noLabel && !classLinkInfo.excludeTypeParameterLinks) {
-                    linkOutput.append(getTypeParameterLinks(linkInfo).toString());
+                    link.addContent(getTypeParameterLinks(linkInfo));
                 }
-                return linkOutput;
+                return link;
             }
         }
         // Can't link so just write label.
-        linkOutput.append(label.toString());
+        link.addContent(label.toString());
         if (noLabel && !classLinkInfo.excludeTypeParameterLinks) {
-            linkOutput.append(getTypeParameterLinks(linkInfo).toString());
+            link.addContent(getTypeParameterLinks(linkInfo));
         }
-        return linkOutput;
+        return link;
     }
 
     /**
      * {@inheritDoc}
      */
-    protected LinkOutput getTypeParameterLink(LinkInfo linkInfo,
+    protected Content getTypeParameterLink(LinkInfo linkInfo,
         Type typeParam) {
         LinkInfoImpl typeLinkInfo = new LinkInfoImpl(m_writer.configuration,
-                linkInfo.getContext(), typeParam);
+                ((LinkInfoImpl) linkInfo).getContext(), typeParam);
         typeLinkInfo.excludeTypeBounds = linkInfo.excludeTypeBounds;
         typeLinkInfo.excludeTypeParameterLinks = linkInfo.excludeTypeParameterLinks;
         typeLinkInfo.linkToSelf = linkInfo.linkToSelf;
         typeLinkInfo.isJava5DeclarationLocation = false;
-        LinkOutput output = getLinkOutput(typeLinkInfo);
-        ((LinkInfoImpl) linkInfo).displayLength += typeLinkInfo.displayLength;
-        return output;
+        return getLink(typeLinkInfo);
     }
 
-    protected LinkOutput getTypeAnnotationLink(LinkInfo linkInfo,
+    protected Content getTypeAnnotationLink(LinkInfo linkInfo,
             AnnotationDesc annotation) {
         throw new RuntimeException("Not implemented yet!");
     }
 
-    public LinkOutput getTypeAnnotationLinks(LinkInfo linkInfo) {
-        LinkOutput output = getOutputInstance();
+    public Content getTypeAnnotationLinks(LinkInfo linkInfo) {
+        ContentBuilder links = new ContentBuilder();
         AnnotationDesc[] annotations;
         if (linkInfo.type instanceof AnnotatedType) {
             annotations = linkInfo.type.asAnnotatedType().annotations();
         } else if (linkInfo.type instanceof TypeVariable) {
             annotations = linkInfo.type.asTypeVariable().annotations();
         } else {
-            return output;
+            return links;
         }
 
         if (annotations.length == 0)
-            return output;
+            return links;
 
-        List<String> annos = m_writer.getAnnotations(0, annotations, false, linkInfo.isJava5DeclarationLocation);
+        List<Content> annos = m_writer.getAnnotations(0, annotations, false, linkInfo.isJava5DeclarationLocation);
 
         boolean isFirst = true;
-        for (String anno : annos) {
+        for (Content anno : annos) {
             if (!isFirst) {
-                linkInfo.displayLength += 1;
-                output.append(" ");
+                links.addContent(" ");
             }
-            output.append(anno);
+            links.addContent(anno);
             isFirst = false;
         }
         if (!annos.isEmpty()) {
-            linkInfo.displayLength += 1;
-            output.append(" ");
+            links.addContent(" ");
         }
 
-        return output;
+        return links;
     }
 
     /**
@@ -204,7 +201,7 @@
      * @param linkInfo the information about the link.
      */
     private DocPath getPath(LinkInfoImpl linkInfo) {
-        if (linkInfo.context == LinkInfoImpl.PACKAGE_FRAME) {
+        if (linkInfo.context == LinkInfoImpl.Kind.PACKAGE_FRAME) {
             //Not really necessary to do this but we want to be consistent
             //with 1.4.2 output.
             return DocPath.forName(linkInfo.classDoc);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkInfoImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkInfoImpl.java
index ae64b75..7e3b604 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkInfoImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkInfoImpl.java
@@ -27,6 +27,9 @@
 package com.sun.tools.doclets.formats.html;
 
 import com.sun.javadoc.*;
+import com.sun.tools.doclets.formats.html.markup.ContentBuilder;
+import com.sun.tools.doclets.formats.html.markup.StringContent;
+import com.sun.tools.doclets.internal.toolkit.Content;
 import com.sun.tools.doclets.internal.toolkit.util.*;
 import com.sun.tools.doclets.internal.toolkit.util.links.*;
 
@@ -38,177 +41,181 @@
  */
 public class LinkInfoImpl extends LinkInfo {
 
-    /**
-     * Indicate that the link appears in a class list.
-     */
-    public static final int ALL_CLASSES_FRAME = 1;
+    public enum Kind {
+        DEFAULT,
 
-    /**
-     * Indicate that the link appears in a class documentation.
-     */
-    public static final int CONTEXT_CLASS = 2;
+        /**
+         * Indicate that the link appears in a class list.
+         */
+        ALL_CLASSES_FRAME,
 
-    /**
-     * Indicate that the link appears in member documentation.
-     */
-    public static final int CONTEXT_MEMBER = 3;
+        /**
+         * Indicate that the link appears in a class documentation.
+         */
+        CLASS,
 
-    /**
-     * Indicate that the link appears in class use documentation.
-     */
-    public static final int CONTEXT_CLASS_USE = 4;
+        /**
+         * Indicate that the link appears in member documentation.
+         */
+        MEMBER,
 
-    /**
-     * Indicate that the link appears in index documentation.
-     */
-    public static final int CONTEXT_INDEX = 5;
+        /**
+         * Indicate that the link appears in class use documentation.
+         */
+        CLASS_USE,
 
-    /**
-     * Indicate that the link appears in constant value summary.
-     */
-    public static final int CONTEXT_CONSTANT_SUMMARY = 6;
+        /**
+         * Indicate that the link appears in index documentation.
+         */
+        INDEX,
 
-    /**
-     * Indicate that the link appears in serialized form documentation.
-     */
-    public static final int CONTEXT_SERIALIZED_FORM = 7;
+        /**
+         * Indicate that the link appears in constant value summary.
+         */
+        CONSTANT_SUMMARY,
 
-    /**
-     * Indicate that the link appears in serial member documentation.
-     */
-    public static final int CONTEXT_SERIAL_MEMBER = 8;
+        /**
+         * Indicate that the link appears in serialized form documentation.
+         */
+        SERIALIZED_FORM,
 
-    /**
-     * Indicate that the link appears in package documentation.
-     */
-    public static final int CONTEXT_PACKAGE = 9;
+        /**
+         * Indicate that the link appears in serial member documentation.
+         */
+        SERIAL_MEMBER,
 
-    /**
-     * Indicate that the link appears in see tag documentation.
-     */
-    public static final int CONTEXT_SEE_TAG = 10;
+        /**
+         * Indicate that the link appears in package documentation.
+         */
+        PACKAGE,
 
-    /**
-     * Indicate that the link appears in value tag documentation.
-     */
-    public static final int CONTEXT_VALUE_TAG = 11;
+        /**
+         * Indicate that the link appears in see tag documentation.
+         */
+        SEE_TAG,
 
-    /**
-     * Indicate that the link appears in tree documentation.
-     */
-    public static final int CONTEXT_TREE = 12;
+        /**
+         * Indicate that the link appears in value tag documentation.
+         */
+        VALUE_TAG,
 
-    /**
-     * Indicate that the link appears in a class list.
-     */
-    public static final int PACKAGE_FRAME = 13;
+        /**
+         * Indicate that the link appears in tree documentation.
+         */
+        TREE,
 
-    /**
-     * The header in the class documentation.
-     */
-    public static final int CONTEXT_CLASS_HEADER = 14;
+        /**
+         * Indicate that the link appears in a class list.
+         */
+        PACKAGE_FRAME,
 
-    /**
-     * The signature in the class documentation.
-     */
-    public static final int CONTEXT_CLASS_SIGNATURE = 15;
+        /**
+         * The header in the class documentation.
+         */
+        CLASS_HEADER,
 
-    /**
-     * The return type of a method.
-     */
-    public static final int CONTEXT_RETURN_TYPE = 16;
+        /**
+         * The signature in the class documentation.
+         */
+        CLASS_SIGNATURE,
 
-    /**
-     * The return type of a method in a member summary.
-     */
-    public static final int CONTEXT_SUMMARY_RETURN_TYPE = 17;
+        /**
+         * The return type of a method.
+         */
+        RETURN_TYPE,
 
-    /**
-     * The type of a method/constructor parameter.
-     */
-    public static final int CONTEXT_EXECUTABLE_MEMBER_PARAM = 18;
+        /**
+         * The return type of a method in a member summary.
+         */
+        SUMMARY_RETURN_TYPE,
 
-    /**
-     * Super interface links.
-     */
-    public static final int CONTEXT_SUPER_INTERFACES = 19;
+        /**
+         * The type of a method/constructor parameter.
+         */
+        EXECUTABLE_MEMBER_PARAM,
 
-    /**
-     * Implemented interface links.
-     */
-    public static final int CONTEXT_IMPLEMENTED_INTERFACES = 20;
+        /**
+         * Super interface links.
+         */
+        SUPER_INTERFACES,
 
-    /**
-     * Implemented class links.
-     */
-    public static final int CONTEXT_IMPLEMENTED_CLASSES = 21;
+        /**
+         * Implemented interface links.
+         */
+        IMPLEMENTED_INTERFACES,
 
-    /**
-     * Subinterface links.
-     */
-    public static final int CONTEXT_SUBINTERFACES = 22;
+        /**
+         * Implemented class links.
+         */
+        IMPLEMENTED_CLASSES,
 
-    /**
-     * Subclasses links.
-     */
-    public static final int CONTEXT_SUBCLASSES = 23;
+        /**
+         * Subinterface links.
+         */
+        SUBINTERFACES,
 
-    /**
-     * The signature in the class documentation (implements/extends portion).
-     */
-    public static final int CONTEXT_CLASS_SIGNATURE_PARENT_NAME = 24;
+        /**
+         * Subclasses links.
+         */
+        SUBCLASSES,
 
-    /**
-     * The header for method documentation copied from parent.
-     */
-    public static final int CONTEXT_METHOD_DOC_COPY = 26;
+        /**
+         * The signature in the class documentation (implements/extends portion).
+         */
+        CLASS_SIGNATURE_PARENT_NAME,
 
-    /**
-     * Method "specified by" link.
-     */
-    public static final int CONTEXT_METHOD_SPECIFIED_BY = 27;
+        /**
+         * The header for method documentation copied from parent.
+         */
+        METHOD_DOC_COPY,
 
-    /**
-     * Method "overrides" link.
-     */
-    public static final int CONTEXT_METHOD_OVERRIDES = 28;
+        /**
+         * Method "specified by" link.
+         */
+        METHOD_SPECIFIED_BY,
 
-    /**
-     * Annotation link.
-     */
-    public static final int CONTEXT_ANNOTATION = 29;
+        /**
+         * Method "overrides" link.
+         */
+        METHOD_OVERRIDES,
 
-    /**
-     * The header for field documentation copied from parent.
-     */
-    public static final int CONTEXT_FIELD_DOC_COPY = 30;
+        /**
+         * Annotation link.
+         */
+        ANNOTATION,
 
-    /**
-     * The parent nodes int the class tree.
-     */
-    public static final int CONTEXT_CLASS_TREE_PARENT = 31;
+        /**
+         * The header for field documentation copied from parent.
+         */
+        FIELD_DOC_COPY,
 
-    /**
-     * The type parameters of a method or constructor.
-     */
-    public static final int CONTEXT_MEMBER_TYPE_PARAMS = 32;
+        /**
+         * The parent nodes in the class tree.
+         */
+        CLASS_TREE_PARENT,
 
-    /**
-     * Indicate that the link appears in class use documentation.
-     */
-    public static final int CONTEXT_CLASS_USE_HEADER = 33;
+        /**
+         * The type parameters of a method or constructor.
+         */
+        MEMBER_TYPE_PARAMS,
 
-    /**
-     * The header for property documentation copied from parent.
-     */
-    public static final int CONTEXT_PROPERTY_DOC_COPY = 34;
+        /**
+         * Indicate that the link appears in class use documentation.
+         */
+        CLASS_USE_HEADER,
+
+        /**
+         * The header for property documentation copied from parent.
+         */
+        PROPERTY_DOC_COPY
+    }
 
     public final ConfigurationImpl configuration;
 
     /**
-     * The integer indicating the location of the link.
+     * The location of the link.
      */
-    public int context;
+    public Kind context = Kind.DEFAULT;
 
     /**
      * The value of the marker #.
@@ -218,7 +225,7 @@
     /**
      * String style of text defined in style sheet.
      */
-    public String styleName ="";
+    public String styleName = "";
 
     /**
      * The value of the target.
@@ -230,108 +237,34 @@
      *
      * @param configuration the configuration data for the doclet
      * @param context    the context of the link.
-     * @param classDoc   the class to link to.
-     * @param label      the label for the link.
-     * @param target     the value of the target attribute.
-     */
-    public LinkInfoImpl(ConfigurationImpl configuration,
-            int context, ClassDoc classDoc, String label, String target) {
-        this.configuration = configuration;
-        this.classDoc = classDoc;
-        this.label = label;
-        this.target = target;
-        setContext(context);
-    }
-
-    /**
-     * Construct a LinkInfo object.
-     *
-     * @param configuration the configuration data for the doclet
-     * @param context    the context of the link.
-     * @param classDoc   the class to link to.
-     * @param where      the value of the marker #.
-     * @param label      the label for the link.
-     * @param isStrong       true if the link should be strong.
-     * @param styleName  String style of text defined in style sheet.
-     */
-    public LinkInfoImpl(ConfigurationImpl configuration,
-            int context, ClassDoc classDoc, String where, String label,
-            boolean isStrong, String styleName) {
-        this.configuration = configuration;
-        this.classDoc = classDoc;
-        this.where = where;
-        this.label = label;
-        this.isStrong = isStrong;
-        this.styleName = styleName;
-        setContext(context);
-    }
-
-    /**
-     * Construct a LinkInfo object.
-     *
-     * @param configuration the configuration data for the doclet
-     * @param context    the context of the link.
-     * @param classDoc   the class to link to.
-     * @param where      the value of the marker #.
-     * @param label      the label for the link.
-     * @param isStrong       true if the link should be strong.
-     */
-    public LinkInfoImpl(ConfigurationImpl configuration,
-            int context, ClassDoc classDoc, String where, String label,
-            boolean isStrong) {
-        this.configuration = configuration;
-        this.classDoc = classDoc;
-        this.where = where;
-        this.label = label;
-        this.isStrong = isStrong;
-        setContext(context);
-    }
-
-    /**
-     * Construct a LinkInfo object.
-     *
-     * @param configuration the configuration data for the doclet
-     * @param classDoc   the class to link to.
-     * @param label      the label for the link.
-     */
-    public LinkInfoImpl(ConfigurationImpl configuration,
-            ClassDoc classDoc, String label) {
-        this.configuration = configuration;
-        this.classDoc = classDoc;
-        this.label = label;
-        setContext(context);
-    }
-
-    /**
-     * Construct a LinkInfo object.
-     *
-     * @param configuration the configuration data for the doclet
      * @param context               the context of the link.
      * @param executableMemberDoc   the member to link to.
-     * @param isStrong                true if the link should be strong.
      */
     public LinkInfoImpl(ConfigurationImpl configuration,
-            int context, ExecutableMemberDoc executableMemberDoc,
-            boolean isStrong) {
+            Kind context, ExecutableMemberDoc executableMemberDoc) {
         this.configuration = configuration;
         this.executableMemberDoc = executableMemberDoc;
-        this.isStrong = isStrong;
         setContext(context);
     }
 
     /**
+     * {@inherotDoc}
+     */
+    protected Content newContent() {
+        return new ContentBuilder();
+    }
+
+    /**
      * Construct a LinkInfo object.
      *
      * @param configuration the configuration data for the doclet
      * @param context    the context of the link.
      * @param classDoc   the class to link to.
-     * @param isStrong       true if the link should be strong.
      */
     public LinkInfoImpl(ConfigurationImpl configuration,
-            int context, ClassDoc classDoc,  boolean isStrong) {
+            Kind context, ClassDoc classDoc) {
         this.configuration = configuration;
         this.classDoc = classDoc;
-        this.isStrong = isStrong;
         setContext(context);
     }
 
@@ -343,70 +276,76 @@
      * @param type       the class to link to.
      */
     public LinkInfoImpl(ConfigurationImpl configuration,
-            int context, Type type) {
+            Kind context, Type type) {
         this.configuration = configuration;
         this.type = type;
         setContext(context);
     }
 
+
     /**
-     * Construct a LinkInfo object.
-     *
-     * @param configuration the configuration data for the doclet
-     * @param context    the context of the link.
-     * @param type       the class to link to.
-     * @param isVarArg   true if this is a link to a var arg.
+     * Set the label for the link.
+     * @param label plain-text label for the link
      */
-    public LinkInfoImpl(ConfigurationImpl configuration,
-            int context, Type type, boolean isVarArg) {
-        this.configuration = configuration;
-        this.type = type;
-        this.isVarArg = isVarArg;
-        setContext(context);
+    public LinkInfoImpl label(String label) {
+        this.label = new StringContent(label);
+        return this;
     }
 
     /**
-     * Construct a LinkInfo object.
-     *
-     * @param configuration the configuration data for the doclet
-     * @param context    the context of the link.
-     * @param type       the class to link to.
-     * @param label      the label for the link.
-     * @param isStrong     true if the link should be strong.
+     * Set the label for the link.
      */
-    public LinkInfoImpl(ConfigurationImpl configuration,
-            int context, Type type, String label,
-            boolean isStrong) {
-        this.configuration = configuration;
-        this.type = type;
+    public LinkInfoImpl label(Content label) {
         this.label = label;
-        this.isStrong = isStrong;
-        setContext(context);
+        return this;
     }
 
     /**
-     * Construct a LinkInfo object.
-     *
-     * @param configuration the configuration data for the doclet
-     * @param context    the context of the link.
-     * @param classDoc   the class to link to.
-     * @param label      the label for the link.
-     * @param isStrong       true if the link should be strong.
+     * Set whether or not the link should be strong.
      */
-    public LinkInfoImpl(ConfigurationImpl configuration,
-            int context, ClassDoc classDoc, String label,
-            boolean isStrong) {
-        this.configuration = configuration;
-        this.classDoc = classDoc;
-        this.label = label;
-        this.isStrong = isStrong;
-        setContext(context);
+    public LinkInfoImpl strong(boolean strong) {
+        this.isStrong = strong;
+        return this;
     }
 
     /**
+     * Set the style to be used for the link.
+     * @param styleName  String style of text defined in style sheet.
+     */
+    public LinkInfoImpl styleName(String styleName) {
+        this.styleName = styleName;
+        return this;
+    }
+
+    /**
+     * Set the target to be used for the link.
+     * @param styleName  String style of text defined in style sheet.
+     */
+    public LinkInfoImpl target(String target) {
+        this.target = target;
+        return this;
+    }
+
+    /**
+     * Set whether or not this is a link to a varargs parameter.
+     */
+    public LinkInfoImpl varargs(boolean varargs) {
+        this.isVarArg = varargs;
+        return this;
+    }
+
+    /**
+     * Set the fragment specifier for the link.
+     */
+    public LinkInfoImpl where(String where) {
+        this.where = where;
+        return this;
+     }
+
+    /**
      * {@inheritDoc}
      */
-    public int getContext() {
+    public Kind getContext() {
         return context;
     }
 
@@ -418,63 +357,63 @@
      *
      * @param c the context id to set.
      */
-    public void setContext(int c) {
+    public final void setContext(Kind c) {
         //NOTE:  Put context specific link code here.
         switch (c) {
             case ALL_CLASSES_FRAME:
             case PACKAGE_FRAME:
-            case CONTEXT_IMPLEMENTED_CLASSES:
-            case CONTEXT_SUBCLASSES:
-            case CONTEXT_METHOD_DOC_COPY:
-            case CONTEXT_FIELD_DOC_COPY:
-            case CONTEXT_PROPERTY_DOC_COPY:
-            case CONTEXT_CLASS_USE_HEADER:
+            case IMPLEMENTED_CLASSES:
+            case SUBCLASSES:
+            case METHOD_DOC_COPY:
+            case FIELD_DOC_COPY:
+            case PROPERTY_DOC_COPY:
+            case CLASS_USE_HEADER:
                 includeTypeInClassLinkLabel = false;
                 break;
 
-            case CONTEXT_ANNOTATION:
+            case ANNOTATION:
                 excludeTypeParameterLinks = true;
                 excludeTypeBounds = true;
                 break;
 
-            case CONTEXT_IMPLEMENTED_INTERFACES:
-            case CONTEXT_SUPER_INTERFACES:
-            case CONTEXT_SUBINTERFACES:
-            case CONTEXT_CLASS_TREE_PARENT:
-            case CONTEXT_TREE:
-            case CONTEXT_CLASS_SIGNATURE_PARENT_NAME:
+            case IMPLEMENTED_INTERFACES:
+            case SUPER_INTERFACES:
+            case SUBINTERFACES:
+            case CLASS_TREE_PARENT:
+            case TREE:
+            case CLASS_SIGNATURE_PARENT_NAME:
                 excludeTypeParameterLinks = true;
                 excludeTypeBounds = true;
                 includeTypeInClassLinkLabel = false;
                 includeTypeAsSepLink = true;
                 break;
 
-            case CONTEXT_PACKAGE:
-            case CONTEXT_CLASS_USE:
-            case CONTEXT_CLASS_HEADER:
-            case CONTEXT_CLASS_SIGNATURE:
+            case PACKAGE:
+            case CLASS_USE:
+            case CLASS_HEADER:
+            case CLASS_SIGNATURE:
                 excludeTypeParameterLinks = true;
                 includeTypeAsSepLink = true;
                 includeTypeInClassLinkLabel = false;
                 break;
 
-            case CONTEXT_MEMBER_TYPE_PARAMS:
+            case MEMBER_TYPE_PARAMS:
                 includeTypeAsSepLink = true;
                 includeTypeInClassLinkLabel = false;
                 break;
 
-            case CONTEXT_RETURN_TYPE:
-            case CONTEXT_SUMMARY_RETURN_TYPE:
+            case RETURN_TYPE:
+            case SUMMARY_RETURN_TYPE:
                 excludeTypeBounds = true;
                 break;
-            case CONTEXT_EXECUTABLE_MEMBER_PARAM:
+            case EXECUTABLE_MEMBER_PARAM:
                 excludeTypeBounds = true;
                 break;
         }
         context = c;
         if (type != null &&
             type.asTypeVariable()!= null &&
-            type.asTypeVariable().owner() instanceof ExecutableMemberDoc){
+            type.asTypeVariable().owner() instanceof ExecutableMemberDoc) {
             excludeTypeParameterLinks = true;
         }
     }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java
index 0585a9e..235c913 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java
@@ -117,7 +117,6 @@
      * @return a content object for the signature
      */
     public Content getSignature(MethodDoc method) {
-        writer.displayLength = 0;
         Content pre = new HtmlTree(HtmlTag.PRE);
         writer.addAnnotationInfo(method, pre);
         addModifiers(method, pre);
@@ -129,8 +128,9 @@
         } else {
             addName(method.name(), pre);
         }
-        addParameters(method, pre);
-        addExceptions(method, pre);
+        int indent = pre.charCount();
+        addParameters(method, pre, indent);
+        addExceptions(method, pre, indent);
         return pre;
     }
 
@@ -152,12 +152,12 @@
                     Util.isLinkable(holderClassDoc, configuration)))) {
                 writer.addInlineComment(method, methodDocTree);
             } else {
-                Content link = new RawHtml(
-                        writer.getDocLink(LinkInfoImpl.CONTEXT_METHOD_DOC_COPY,
+                Content link =
+                        writer.getDocLink(LinkInfoImpl.Kind.METHOD_DOC_COPY,
                         holder.asClassDoc(), method,
                         holder.asClassDoc().isIncluded() ?
                             holder.typeName() : holder.qualifiedTypeName(),
-                            false));
+                            false);
                 Content codelLink = HtmlTree.CODE(link);
                 Content strong = HtmlTree.STRONG(holder.asClassDoc().isClass()?
                     writer.descfrmClassLabel : writer.descfrmInterfaceLabel);
@@ -223,8 +223,8 @@
     /**
      * {@inheritDoc}
      */
-    public String getCaption() {
-        return configuration.getText("doclet.Methods");
+    public Content getCaption() {
+        return configuration.getResource("doclet.Methods");
     }
 
     /**
@@ -260,8 +260,8 @@
      * {@inheritDoc}
      */
     public void addInheritedSummaryLabel(ClassDoc cd, Content inheritedTree) {
-        Content classLink = new RawHtml(writer.getPreQualifiedClassLink(
-                LinkInfoImpl.CONTEXT_MEMBER, cd, false));
+        Content classLink = writer.getPreQualifiedClassLink(
+                LinkInfoImpl.Kind.MEMBER, cd, false);
         Content label = new StringContent(cd.isClass() ?
             configuration.getText("doclet.Methods_Inherited_From_Class") :
             configuration.getText("doclet.Methods_Inherited_From_Interface"));
@@ -300,25 +300,25 @@
             return;
         }
         Content label = writer.overridesLabel;
-        int context = LinkInfoImpl.CONTEXT_METHOD_OVERRIDES;
+        LinkInfoImpl.Kind context = LinkInfoImpl.Kind.METHOD_OVERRIDES;
 
         if (method != null) {
             if (overriddenType.asClassDoc().isAbstract() && method.isAbstract()){
                 //Abstract method is implemented from abstract class,
                 //not overridden
                 label = writer.specifiedByLabel;
-                context = LinkInfoImpl.CONTEXT_METHOD_SPECIFIED_BY;
+                context = LinkInfoImpl.Kind.METHOD_SPECIFIED_BY;
             }
             Content dt = HtmlTree.DT(HtmlTree.STRONG(label));
             dl.addContent(dt);
-            Content overriddenTypeLink = new RawHtml(
-                    writer.getLink(new LinkInfoImpl(writer.configuration, context, overriddenType)));
+            Content overriddenTypeLink =
+                    writer.getLink(new LinkInfoImpl(writer.configuration, context, overriddenType));
             Content codeOverridenTypeLink = HtmlTree.CODE(overriddenTypeLink);
             String name = method.name();
-            Content methlink = new RawHtml(writer.getLink(
-                    new LinkInfoImpl(writer.configuration, LinkInfoImpl.CONTEXT_MEMBER,
-                    overriddenType.asClassDoc(),
-                    writer.getAnchor(method), name, false)));
+            Content methlink = writer.getLink(
+                    new LinkInfoImpl(writer.configuration, LinkInfoImpl.Kind.MEMBER,
+                    overriddenType.asClassDoc())
+                    .where(writer.getAnchor(method)).label(name));
             Content codeMethLink = HtmlTree.CODE(methlink);
             Content dd = HtmlTree.DD(codeMethLink);
             dd.addContent(writer.getSpace());
@@ -361,14 +361,14 @@
         for (int i = 0; i < implementedMethods.length; i++) {
             MethodDoc implementedMeth = implementedMethods[i];
             Type intfac = implementedMethodsFinder.getMethodHolder(implementedMeth);
-            Content intfaclink = new RawHtml(writer.getLink(new LinkInfoImpl(
-                    writer.configuration, LinkInfoImpl.CONTEXT_METHOD_SPECIFIED_BY, intfac)));
+            Content intfaclink = writer.getLink(new LinkInfoImpl(
+                    writer.configuration, LinkInfoImpl.Kind.METHOD_SPECIFIED_BY, intfac));
             Content codeIntfacLink = HtmlTree.CODE(intfaclink);
             Content dt = HtmlTree.DT(HtmlTree.STRONG(writer.specifiedByLabel));
             dl.addContent(dt);
-            Content methlink = new RawHtml(writer.getDocLink(
-                    LinkInfoImpl.CONTEXT_MEMBER, implementedMeth,
-                    implementedMeth.name(), false));
+            Content methlink = writer.getDocLink(
+                    LinkInfoImpl.Kind.MEMBER, implementedMeth,
+                    implementedMeth.name(), false);
             Content codeMethLink = HtmlTree.CODE(methlink);
             Content dd = HtmlTree.DD(codeMethLink);
             dd.addContent(writer.getSpace());
@@ -388,8 +388,8 @@
     protected void addReturnType(MethodDoc method, Content htmltree) {
         Type type = method.returnType();
         if (type != null) {
-            Content linkContent = new RawHtml(writer.getLink(
-                    new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_RETURN_TYPE, type)));
+            Content linkContent = writer.getLink(
+                    new LinkInfoImpl(configuration, LinkInfoImpl.Kind.RETURN_TYPE, type));
             htmltree.addContent(linkContent);
             htmltree.addContent(writer.getSpace());
         }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/NestedClassWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/NestedClassWriterImpl.java
index 6ce42e5..487d9ff 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/NestedClassWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/NestedClassWriterImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -26,7 +26,6 @@
 package com.sun.tools.doclets.formats.html;
 
 import java.io.*;
-import java.util.*;
 
 import com.sun.javadoc.*;
 import com.sun.tools.doclets.formats.html.markup.*;
@@ -101,8 +100,8 @@
     /**
      * {@inheritDoc}
      */
-    public String getCaption() {
-        return configuration.getText("doclet.Nested_Classes");
+    public Content getCaption() {
+        return configuration.getResource("doclet.Nested_Classes");
     }
 
     /**
@@ -148,8 +147,8 @@
      * {@inheritDoc}
      */
     public void addInheritedSummaryLabel(ClassDoc cd, Content inheritedTree) {
-        Content classLink = new RawHtml(writer.getPreQualifiedClassLink(
-                LinkInfoImpl.CONTEXT_MEMBER, cd, false));
+        Content classLink = writer.getPreQualifiedClassLink(
+                LinkInfoImpl.Kind.MEMBER, cd, false);
         Content label = new StringContent(cd.isInterface() ?
             configuration.getText("doclet.Nested_Classes_Interface_Inherited_From_Interface") :
             configuration.getText("doclet.Nested_Classes_Interfaces_Inherited_From_Class"));
@@ -163,10 +162,10 @@
     /**
      * {@inheritDoc}
      */
-    protected void addSummaryLink(int context, ClassDoc cd, ProgramElementDoc member,
+    protected void addSummaryLink(LinkInfoImpl.Kind context, ClassDoc cd, ProgramElementDoc member,
             Content tdSummary) {
-        Content strong = HtmlTree.STRONG(new RawHtml(
-                writer.getLink(new LinkInfoImpl(configuration, context, (ClassDoc)member, false))));
+        Content strong = HtmlTree.STRONG(
+                writer.getLink(new LinkInfoImpl(configuration, context, (ClassDoc)member)));
         Content code = HtmlTree.CODE(strong);
         tdSummary.addContent(code);
     }
@@ -176,9 +175,9 @@
      */
     protected void addInheritedSummaryLink(ClassDoc cd,
             ProgramElementDoc member, Content linksTree) {
-        linksTree.addContent(new RawHtml(
-                writer.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_MEMBER,
-                (ClassDoc)member, false))));
+        linksTree.addContent(
+                writer.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER,
+                (ClassDoc)member)));
     }
 
     /**
@@ -194,7 +193,7 @@
      * {@inheritDoc}
      */
     protected Content getDeprecatedLink(ProgramElementDoc member) {
-        return writer.getQualifiedClassLink(LinkInfoImpl.CONTEXT_MEMBER,
+        return writer.getQualifiedClassLink(LinkInfoImpl.Kind.MEMBER,
                 (ClassDoc)member);
     }
 
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageFrameWriter.java
index 851fed9..cdd8837 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageFrameWriter.java
@@ -94,7 +94,7 @@
             packgen = new PackageFrameWriter(configuration, packageDoc);
             String pkgName = Util.getPackageName(packageDoc);
             Content body = packgen.getBody(false, packgen.getWindowTitle(pkgName));
-            Content pkgNameContent = new RawHtml(pkgName);
+            Content pkgNameContent = new StringContent(pkgName);
             Content heading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, HtmlStyle.bar,
                     packgen.getTargetPackageLink(packageDoc, "classFrame", pkgNameContent));
             body.addContent(heading);
@@ -166,7 +166,7 @@
             Arrays.sort(arr);
             boolean printedHeader = false;
             HtmlTree ul = new HtmlTree(HtmlTag.UL);
-            ul.addAttr(HtmlAttr.TITLE, labelContent.toString());
+            ul.setTitle(labelContent);
             for (int i = 0; i < arr.length; i++) {
                 if (documentedClasses != null &&
                         !documentedClasses.contains(arr[i])) {
@@ -182,10 +182,10 @@
                     contentTree.addContent(heading);
                     printedHeader = true;
                 }
-                Content link = new RawHtml (getLink(new LinkInfoImpl(configuration,
-                        LinkInfoImpl.PACKAGE_FRAME, arr[i],
-                        (arr[i].isInterface() ? italicsText(arr[i].name()) :
-                            arr[i].name()),"classFrame")));
+                Content arr_i_name = new StringContent(arr[i].name());
+                if (arr[i].isInterface()) arr_i_name = HtmlTree.I(arr_i_name);
+                Content link = getLink(new LinkInfoImpl(configuration,
+                        LinkInfoImpl.Kind.PACKAGE_FRAME, arr[i]).label(arr_i_name).target("classFrame"));
                 Content li = HtmlTree.LI(link);
                 ul.addContent(li);
             }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java
index ef60299..fad1bd3 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java
@@ -84,7 +84,7 @@
                 packagesLabel);
         Content div = HtmlTree.DIV(HtmlStyle.indexContainer, heading);
         HtmlTree ul = new HtmlTree(HtmlTag.UL);
-        ul.addAttr(HtmlAttr.TITLE, packagesLabel.toString());
+        ul.setTitle(packagesLabel);
         for(int i = 0; i < packages.length; i++) {
             // Do not list the package if -nodeprecated option is set and the
             // package is marked as deprecated.
@@ -112,7 +112,7 @@
                      DocPaths.PACKAGE_FRAME), packageLabel, "",
                     "packageFrame");
         } else {
-            packageLabel = new RawHtml("&lt;unnamed package&gt;");
+            packageLabel = new StringContent("<unnamed package>");
             packageLinkContent = getHyperLink(DocPaths.PACKAGE_FRAME,
                     packageLabel, "", "packageFrame");
         }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java
index ee497de..e11ed98 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java
@@ -123,7 +123,7 @@
     /**
      * {@inheritDoc}
      */
-    protected void addProfilesList(String profileSummary, String profilesTableSummary,
+    protected void addProfilesList(Content profileSummary, String profilesTableSummary,
             Content body) {
         Content table = HtmlTree.TABLE(HtmlStyle.overviewSummary, 0, 3, 0, profilesTableSummary,
                 getTableCaption(profileSummary));
@@ -141,7 +141,7 @@
     protected void addPackagesList(PackageDoc[] packages, String text,
             String tableSummary, Content body) {
         Content table = HtmlTree.TABLE(HtmlStyle.overviewSummary, 0, 3, 0, tableSummary,
-                getTableCaption(text));
+                getTableCaption(new RawHtml(text)));
         table.addContent(getSummaryTableHeader(packageTableHeader, "col"));
         Content tbody = new HtmlTree(HtmlTag.TBODY);
         addPackagesList(packages, tbody);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java
index e95c370..d9510f2 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java
index b8369ce..3e2668f 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -152,9 +152,9 @@
      */
     protected void addPackageList(Content contentTree) throws IOException {
         Content table = HtmlTree.TABLE(0, 3, 0, useTableSummary,
-                getTableCaption(configuration.getText(
+                getTableCaption(configuration.getResource(
                 "doclet.ClassUse_Packages.that.use.0",
-                getPackageLinkString(pkgdoc, Util.getPackageName(pkgdoc), false))));
+                getPackageLink(pkgdoc, Util.getPackageName(pkgdoc)))));
         table.addContent(getSummaryTableHeader(packageTableHeader, "col"));
         Content tbody = new HtmlTree(HtmlTag.TBODY);
         Iterator<String> it = usingPackageToUsedClasses.keySet().iterator();
@@ -197,10 +197,10 @@
             String tableSummary = configuration.getText("doclet.Use_Table_Summary",
                     configuration.getText("doclet.classes"));
             Content table = HtmlTree.TABLE(0, 3, 0, tableSummary,
-                    getTableCaption(configuration.getText(
+                    getTableCaption(configuration.getResource(
                     "doclet.ClassUse_Classes.in.0.used.by.1",
-                    getPackageLinkString(pkgdoc, Util.getPackageName(pkgdoc), false),
-                    getPackageLinkString(usingPackage,Util.getPackageName(usingPackage), false))));
+                    getPackageLink(pkgdoc, Util.getPackageName(pkgdoc)),
+                    getPackageLink(usingPackage, Util.getPackageName(usingPackage)))));
             table.addContent(getSummaryTableHeader(classTableHeader, "col"));
             Content tbody = new HtmlTree(HtmlTag.TBODY);
             Iterator<ClassDoc> itc =
@@ -247,7 +247,7 @@
     protected void addPackageUse(PackageDoc pkg, Content contentTree) throws IOException {
         Content tdFirst = HtmlTree.TD(HtmlStyle.colFirst,
                 getHyperLink(Util.getPackageName(pkg),
-                new RawHtml(Util.getPackageName(pkg))));
+                new StringContent(Util.getPackageName(pkg))));
         contentTree.addContent(tdFirst);
         HtmlTree tdLast = new HtmlTree(HtmlTag.TD);
         tdLast.addStyle(HtmlStyle.colLast);
@@ -272,7 +272,10 @@
         Content bodyTree = getBody(true, getWindowTitle(title));
         addTop(bodyTree);
         addNavLinks(true, bodyTree);
-        Content headContent = getResource("doclet.ClassUse_Title", packageText, name);
+        ContentBuilder headContent = new ContentBuilder();
+        headContent.addContent(getResource("doclet.ClassUse_Title", packageText));
+        headContent.addContent(new HtmlTree(HtmlTag.BR));
+        headContent.addContent(name);
         Content heading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true,
                 HtmlStyle.title, headContent);
         Content div = HtmlTree.DIV(HtmlStyle.header, heading);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java
index c1fcebf..16be6c3 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -102,7 +102,7 @@
         Content tHeading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true,
                 HtmlStyle.title, packageLabel);
         tHeading.addContent(getSpace());
-        Content packageHead = new RawHtml(heading);
+        Content packageHead = new StringContent(heading);
         tHeading.addContent(packageHead);
         div.addContent(tHeading);
         addDeprecationInfo(div);
@@ -168,7 +168,7 @@
             String tableSummary, String[] tableHeader, Content summaryContentTree) {
         if(classes.length > 0) {
             Arrays.sort(classes);
-            Content caption = getTableCaption(label);
+            Content caption = getTableCaption(new RawHtml(label));
             Content table = HtmlTree.TABLE(HtmlStyle.packageSummary, 0, 3, 0,
                     tableSummary, caption);
             table.addContent(getSummaryTableHeader(tableHeader, "col"));
@@ -178,9 +178,8 @@
                     !configuration.isGeneratedDoc(classes[i])) {
                     continue;
                 }
-                Content classContent = new RawHtml(getLink(new LinkInfoImpl(
-                        configuration, LinkInfoImpl.CONTEXT_PACKAGE, classes[i],
-                        false)));
+                Content classContent = getLink(new LinkInfoImpl(
+                        configuration, LinkInfoImpl.Kind.PACKAGE, classes[i]));
                 Content tdClass = HtmlTree.TD(HtmlStyle.colFirst, classContent);
                 HtmlTree tr = HtmlTree.TR(tdClass);
                 if (i%2 == 0)
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java
index f336fe8..4689eca 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java
@@ -87,7 +87,7 @@
                 profilesLabel);
         Content div = HtmlTree.DIV(HtmlStyle.indexContainer, heading);
         HtmlTree ul = new HtmlTree(HtmlTag.UL);
-        ul.addAttr(HtmlAttr.TITLE, profilesLabel.toString());
+        ul.setTitle(profilesLabel);
         for (int i = 1; i < profiles.getProfileCount(); i++) {
             ul.addContent(getProfile(i));
         }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageFrameWriter.java
index 00ff307..ef8c0fb 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageFrameWriter.java
@@ -158,7 +158,7 @@
             Arrays.sort(arr);
             boolean printedHeader = false;
             HtmlTree ul = new HtmlTree(HtmlTag.UL);
-            ul.addAttr(HtmlAttr.TITLE, labelContent.toString());
+            ul.setTitle(labelContent);
             for (int i = 0; i < arr.length; i++) {
                 if (!isTypeInProfile(arr[i], profileValue)) {
                     continue;
@@ -173,10 +173,10 @@
                     contentTree.addContent(heading);
                     printedHeader = true;
                 }
-                Content link = new RawHtml (getLink(new LinkInfoImpl(configuration,
-                        LinkInfoImpl.PACKAGE_FRAME, arr[i],
-                        (arr[i].isInterface() ? italicsText(arr[i].name()) :
-                            arr[i].name()),"classFrame")));
+                Content arr_i_name = new StringContent(arr[i].name());
+                if (arr[i].isInterface()) arr_i_name = HtmlTree.I(arr_i_name);
+                Content link = getLink(new LinkInfoImpl(configuration,
+                        LinkInfoImpl.Kind.PACKAGE_FRAME, arr[i]).label(arr_i_name).target("classFrame"));
                 Content li = HtmlTree.LI(link);
                 ul.addContent(li);
             }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java
index 3d5535d..6764f5f 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java
@@ -91,7 +91,7 @@
         heading.addContent(packagesLabel);
         Content div = HtmlTree.DIV(HtmlStyle.indexContainer, heading);
         HtmlTree ul = new HtmlTree(HtmlTag.UL);
-        ul.addAttr(HtmlAttr.TITLE, packagesLabel.toString());
+        ul.setTitle(packagesLabel);
         PackageDoc[] packages = configuration.profilePackages.get(profileName);
         for (int i = 0; i < packages.length; i++) {
             if ((!(configuration.nodeprecated && Util.isDeprecated(packages[i])))) {
@@ -118,7 +118,7 @@
                      DocPaths.profilePackageFrame(profileName)), pkgLabel, "",
                     "packageFrame");
         } else {
-            pkgLabel = new RawHtml("&lt;unnamed package&gt;");
+            pkgLabel = new StringContent("<unnamed package>");
             packageLinkContent = getHyperLink(DocPaths.PACKAGE_FRAME,
                     pkgLabel, "", "packageFrame");
         }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PropertyWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PropertyWriterImpl.java
index 4fa52f2..9018b77 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PropertyWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PropertyWriterImpl.java
@@ -98,9 +98,9 @@
         Content pre = new HtmlTree(HtmlTag.PRE);
         writer.addAnnotationInfo(property, pre);
         addModifiers(property, pre);
-        Content propertylink = new RawHtml(writer.getLink(new LinkInfoImpl(
-                configuration, LinkInfoImpl.CONTEXT_MEMBER,
-                property.returnType())));
+        Content propertylink = writer.getLink(new LinkInfoImpl(
+                configuration, LinkInfoImpl.Kind.MEMBER,
+                property.returnType()));
         pre.addContent(propertylink);
         pre.addContent(" ");
         if (configuration.linksource) {
@@ -128,12 +128,12 @@
                     (! (holder.isPublic() || Util.isLinkable(holder, configuration)))) {
                 writer.addInlineComment(property, propertyDocTree);
             } else {
-                Content link = new RawHtml(
-                        writer.getDocLink(LinkInfoImpl.CONTEXT_PROPERTY_DOC_COPY,
+                Content link =
+                        writer.getDocLink(LinkInfoImpl.Kind.PROPERTY_DOC_COPY,
                         holder, property,
                         holder.isIncluded() ?
                             holder.typeName() : holder.qualifiedTypeName(),
-                            false));
+                            false);
                 Content codeLink = HtmlTree.CODE(link);
                 Content strong = HtmlTree.STRONG(holder.isClass()?
                    writer.descfrmClassLabel : writer.descfrmInterfaceLabel);
@@ -199,8 +199,8 @@
     /**
      * {@inheritDoc}
      */
-    public String getCaption() {
-        return configuration.getText("doclet.Properties");
+    public Content getCaption() {
+        return configuration.getResource("doclet.Properties");
     }
 
     /**
@@ -235,8 +235,8 @@
      * {@inheritDoc}
      */
     public void addInheritedSummaryLabel(ClassDoc cd, Content inheritedTree) {
-        Content classLink = new RawHtml(writer.getPreQualifiedClassLink(
-                LinkInfoImpl.CONTEXT_MEMBER, cd, false));
+        Content classLink = writer.getPreQualifiedClassLink(
+                LinkInfoImpl.Kind.MEMBER, cd, false);
         Content label = new StringContent(cd.isClass() ?
             configuration.getText("doclet.Properties_Inherited_From_Class") :
             configuration.getText("doclet.Properties_Inherited_From_Interface"));
@@ -250,15 +250,15 @@
     /**
      * {@inheritDoc}
      */
-    protected void addSummaryLink(int context, ClassDoc cd, ProgramElementDoc member,
+    protected void addSummaryLink(LinkInfoImpl.Kind context, ClassDoc cd, ProgramElementDoc member,
             Content tdSummary) {
-        Content strong = HtmlTree.STRONG(new RawHtml(
+        Content strong = HtmlTree.STRONG(
                 writer.getDocLink(context,
                         cd,
                         (MemberDoc) member,
                         member.name().substring(0, member.name().lastIndexOf("Property")),
                         false,
-                        true)));
+                        true));
 
         Content code = HtmlTree.CODE(strong);
         tdSummary.addContent(code);
@@ -269,12 +269,12 @@
      */
     protected void addInheritedSummaryLink(ClassDoc cd,
             ProgramElementDoc member, Content linksTree) {
-        linksTree.addContent(new RawHtml(
-                writer.getDocLink(LinkInfoImpl.CONTEXT_MEMBER, cd, (MemberDoc)member,
+        linksTree.addContent(
+                writer.getDocLink(LinkInfoImpl.Kind.MEMBER, cd, (MemberDoc)member,
                 ((member.name().lastIndexOf("Property") != -1) && configuration.javafx)
                         ? member.name().substring(0, member.name().length() - "Property".length())
                         : member.name(),
-                false, true)));
+                false, true));
     }
 
     /**
@@ -289,7 +289,7 @@
      * {@inheritDoc}
      */
     protected Content getDeprecatedLink(ProgramElementDoc member) {
-        return writer.getDocLink(LinkInfoImpl.CONTEXT_MEMBER,
+        return writer.getDocLink(LinkInfoImpl.Kind.MEMBER,
                 (MemberDoc) member, ((MethodDoc)member).qualifiedName());
     }
 
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SerializedFormWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SerializedFormWriterImpl.java
index 665d15c..23ef780 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SerializedFormWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SerializedFormWriterImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -127,29 +127,28 @@
      * @return a content tree for the class header
      */
     public Content getClassHeader(ClassDoc classDoc) {
-        String classLink = (classDoc.isPublic() || classDoc.isProtected())?
-            getLink(new LinkInfoImpl(configuration, classDoc,
-            configuration.getClassName(classDoc))):
-            classDoc.qualifiedName();
+        Content classLink = (classDoc.isPublic() || classDoc.isProtected()) ?
+            getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.DEFAULT, classDoc)
+            .label(configuration.getClassName(classDoc))) :
+            new StringContent(classDoc.qualifiedName());
         Content li = HtmlTree.LI(HtmlStyle.blockList, getMarkerAnchor(
                 classDoc.qualifiedName()));
-        String superClassLink =
+        Content superClassLink =
             classDoc.superclassType() != null ?
                 getLink(new LinkInfoImpl(configuration,
-                        LinkInfoImpl.CONTEXT_SERIALIZED_FORM,
+                        LinkInfoImpl.Kind.SERIALIZED_FORM,
                         classDoc.superclassType())) :
                 null;
 
         //Print the heading.
-        String className = superClassLink == null ?
-            configuration.getText(
+        Content className = superClassLink == null ?
+            configuration.getResource(
             "doclet.Class_0_implements_serializable", classLink) :
-            configuration.getText(
+            configuration.getResource(
             "doclet.Class_0_extends_implements_serializable", classLink,
             superClassLink);
-        Content classNameContent = new RawHtml(className);
         li.addContent(HtmlTree.HEADING(HtmlConstants.SERIALIZED_MEMBER_HEADING,
-                classNameContent));
+                className));
         return li;
     }
 
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SourceToHTMLConverter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SourceToHTMLConverter.java
index c151c3a..9d528a9 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SourceToHTMLConverter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SourceToHTMLConverter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -58,7 +58,7 @@
     /**
      * New line to be added to the documentation.
      */
-    private static final Content NEW_LINE = new RawHtml(DocletConstants.NL);
+    private static final String NEW_LINE = DocletConstants.NL;
 
     private final ConfigurationImpl configuration;
 
@@ -269,10 +269,7 @@
      */
     private void addLine(Content pre, String line, int currentLineNo) {
         if (line != null) {
-            StringBuilder lineBuffer = new StringBuilder(line);
-            Util.replaceTabs(configuration, lineBuffer);
-            Util.escapeHtmlChars(lineBuffer);
-            pre.addContent(new RawHtml(lineBuffer.toString()));
+            pre.addContent(Util.replaceTabs(configuration, line));
             Content anchor = HtmlTree.A_NAME("line." + Integer.toString(currentLineNo));
             pre.addContent(anchor);
             pre.addContent(NEW_LINE);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SubWriterHolderWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SubWriterHolderWriter.java
index f3af843..94bde2e 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SubWriterHolderWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SubWriterHolderWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -135,10 +135,8 @@
      * @return the content tree for the method type link
      */
     public Content getMethodTypeLinks(MethodTypes methodType) {
-        StringBuilder jsShow = new StringBuilder("javascript:show(");
-        jsShow.append(methodType.value()).append(");");
-        HtmlTree link = HtmlTree.A(jsShow.toString(),
-                new StringContent(methodType.text()));
+        String jsShow = "javascript:show(" + methodType.value() +");";
+        HtmlTree link = HtmlTree.A(jsShow, new StringContent(methodType.text()));
         return link;
     }
 
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletOutputImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletOutputImpl.java
deleted file mode 100644
index 0dfb467..0000000
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletOutputImpl.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.doclets.formats.html;
-
-import com.sun.tools.doclets.internal.toolkit.taglets.*;
-
-/**
- * The output for HTML taglets.
- *
- *  <p><b>This is NOT part of any supported API.
- *  If you write code that depends on this, you do so at your own risk.
- *  This code and its internal interfaces are subject to change or
- *  deletion without notice.</b>
- *
- * @since 1.5
- * @author Jamie Ho
- */
-
-public class TagletOutputImpl implements TagletOutput {
-
-    private StringBuilder output;
-
-    public TagletOutputImpl(String o) {
-        setOutput(o);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setOutput (Object o) {
-        output = new StringBuilder(o == null ? "" : (String) o);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void appendOutput(TagletOutput o) {
-        output.append(o.toString());
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean hasInheritDocTag() {
-        return output.indexOf(InheritDocTaglet.INHERIT_DOC_INLINE_TAG) != -1;
-    }
-
-    public String toString() {
-        return output.toString();
-    }
-
-    /**
-     * Check whether the taglet output is empty.
-     */
-    public boolean isEmpty() {
-        return (toString().trim().isEmpty());
-    }
-}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletWriterImpl.java
index 6f190da..1939d68 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletWriterImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,11 @@
 package com.sun.tools.doclets.formats.html;
 
 import com.sun.javadoc.*;
+import com.sun.tools.doclets.formats.html.markup.ContentBuilder;
+import com.sun.tools.doclets.formats.html.markup.HtmlStyle;
+import com.sun.tools.doclets.formats.html.markup.HtmlTree;
+import com.sun.tools.doclets.formats.html.markup.RawHtml;
+import com.sun.tools.doclets.formats.html.markup.StringContent;
 import com.sun.tools.doclets.internal.toolkit.*;
 import com.sun.tools.doclets.internal.toolkit.builders.SerializedFormBuilder;
 import com.sun.tools.doclets.internal.toolkit.taglets.*;
@@ -58,39 +63,48 @@
     /**
      * {@inheritDoc}
      */
-    public TagletOutput getOutputInstance() {
-        return new TagletOutputImpl("");
+    public Content getOutputInstance() {
+        return new ContentBuilder();
     }
 
     /**
      * {@inheritDoc}
      */
-    public TagletOutput getDocRootOutput() {
+    protected Content codeTagOutput(Tag tag) {
+        Content result = HtmlTree.CODE(new StringContent(tag.text()));
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Content getDocRootOutput() {
+        String path;
         if (configuration.docrootparent.length() > 0)
-            return new TagletOutputImpl(configuration.docrootparent);
+            path = configuration.docrootparent;
         else if (htmlWriter.pathToRoot.isEmpty())
-            return new TagletOutputImpl(".");
+            path = ".";
         else
-            return new TagletOutputImpl(htmlWriter.pathToRoot.getPath());
+            path = htmlWriter.pathToRoot.getPath();
+        return new StringContent(path);
     }
 
     /**
      * {@inheritDoc}
      */
-    public TagletOutput deprecatedTagOutput(Doc doc) {
-        StringBuilder output = new StringBuilder();
+    public Content deprecatedTagOutput(Doc doc) {
+        ContentBuilder result = new ContentBuilder();
         Tag[] deprs = doc.tags("deprecated");
         if (doc instanceof ClassDoc) {
             if (Util.isDeprecated((ProgramElementDoc) doc)) {
-                output.append("<span class=\"strong\">" +
-                    configuration.
-                        getText("doclet.Deprecated") + "</span>&nbsp;");
+                result.addContent(HtmlTree.SPAN(HtmlStyle.strong,
+                        new StringContent(configuration.getText("doclet.Deprecated"))));
+                result.addContent(RawHtml.nbsp);
                 if (deprs.length > 0) {
                     Tag[] commentTags = deprs[0].inlineTags();
                     if (commentTags.length > 0) {
-
-                        output.append(commentTagsToOutput(null, doc,
-                            deprs[0].inlineTags(), false).toString()
+                        result.addContent(commentTagsToOutput(null, doc,
+                            deprs[0].inlineTags(), false)
                         );
                     }
                 }
@@ -98,24 +112,31 @@
         } else {
             MemberDoc member = (MemberDoc) doc;
             if (Util.isDeprecated((ProgramElementDoc) doc)) {
-                output.append("<span class=\"strong\">" +
-                    configuration.
-                            getText("doclet.Deprecated") + "</span>&nbsp;");
+                result.addContent(HtmlTree.SPAN(HtmlStyle.strong,
+                        new StringContent(configuration.getText("doclet.Deprecated"))));
+                result.addContent(RawHtml.nbsp);
                 if (deprs.length > 0) {
-                    output.append("<i>");
-                    output.append(commentTagsToOutput(null, doc,
-                        deprs[0].inlineTags(), false).toString());
-                    output.append("</i>");
+                    Content body = commentTagsToOutput(null, doc,
+                        deprs[0].inlineTags(), false);
+                    result.addContent(HtmlTree.I(body));
                 }
             } else {
                 if (Util.isDeprecated(member.containingClass())) {
-                    output.append("<span class=\"strong\">" +
-                    configuration.
-                            getText("doclet.Deprecated") + "</span>&nbsp;");
+                    result.addContent(HtmlTree.SPAN(HtmlStyle.strong,
+                            new StringContent(configuration.getText("doclet.Deprecated"))));
+                    result.addContent(RawHtml.nbsp);
                 }
             }
         }
-        return new TagletOutputImpl(output.toString());
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected Content literalTagOutput(Tag tag) {
+        Content result = new StringContent(tag.text());
+        return result;
     }
 
     /**
@@ -128,177 +149,200 @@
     /**
      * {@inheritDoc}
      */
-    public TagletOutput getParamHeader(String header) {
-        StringBuilder result = new StringBuilder();
-        result.append("<dt>");
-        result.append("<span class=\"strong\">").append(header).append("</span></dt>");
-        return new TagletOutputImpl(result.toString());
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public TagletOutput paramTagOutput(ParamTag paramTag, String paramName) {
-        TagletOutput result = new TagletOutputImpl("<dd><code>" + paramName + "</code>"
-         + " - " + htmlWriter.commentTagsToString(paramTag, null, paramTag.inlineTags(), false) + "</dd>");
+    public Content getParamHeader(String header) {
+        HtmlTree result = HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.strong,
+                new StringContent(header)));
         return result;
     }
 
     /**
      * {@inheritDoc}
      */
-    public TagletOutput returnTagOutput(Tag returnTag) {
-        TagletOutput result = new TagletOutputImpl(DocletConstants.NL + "<dt>" +
-            "<span class=\"strong\">" + configuration.getText("doclet.Returns") +
-            "</span>" + "</dt>" + "<dd>" +
-            htmlWriter.commentTagsToString(returnTag, null, returnTag.inlineTags(),
-            false) + "</dd>");
+    public Content paramTagOutput(ParamTag paramTag, String paramName) {
+        ContentBuilder body = new ContentBuilder();
+        body.addContent(HtmlTree.CODE(new RawHtml(paramName)));
+        body.addContent(" - ");
+        body.addContent(htmlWriter.commentTagsToContent(paramTag, null, paramTag.inlineTags(), false));
+        HtmlTree result = HtmlTree.DD(body);
         return result;
     }
 
     /**
      * {@inheritDoc}
      */
-    public TagletOutput seeTagOutput(Doc holder, SeeTag[] seeTags) {
-        String result = "";
+    public Content propertyTagOutput(Tag tag, String prefix) {
+        Content body = new ContentBuilder();
+        body.addContent(new RawHtml(prefix));
+        body.addContent(" ");
+        body.addContent(HtmlTree.CODE(new RawHtml(tag.text())));
+        body.addContent(".");
+        Content result = HtmlTree.P(body);
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Content returnTagOutput(Tag returnTag) {
+        ContentBuilder result = new ContentBuilder();
+        result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.strong,
+                new StringContent(configuration.getText("doclet.Returns")))));
+        result.addContent(HtmlTree.DD(htmlWriter.commentTagsToContent(
+                returnTag, null, returnTag.inlineTags(), false)));
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Content seeTagOutput(Doc holder, SeeTag[] seeTags) {
+        ContentBuilder body = new ContentBuilder();
         if (seeTags.length > 0) {
-            result = addSeeHeader(result);
             for (int i = 0; i < seeTags.length; ++i) {
-                if (i > 0) {
-                    result += ", " + DocletConstants.NL;
-                }
-                result += htmlWriter.seeTagToString(seeTags[i]);
+                appendSeparatorIfNotEmpty(body);
+                body.addContent(htmlWriter.seeTagToContent(seeTags[i]));
             }
         }
         if (holder.isField() && ((FieldDoc)holder).constantValue() != null &&
                 htmlWriter instanceof ClassWriterImpl) {
             //Automatically add link to constant values page for constant fields.
-            result = addSeeHeader(result);
+            appendSeparatorIfNotEmpty(body);
             DocPath constantsPath =
                     htmlWriter.pathToRoot.resolve(DocPaths.CONSTANT_VALUES);
             String whichConstant =
                     ((ClassWriterImpl) htmlWriter).getClassDoc().qualifiedName() + "." + ((FieldDoc) holder).name();
             DocLink link = constantsPath.fragment(whichConstant);
-            result += htmlWriter.getHyperLinkString(link,
-                    configuration.getText("doclet.Constants_Summary"),
-                    false);
+            body.addContent(htmlWriter.getHyperLink(link,
+                    new StringContent(configuration.getText("doclet.Constants_Summary"))));
         }
         if (holder.isClass() && ((ClassDoc)holder).isSerializable()) {
             //Automatically add link to serialized form page for serializable classes.
             if ((SerializedFormBuilder.serialInclude(holder) &&
                       SerializedFormBuilder.serialInclude(((ClassDoc)holder).containingPackage()))) {
-                result = addSeeHeader(result);
+                appendSeparatorIfNotEmpty(body);
                 DocPath serialPath = htmlWriter.pathToRoot.resolve(DocPaths.SERIALIZED_FORM);
                 DocLink link = serialPath.fragment(((ClassDoc)holder).qualifiedName());
-                result += htmlWriter.getHyperLinkString(link,
-                        configuration.getText("doclet.Serialized_Form"), false);
+                body.addContent(htmlWriter.getHyperLink(link,
+                        new StringContent(configuration.getText("doclet.Serialized_Form"))));
             }
         }
-        return result.equals("") ? null : new TagletOutputImpl(result + "</dd>");
+        if (body.isEmpty())
+            return body;
+
+        ContentBuilder result = new ContentBuilder();
+        result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.strong,
+                new StringContent(configuration.getText("doclet.See_Also")))));
+        result.addContent(HtmlTree.DD(body));
+        return result;
+
     }
 
-    private String addSeeHeader(String result) {
-        if (result != null && result.length() > 0) {
-            return result + ", " + DocletConstants.NL;
-        } else {
-            return "<dt><span class=\"strong\">" +
-                    configuration.getText("doclet.See_Also") + "</span></dt><dd>";
+    private void appendSeparatorIfNotEmpty(ContentBuilder body) {
+        if (!body.isEmpty()) {
+            body.addContent(", ");
+            body.addContent(DocletConstants.NL);
         }
-     }
+    }
 
     /**
      * {@inheritDoc}
      */
-    public TagletOutput simpleTagOutput(Tag[] simpleTags, String header) {
-        String result = "<dt><span class=\"strong\">" + header + "</span></dt>" + DocletConstants.NL +
-            "  <dd>";
+    public Content simpleTagOutput(Tag[] simpleTags, String header) {
+        ContentBuilder result = new ContentBuilder();
+        result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.strong, new RawHtml(header))));
+        ContentBuilder body = new ContentBuilder();
         for (int i = 0; i < simpleTags.length; i++) {
             if (i > 0) {
-                result += ", ";
+                body.addContent(", ");
             }
-            result += htmlWriter.commentTagsToString(simpleTags[i], null, simpleTags[i].inlineTags(), false);
+            body.addContent(htmlWriter.commentTagsToContent(
+                    simpleTags[i], null, simpleTags[i].inlineTags(), false));
         }
-        result += "</dd>" + DocletConstants.NL;
-        return new TagletOutputImpl(result);
+        result.addContent(HtmlTree.DD(body));
+        return result;
     }
 
     /**
      * {@inheritDoc}
      */
-    public TagletOutput simpleTagOutput(Tag simpleTag, String header) {
-        return new TagletOutputImpl("<dt><span class=\"strong\">" + header + "</span></dt>" + "  <dd>"
-            + htmlWriter.commentTagsToString(simpleTag, null, simpleTag.inlineTags(), false)
-            + "</dd>" + DocletConstants.NL);
+    public Content simpleTagOutput(Tag simpleTag, String header) {
+        ContentBuilder result = new ContentBuilder();
+        result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.strong, new RawHtml(header))));
+        Content body = htmlWriter.commentTagsToContent(
+                simpleTag, null, simpleTag.inlineTags(), false);
+        result.addContent(HtmlTree.DD(body));
+        return result;
     }
 
     /**
      * {@inheritDoc}
      */
-    public TagletOutput getThrowsHeader() {
-        return new TagletOutputImpl(DocletConstants.NL + "<dt>" + "<span class=\"strong\">" +
-            configuration.getText("doclet.Throws") + "</span></dt>");
+    public Content getThrowsHeader() {
+        HtmlTree result = HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.strong,
+                new StringContent(configuration.getText("doclet.Throws"))));
+        return result;
     }
 
     /**
      * {@inheritDoc}
      */
-    public TagletOutput throwsTagOutput(ThrowsTag throwsTag) {
-        String result = DocletConstants.NL + "<dd>";
-        result += throwsTag.exceptionType() == null ?
-            htmlWriter.codeText(throwsTag.exceptionName()) :
-            htmlWriter.codeText(
-                htmlWriter.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_MEMBER,
-                throwsTag.exceptionType())));
-        TagletOutput text = new TagletOutputImpl(
-            htmlWriter.commentTagsToString(throwsTag, null,
-            throwsTag.inlineTags(), false));
-        if (text != null && text.toString().length() > 0) {
-            result += " - " + text;
+    public Content throwsTagOutput(ThrowsTag throwsTag) {
+        ContentBuilder body = new ContentBuilder();
+        Content excName = (throwsTag.exceptionType() == null) ?
+                new RawHtml(throwsTag.exceptionName()) :
+                htmlWriter.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER,
+                throwsTag.exceptionType()));
+        body.addContent(HtmlTree.CODE(excName));
+        Content desc = htmlWriter.commentTagsToContent(throwsTag, null,
+            throwsTag.inlineTags(), false);
+        if (desc != null && !desc.isEmpty()) {
+            body.addContent(" - ");
+            body.addContent(desc);
         }
-        result += "</dd>";
-        return new TagletOutputImpl(result);
+        HtmlTree result = HtmlTree.DD(body);
+        return result;
     }
 
     /**
      * {@inheritDoc}
      */
-    public TagletOutput throwsTagOutput(Type throwsType) {
-        return new TagletOutputImpl(DocletConstants.NL + "<dd>" +
-            htmlWriter.codeText(htmlWriter.getLink(
-                new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_MEMBER, throwsType))) + "</dd>");
+    public Content throwsTagOutput(Type throwsType) {
+        HtmlTree result = HtmlTree.DD(HtmlTree.CODE(htmlWriter.getLink(
+                new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER, throwsType))));
+        return result;
     }
 
     /**
      * {@inheritDoc}
      */
-    public TagletOutput valueTagOutput(FieldDoc field, String constantVal,
+    public Content valueTagOutput(FieldDoc field, String constantVal,
             boolean includeLink) {
-        return new TagletOutputImpl(includeLink ?
-            htmlWriter.getDocLink(LinkInfoImpl.CONTEXT_VALUE_TAG, field,
-                constantVal, false) : constantVal);
+        return includeLink ?
+            htmlWriter.getDocLink(LinkInfoImpl.Kind.VALUE_TAG, field,
+                constantVal, false) : new RawHtml(constantVal);
     }
 
     /**
      * {@inheritDoc}
      */
-    public TagletOutput commentTagsToOutput(Tag holderTag, Tag[] tags) {
+    public Content commentTagsToOutput(Tag holderTag, Tag[] tags) {
         return commentTagsToOutput(holderTag, null, tags, false);
     }
 
     /**
      * {@inheritDoc}
      */
-    public TagletOutput commentTagsToOutput(Doc holderDoc, Tag[] tags) {
+    public Content commentTagsToOutput(Doc holderDoc, Tag[] tags) {
         return commentTagsToOutput(null, holderDoc, tags, false);
     }
 
     /**
      * {@inheritDoc}
      */
-    public TagletOutput commentTagsToOutput(Tag holderTag,
+    public Content commentTagsToOutput(Tag holderTag,
         Doc holderDoc, Tag[] tags, boolean isFirstSentence) {
-        return new TagletOutputImpl(htmlWriter.commentTagsToString(
-            holderTag, holderDoc, tags, isFirstSentence));
+        return htmlWriter.commentTagsToContent(
+            holderTag, holderDoc, tags, isFirstSentence);
     }
 
     /**
@@ -307,13 +351,4 @@
     public Configuration configuration() {
         return configuration;
     }
-
-    /**
-     * Return an instance of a TagletWriter that knows how to write HTML.
-     *
-     * @return an instance of a TagletWriter that knows how to write HTML.
-     */
-    public TagletOutput getTagletOutputInstance() {
-        return new TagletOutputImpl("");
-    }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/ContentBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/ContentBuilder.java
new file mode 100644
index 0000000..a586627
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/ContentBuilder.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.doclets.formats.html.markup;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import com.sun.tools.doclets.internal.toolkit.Content;
+
+/**
+ * A sequence of Content nodes.
+ */
+public class ContentBuilder extends Content {
+    protected List<Content> contents = Collections.<Content>emptyList();
+
+    @Override
+    public void addContent(Content content) {
+        nullCheck(content);
+        if ((content instanceof ContentBuilder) && content.isEmpty())
+            return;
+        ensureMutableContents();
+        if (content instanceof ContentBuilder) {
+            contents.addAll(((ContentBuilder) content).contents);
+        } else
+            contents.add(content);
+    }
+
+    @Override
+    public void addContent(String text) {
+        if (text.isEmpty())
+            return;
+        ensureMutableContents();
+        Content c = contents.isEmpty() ? null : contents.get(contents.size() - 1);
+        StringContent sc;
+        if (c != null && c instanceof StringContent) {
+            sc = (StringContent) c;
+        } else {
+            contents.add(sc = new StringContent());
+        }
+        sc.addContent(text);
+    }
+
+    @Override
+    public boolean write(Writer writer, boolean atNewline) throws IOException {
+        for (Content content: contents) {
+            atNewline = content.write(writer, atNewline);
+        }
+        return atNewline;
+    }
+
+    @Override
+    public boolean isEmpty() {
+        for (Content content: contents) {
+            if (!content.isEmpty())
+                return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int charCount() {
+        int n = 0;
+        for (Content c : contents)
+            n += c.charCount();
+        return n;
+    }
+
+    private void ensureMutableContents() {
+        if (contents.isEmpty())
+            contents = new ArrayList<Content>();
+    }
+}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java
index 36b55fe..c0048f9 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -34,7 +34,6 @@
 import com.sun.tools.doclets.internal.toolkit.util.DocFile;
 import com.sun.tools.doclets.internal.toolkit.util.DocLink;
 import com.sun.tools.doclets.internal.toolkit.util.DocPath;
-import com.sun.tools.doclets.internal.toolkit.util.DocPaths;
 
 
 /**
@@ -72,43 +71,8 @@
      */
     public abstract Configuration configuration();
 
-    /**
-     * Return Html Hyper Link string.
-     *
-     * @param link       String name of the file.
-     * @param label      Tag for the link.
-     * @param strong       Boolean that sets label to strong.
-     * @return String    Hyper Link.
-     */
-    public String getHyperLinkString(DocPath link,
-                               String label, boolean strong) {
-        return getHyperLinkString(link, label, strong, "", "", "");
-    }
-
-    public String getHyperLinkString(DocLink link,
-                               String label, boolean strong) {
-        return getHyperLinkString(link, label, strong, "", "", "");
-    }
-
-    /**
-     * Get Html Hyper Link string.
-     *
-     * @param link       String name of the file.
-     * @param label      Tag for the link.
-     * @param strong       Boolean that sets label to strong.
-     * @param stylename  String style of text defined in style sheet.
-     * @return String    Hyper Link.
-     */
-    public String getHyperLinkString(DocPath link,
-                               String label, boolean strong,
-                               String stylename) {
-        return getHyperLinkString(link, label, strong, stylename, "", "");
-    }
-
-    public String getHyperLinkString(DocLink link,
-                               String label, boolean strong,
-                               String stylename) {
-        return getHyperLinkString(link, label, strong, stylename, "", "");
+    public Content getHyperLink(DocPath link, String label) {
+        return getHyperLink(link, new StringContent(label), false, "", "", "");
     }
 
     /**
@@ -125,69 +89,47 @@
     }
 
     /**
-     * Get Html Hyper Link string.
+     * Get Html hyperlink.
      *
-     * @param link       String name of the file.
+     * @param link       path of the file.
      * @param label      Tag for the link.
      * @return a content tree for the hyper link
      */
+    public Content getHyperLink(DocPath link, Content label) {
+        return getHyperLink(link, label, "", "");
+    }
+
+    public Content getHyperLink(DocLink link, Content label) {
+        return getHyperLink(link, label, "", "");
+    }
+
     public Content getHyperLink(DocPath link,
-                               Content label) {
-        return getHyperLink(link, label, "", "");
-    }
-
-    public Content getHyperLink(DocLink link,
-                               Content label) {
-        return getHyperLink(link, label, "", "");
-    }
-
-    /**
-     * Get Html Hyper Link string.
-     *
-     * @param link       String name of the file.
-     * @param label      Tag for the link.
-     * @param strong       Boolean that sets label to strong.
-     * @param stylename  String style of text defined in style sheet.
-     * @param title      String that describes the links content for accessibility.
-     * @param target     Target frame.
-     * @return String    Hyper Link.
-     */
-    public String getHyperLinkString(DocPath link,
-                               String label, boolean strong,
+                               Content label, boolean strong,
                                String stylename, String title, String target) {
-        return getHyperLinkString(new DocLink(link), label, strong,
+        return getHyperLink(new DocLink(link), label, strong,
                 stylename, title, target);
     }
 
-    public String getHyperLinkString(DocLink link,
-                               String label, boolean strong,
+    public Content getHyperLink(DocLink link,
+                               Content label, boolean strong,
                                String stylename, String title, String target) {
-        StringBuilder retlink = new StringBuilder();
-        retlink.append("<a href=\"").append(link).append('"');
+        Content body = label;
+        if (strong) {
+            body = HtmlTree.SPAN(HtmlStyle.strong, body);
+        }
+        if (stylename != null && stylename.length() != 0) {
+            HtmlTree t = new HtmlTree(HtmlTag.FONT, body);
+            t.addAttr(HtmlAttr.CLASS, stylename);
+            body = t;
+        }
+        HtmlTree l = HtmlTree.A(link.toString(), body);
         if (title != null && title.length() != 0) {
-            retlink.append(" title=\"").append(title).append('"');
+            l.addAttr(HtmlAttr.TITLE, title);
         }
         if (target != null && target.length() != 0) {
-            retlink.append(" target=\"").append(target).append('"');
+            l.addAttr(HtmlAttr.TARGET, target);
         }
-        retlink.append(">");
-        if (stylename != null && stylename.length() != 0) {
-            retlink.append("<FONT CLASS=\"");
-            retlink.append(stylename);
-            retlink.append("\">");
-        }
-        if (strong) {
-            retlink.append("<span class=\"strong\">");
-        }
-        retlink.append(label);
-        if (strong) {
-            retlink.append("</span>");
-        }
-        if (stylename != null && stylename.length() != 0) {
-            retlink.append("</FONT>");
-        }
-        retlink.append("</a>");
-        return retlink.toString();
+        return l;
     }
 
     /**
@@ -217,17 +159,6 @@
     }
 
     /**
-     * Get link string without positioning in the file.
-     *
-     * @param link       String name of the file.
-     * @param label      Tag for the link.
-     * @return Strign    Hyper link.
-     */
-    public String getHyperLinkString(DocPath link, String label) {
-        return getHyperLinkString(link, label, false);
-    }
-
-    /**
      * Get the name of the package, this class is in.
      *
      * @param cd    ClassDoc.
@@ -277,20 +208,6 @@
         write(htmlDocument);
     }
 
-    /**
-     * Print the appropriate spaces to format the class tree in the class page.
-     *
-     * @param len   Number of spaces.
-     */
-    public String spaces(int len) {
-        String space = "";
-
-        for (int i = 0; i < len; i++) {
-            space += " ";
-        }
-        return space;
-    }
-
     protected String getGeneratedByString() {
         Calendar calendar = new GregorianCalendar(TimeZone.getDefault());
         Date today = calendar.getTime();
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTag.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTag.java
index a4ee63d..fe9f554 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTag.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTag.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,7 @@
     CENTER,
     CODE(BlockType.INLINE, EndTag.END),
     DD,
+    DIR,
     DIV,
     DL,
     DT,
@@ -63,6 +64,7 @@
     I(BlockType.INLINE, EndTag.END),
     IMG(BlockType.INLINE, EndTag.NOEND),
     LI,
+    LISTING,
     LINK(BlockType.OTHER, EndTag.NOEND),
     MENU,
     META(BlockType.OTHER, EndTag.NOEND),
@@ -75,6 +77,7 @@
     SMALL(BlockType.INLINE, EndTag.END),
     SPAN(BlockType.INLINE, EndTag.END),
     STRONG(BlockType.INLINE, EndTag.END),
+    SUB(BlockType.INLINE, EndTag.END),
     TABLE,
     TBODY,
     TD,
@@ -84,14 +87,14 @@
     TT(BlockType.INLINE, EndTag.END),
     UL;
 
-    protected final BlockType blockType;
-    protected final EndTag endTag;
-    private final String value;
+    public final BlockType blockType;
+    public final EndTag endTag;
+    public final String value;
 
     /**
      * Enum representing the type of HTML element.
      */
-    protected static enum BlockType {
+    public static enum BlockType {
         BLOCK,
         INLINE,
         OTHER;
@@ -100,7 +103,7 @@
     /**
      * Enum representing HTML end tag requirement.
      */
-    protected static enum EndTag {
+    public static enum EndTag {
         END,
         NOEND;
     }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java
index 6c76105..e6c101a 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -78,8 +78,12 @@
      */
     public void addAttr(HtmlAttr attrName, String attrValue) {
         if (attrs.isEmpty())
-            attrs = new LinkedHashMap<HtmlAttr,String>();
-        attrs.put(nullCheck(attrName), nullCheck(attrValue));
+            attrs = new LinkedHashMap<HtmlAttr,String>(3);
+        attrs.put(nullCheck(attrName), escapeHtmlChars(attrValue));
+    }
+
+    public void setTitle(Content body) {
+        addAttr(HtmlAttr.TITLE, stripHtml(body));
     }
 
     /**
@@ -123,6 +127,42 @@
             addContent(new StringContent(stringContent));
     }
 
+    public int charCount() {
+        int n = 0;
+        for (Content c : content)
+            n += c.charCount();
+        return n;
+    }
+
+    /**
+     * Given a string, escape all special html characters and
+     * return the result.
+     *
+     * @param s The string to check.
+     * @return the original string with all of the HTML characters escaped.
+     */
+    private static String escapeHtmlChars(String s) {
+        for (int i = 0; i < s.length(); i++) {
+            char ch = s.charAt(i);
+            switch (ch) {
+                // only start building a new string if we need to
+                case '<': case '>': case '&':
+                    StringBuilder sb = new StringBuilder(s.substring(0, i));
+                    for ( ; i < s.length(); i++) {
+                        ch = s.charAt(i);
+                        switch (ch) {
+                            case '<': sb.append("&lt;");  break;
+                            case '>': sb.append("&gt;");  break;
+                            case '&': sb.append("&amp;"); break;
+                            default:  sb.append(ch);      break;
+                        }
+                    }
+                    return sb.toString();
+            }
+        }
+        return s;
+    }
+
     /**
      * Generates an HTML anchor tag.
      *
@@ -132,7 +172,7 @@
      */
     public static HtmlTree A(String ref, Content body) {
         HtmlTree htmltree = new HtmlTree(HtmlTag.A, nullCheck(body));
-        htmltree.addAttr(HtmlAttr.HREF, nullCheck(ref));
+        htmltree.addAttr(HtmlAttr.HREF, ref);
         return htmltree;
     }
 
@@ -317,7 +357,7 @@
             HtmlStyle styleClass, Content body) {
         HtmlTree htmltree = new HtmlTree(headingTag, nullCheck(body));
         if (printTitle)
-            htmltree.addAttr(HtmlAttr.TITLE, Util.stripHtml(body.toString()));
+            htmltree.setTitle(body);
         if (styleClass != null)
             htmltree.addStyle(styleClass);
         return htmltree;
@@ -802,7 +842,7 @@
         out.write(tagString);
         Iterator<HtmlAttr> iterator = attrs.keySet().iterator();
         HtmlAttr key;
-        String value = "";
+        String value;
         while (iterator.hasNext()) {
             key = iterator.next();
             value = attrs.get(key);
@@ -830,4 +870,22 @@
             return false;
         }
     }
+
+    /**
+     * Given a Content node, strips all html characters and
+     * return the result.
+     *
+     * @param body The content node to check.
+     * @return the plain text from the content node
+     *
+     */
+    private static String stripHtml(Content body) {
+        String rawString = body.toString();
+        // remove HTML tags
+        rawString = rawString.replaceAll("\\<.*?>", " ");
+        // consolidate multiple spaces between a word to a single space
+        rawString = rawString.replaceAll("\\b\\s{2,}\\b", " ");
+        // remove extra whitespaces
+        return rawString.trim();
+    }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java
index f4d04bb..6fe85c0 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java
@@ -27,6 +27,8 @@
 
 import java.io.*;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import com.sun.tools.doclets.internal.toolkit.*;
 import com.sun.tools.doclets.internal.toolkit.util.*;
@@ -195,8 +197,7 @@
                 configuration.getText("doclet.Modifier"),
                 configuration.getText("doclet.Type"));
         overviewLabel = getResource("doclet.Overview");
-        defaultPackageLabel = new RawHtml(
-                DocletConstants.DEFAULT_PACKAGE_NAME);
+        defaultPackageLabel = new StringContent(DocletConstants.DEFAULT_PACKAGE_NAME);
         packageLabel = getResource("doclet.Package");
         profileLabel = getResource("doclet.Profile");
         useLabel = getResource("doclet.navClassUse");
@@ -252,30 +253,30 @@
      * @return a content tree for the text
      */
     public Content getResource(String key) {
-        return new StringContent(configuration.getText(key));
+        return configuration.getResource(key);
     }
 
     /**
      * Get the configuration string as a content.
      *
      * @param key the key to look for in the configuration file
-     * @param a1 string argument added to configuration text
+     * @param o   string or content argument added to configuration text
      * @return a content tree for the text
      */
-    public Content getResource(String key, String a1) {
-        return new RawHtml(configuration.getText(key, a1));
+    public Content getResource(String key, Object o) {
+        return configuration.getResource(key, o);
     }
 
     /**
      * Get the configuration string as a content.
      *
      * @param key the key to look for in the configuration file
-     * @param a1 string argument added to configuration text
-     * @param a2 string argument added to configuration text
+     * @param o1  string or content argument added to configuration text
+     * @param o2  string or content argument added to configuration text
      * @return a content tree for the text
      */
-    public Content getResource(String key, String a1, String a2) {
-        return new RawHtml(configuration.getText(key, a1, a2));
+    public Content getResource(String key, Object o0, Object o1) {
+        return configuration.getResource(key, o0, o1);
     }
 
     /**
@@ -303,10 +304,11 @@
      *
      * @return a content for the SCRIPT tag
      */
-    protected Content getFramesetJavaScript(){
+    protected Content getFramesetJavaScript() {
         HtmlTree script = new HtmlTree(HtmlTag.SCRIPT);
         script.addAttr(HtmlAttr.TYPE, "text/javascript");
-        String scriptCode = DocletConstants.NL + "    targetPage = \"\" + window.location.search;" + DocletConstants.NL +
+        String scriptCode = DocletConstants.NL +
+                "    targetPage = \"\" + window.location.search;" + DocletConstants.NL +
                 "    if (targetPage != \"\" && targetPage != \"undefined\")" + DocletConstants.NL +
                 "        targetPage = targetPage.substring(1);" + DocletConstants.NL +
                 "    if (targetPage.indexOf(\":\") != -1)" + DocletConstants.NL +
@@ -400,16 +402,6 @@
         return title;
     }
 
-    /**
-     * Return, text passed, with Italics &lt;i&gt; and &lt;/i&gt; tags, surrounding it.
-     * So if the text passed is "Hi", then string returned will be "&lt;i&gt;Hi&lt;/i&gt;".
-     *
-     * @param text String to be printed in between &lt;I&gt; and &lt;/I&gt; tags.
-     */
-    public String italicsText(String text) {
-        return "<i>" + text + "</i>";
-    }
-
     public String codeText(String text) {
         return "<code>" + text + "</code>";
     }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/RawHtml.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/RawHtml.java
index 8ad3c40..6b4fc6e 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/RawHtml.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/RawHtml.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,7 @@
  *
  * @author Bhavesh Patel
  */
-public class RawHtml extends Content{
+public class RawHtml extends Content {
 
     private String rawHtmlContent;
 
@@ -90,10 +90,65 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public String toString() {
         return rawHtmlContent;
     }
 
+    private enum State { TEXT, ENTITY, TAG, STRING };
+
+    @Override
+    public int charCount() {
+        return charCount(rawHtmlContent);
+    }
+
+    static int charCount(String htmlText) {
+        State state = State.TEXT;
+        int count = 0;
+        for (int i = 0; i < htmlText.length(); i++) {
+            char c = htmlText.charAt(i);
+            switch (state) {
+                case TEXT:
+                    switch (c) {
+                        case '<':
+                            state = State.TAG;
+                            break;
+                        case '&':
+                            state = State.ENTITY;
+                            count++;
+                            break;
+                        default:
+                            count++;
+                    }
+                    break;
+
+                case ENTITY:
+                    if (!Character.isLetterOrDigit(c))
+                        state = State.TEXT;
+                    break;
+
+                case TAG:
+                    switch (c) {
+                        case '"':
+                            state = State.STRING;
+                            break;
+                        case '>':
+                            state = State.TEXT;
+                            break;
+                    }
+                    break;
+
+                case STRING:
+                    switch (c) {
+                        case '"':
+                            state = State.TAG;
+                            break;
+                    }
+            }
+        }
+        return count;
+    }
+
     /**
      * {@inheritDoc}
      */
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/StringContent.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/StringContent.java
index adddb32..21d67c0 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/StringContent.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/StringContent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,7 @@
  *
  * @author Bhavesh Patel
  */
-public class StringContent extends Content{
+public class StringContent extends Content {
 
     private StringBuilder stringContent;
 
@@ -58,8 +58,8 @@
      * @param initialContent initial content for the object
      */
     public StringContent(String initialContent) {
-        stringContent = new StringBuilder(
-                Util.escapeHtmlChars(nullCheck(initialContent)));
+        stringContent = new StringBuilder();
+        appendChars(initialContent);
     }
 
     /**
@@ -81,7 +81,7 @@
      * @param strContent string content to be added
      */
     public void addContent(String strContent) {
-        stringContent.append(Util.escapeHtmlChars(nullCheck(strContent)));
+        appendChars(strContent);
     }
 
     /**
@@ -91,6 +91,10 @@
         return (stringContent.length() == 0);
     }
 
+    public int charCount() {
+        return RawHtml.charCount(stringContent.toString());
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -107,4 +111,16 @@
         out.write(s);
         return s.endsWith(DocletConstants.NL);
     }
+
+    private void appendChars(String s) {
+        for (int i = 0; i < s.length(); i++) {
+            char ch = s.charAt(i);
+            switch (ch) {
+                case '<': stringContent.append("&lt;");  break;
+                case '>': stringContent.append("&gt;");  break;
+                case '&': stringContent.append("&amp;"); break;
+                default:  stringContent.append(ch);      break;
+            }
+        }
+    }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties
index 1193cf9..f288579 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties
@@ -132,7 +132,7 @@
 doclet.Help_line_14=Use
 doclet.Help_line_15=Each documented package, class and interface has its own Use page.  This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A.  You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.
 doclet.Help_line_16=Tree (Class Hierarchy)
-doclet.Help_line_17_with_tree_link=There is a {0} page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with <code>java.lang.Object</code>. The interfaces do not inherit from <code>java.lang.Object</code>.
+doclet.Help_line_17_with_tree_link=There is a {0} page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with {1}. The interfaces do not inherit from {1}.
 doclet.Help_line_18=When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
 doclet.Help_line_19=When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
 doclet.Help_line_20_with_deprecated_api_link=The {0} page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
@@ -179,7 +179,7 @@
 doclet.ClassUse_ConstructorThrows=Constructors in {1} that throw {0}
 doclet.ClassUse_No.usage.of.0=No usage of {0}
 doclet.Window_ClassUse_Header=Uses of {0} {1}
-doclet.ClassUse_Title=Uses of {0}<br>{1}
+doclet.ClassUse_Title=Uses of {0}
 doclet.navClassUse=Use
 doclet.Error_in_packagelist=Error in using -group option: {0} {1}
 doclet.Groupname_already_used=In -group option, groupname already used: {0}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java
index 493d0e9..b45b944 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java
@@ -27,6 +27,8 @@
 
 import java.io.*;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import com.sun.javadoc.*;
 import com.sun.tools.javac.sym.Profiles;
@@ -825,6 +827,82 @@
         }
     }
 
+    public abstract Content newContent();
+
+    /**
+     * Get the configuration string as a content.
+     *
+     * @param key the key to look for in the configuration file
+     * @return a content tree for the text
+     */
+    public Content getResource(String key) {
+        Content c = newContent();
+        c.addContent(getText(key));
+        return c;
+    }
+
+    /**
+     * Get the configuration string as a content.
+     *
+     * @param key the key to look for in the configuration file
+     * @param o   string or content argument added to configuration text
+     * @return a content tree for the text
+     */
+    public Content getResource(String key, Object o) {
+        return getResource(key, o, null, null);
+    }
+
+    /**
+     * Get the configuration string as a content.
+     *
+     * @param key the key to look for in the configuration file
+     * @param o   string or content argument added to configuration text
+     * @return a content tree for the text
+     */
+    public Content getResource(String key, Object o1, Object o2) {
+        return getResource(key, o1, o2, null);
+    }
+
+    /**
+     * Get the configuration string as a content.
+     *
+     * @param key the key to look for in the configuration file
+     * @param o1  string or content argument added to configuration text
+     * @param o2  string or content argument added to configuration text
+     * @return a content tree for the text
+     */
+    public Content getResource(String key, Object o0, Object o1, Object o2) {
+        Content c = newContent();
+        Pattern p = Pattern.compile("\\{([012])\\}");
+        String text = getText(key);
+        Matcher m = p.matcher(text);
+        int start = 0;
+        while (m.find(start)) {
+            c.addContent(text.substring(start, m.start()));
+
+            Object o = null;
+            switch (m.group(1).charAt(0)) {
+                case '0': o = o0; break;
+                case '1': o = o1; break;
+                case '2': o = o2; break;
+            }
+
+            if (o == null) {
+                c.addContent("{" + m.group(1) + "}");
+            } else if (o instanceof String) {
+                c.addContent((String) o);
+            } else if (o instanceof Content) {
+                c.addContent((Content) o);
+            }
+
+            start = m.end();
+        }
+
+        c.addContent(text.substring(start));
+        return c;
+    }
+
+
     /**
      * Return true if the ClassDoc element is getting documented, depending upon
      * -nodeprecated option and the deprecation information. Return true if
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Content.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Content.java
index 836f7cf..fff0195 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Content.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Content.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -97,6 +97,15 @@
     }
 
     /**
+     * Return the number of characters of plain text content in this object
+     * (optional operation.)
+     * @return the number of characters of plain text content in this
+     */
+    public int charCount() {
+        return 0;
+    }
+
+    /**
      * Checks for null values.
      *
      * @param t reference type to check for null values
@@ -106,32 +115,4 @@
         t.getClass();
         return t;
     }
-
-    /**
-     * Returns true if the content ends with a newline character. Empty content
-     * is considered as ending with new line.
-     *
-     * @param contentBuilder content to test for newline character at the end
-     * @return true if the content ends with newline.
-     */
-    protected boolean endsWithNewLine(StringBuilder contentBuilder) {
-        int contentLength = contentBuilder.length();
-        if (contentLength == 0) {
-            return true;
-        }
-        int nlLength = DocletConstants.NL.length();
-        if (contentLength < nlLength) {
-            return false;
-        }
-        int contentIndex = contentLength - 1;
-        int nlIndex = nlLength - 1;
-        while (nlIndex >= 0) {
-            if (contentBuilder.charAt(contentIndex) != DocletConstants.NL.charAt(nlIndex)) {
-                return false;
-            }
-            contentIndex--;
-            nlIndex--;
-        }
-        return true;
-    }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/PackageSummaryBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/PackageSummaryBuilder.java
index abe2740..b6e8fec 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/PackageSummaryBuilder.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/PackageSummaryBuilder.java
@@ -120,8 +120,7 @@
      * @param contentTree the content tree to which the documentation will be added
      */
     public void buildPackageDoc(XMLNode node, Content contentTree) throws Exception {
-        contentTree = packageWriter.getPackageHeader(
-                Util.getPackageName(packageDoc));
+        contentTree = packageWriter.getPackageHeader(Util.getPackageName(packageDoc));
         buildChildren(node, contentTree);
         packageWriter.addPackageFooter(contentTree);
         packageWriter.printDocument(contentTree);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BasePropertyTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BasePropertyTaglet.java
index b212e5de..e93c902 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BasePropertyTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BasePropertyTaglet.java
@@ -26,6 +26,7 @@
 package com.sun.tools.doclets.internal.toolkit.taglets;
 
 import com.sun.javadoc.Tag;
+import com.sun.tools.doclets.internal.toolkit.Content;
 
 /**
  * An abstract class that implements the {@link Taglet} interface and
@@ -59,15 +60,8 @@
      * @param tagletWriter the taglet writer for output.
      * @return the TagletOutput representation of this <code>Tag</code>.
      */
-    public TagletOutput getTagletOutput(Tag tag, TagletWriter tagletWriter) {
-        TagletOutput tagletOutput = tagletWriter.getOutputInstance();
-        StringBuilder output = new StringBuilder("<P>");
-        output.append(getText(tagletWriter));
-        output.append(" <CODE>");
-        output.append(tag.text());
-        output.append("</CODE>.</P>");
-        tagletOutput.setOutput(output.toString());
-        return tagletOutput;
+    public Content getTagletOutput(Tag tag, TagletWriter tagletWriter) {
+        return tagletWriter.propertyTagOutput(tag, getText(tagletWriter));
     }
 
     /**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BaseTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BaseTaglet.java
index e83ac83..01ba3ec 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BaseTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BaseTaglet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 package com.sun.tools.doclets.internal.toolkit.taglets;
 
 import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
 
 /**
  * An abstract class for that implements the {@link Taglet} interface.
@@ -130,7 +131,7 @@
      * {@inheritDoc}
      * @throws IllegalArgumentException thrown when the method is not supported by the taglet.
      */
-    public TagletOutput getTagletOutput(Tag tag, TagletWriter writer) {
+    public Content getTagletOutput(Tag tag, TagletWriter writer) {
         throw new IllegalArgumentException("Method not supported in taglet " + getName() + ".");
     }
 
@@ -138,7 +139,7 @@
      * {@inheritDoc}
      * @throws IllegalArgumentException thrown when the method is not supported by the taglet.
      */
-    public TagletOutput getTagletOutput(Doc holder, TagletWriter writer) {
+    public Content getTagletOutput(Doc holder, TagletWriter writer) {
         throw new IllegalArgumentException("Method not supported in taglet " + getName() + ".");
     }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/CodeTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/CodeTaglet.java
index 4fec565..5dc5001 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/CodeTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/CodeTaglet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
 
 import java.util.Map;
 import com.sun.javadoc.Tag;
-import com.sun.tools.doclets.Taglet;
+import com.sun.tools.doclets.internal.toolkit.Content;
 
 /**
  * An inline Taglet used to denote literal code fragments.
@@ -49,23 +49,23 @@
  * @since 1.5
  */
 
-public class CodeTaglet extends LiteralTaglet {
+public class CodeTaglet extends BaseInlineTaglet {
 
-        private static final String NAME = "code";
+    private static final String NAME = "code";
 
-        public static void register(Map<String, Taglet> map) {
-                map.remove(NAME);
-                map.put(NAME, new CodeTaglet());
-        }
+    public static void register(Map<String, Taglet> map) {
+        map.remove(NAME);
+        map.put(NAME, new CodeTaglet());
+    }
 
-        public String getName() {
-                return NAME;
-        }
+    public String getName() {
+        return NAME;
+    }
 
-        /*
-         * Wraps @literal's result in a <code> element.
-         */
-        public String toString(Tag tag) {
-                return "<code>" + super.toString(tag) + "</code>";
-        }
+    /**
+     * {@inheritDoc}
+     */
+    public Content getTagletOutput(Tag tag, TagletWriter writer) {
+        return writer.codeTagOutput(tag);
+    }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/DeprecatedTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/DeprecatedTaglet.java
index fc7fc24..258fe72 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/DeprecatedTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/DeprecatedTaglet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 package com.sun.tools.doclets.internal.toolkit.taglets;
 
 import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
 
 /**
  * A taglet that represents the @deprecated tag.
@@ -48,7 +49,7 @@
     /**
      * {@inheritDoc}
      */
-    public TagletOutput getTagletOutput(Doc holder, TagletWriter writer) {
+    public Content getTagletOutput(Doc holder, TagletWriter writer) {
         return writer.deprecatedTagOutput(holder);
     }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/DocRootTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/DocRootTaglet.java
index 8998f26..1a64127 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/DocRootTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/DocRootTaglet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -26,6 +26,7 @@
 package com.sun.tools.doclets.internal.toolkit.taglets;
 
 import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
 
 /**
  * An inline Taglet representing {&#064;docRoot}.  This taglet is
@@ -60,7 +61,7 @@
      * @param writer a {@link TagletWriter} Taglet writer.
      * @return the string representation of this <code>Tag</code>.
      */
-    public TagletOutput getTagletOutput(Tag tag, TagletWriter writer) {
+    public Content getTagletOutput(Tag tag, TagletWriter writer) {
         return writer.getDocRootOutput();
     }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ExpertTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ExpertTaglet.java
deleted file mode 100644
index 96e5627..0000000
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ExpertTaglet.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.doclets.internal.toolkit.taglets;
-
-import java.util.Map;
-
-import com.sun.tools.doclets.Taglet;
-import com.sun.javadoc.Tag;
-
-/**
- * An inline Taglet used to denote information for experts.
- *
- *  <p><b>This is NOT part of any supported API.
- *  If you write code that depends on this, you do so at your own risk.
- *  This code and its internal interfaces are subject to change or
- *  deletion without notice.</b>
- *
- */
-public class ExpertTaglet implements Taglet {
-
-    private static final String NAME = "expert";
-    private static final String START_TAG = "<sub id=\"expert\">";
-    private static final String END_TAG = "</sub>";
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean inField() {
-        return true;
-    }
-
-    public boolean inConstructor() {
-        return true;
-    }
-
-    public boolean inMethod() {
-        return true;
-    }
-
-    public boolean inOverview() {
-        return true;
-    }
-
-    public boolean inPackage() {
-        return true;
-    }
-
-    public boolean inType() {
-        return true;
-    }
-
-    public boolean isInlineTag() {
-        return false;
-    }
-
-    public String getName() {
-        return NAME;
-    }
-
-    public static void register(Map<String, Taglet> map) {
-        map.remove(NAME);
-        map.put(NAME, new ExpertTaglet());
-    }
-
-    public String toString(Tag tag) {
-        return (tag.text() == null || tag.text().length() == 0) ? null :
-            START_TAG + LiteralTaglet.textToString(tag.text()) + END_TAG;
-    }
-
-
-    public String toString(Tag[] tags) {
-        if (tags == null || tags.length == 0) return null;
-
-        StringBuffer sb = new StringBuffer(START_TAG);
-
-        for(Tag t:tags) {
-            sb.append(LiteralTaglet.textToString(t.text()));
-        }
-        sb.append(END_TAG);
-        return sb.toString();
-    }
-
-}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/InheritDocTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/InheritDocTaglet.java
index 65924bb..357a083 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/InheritDocTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/InheritDocTaglet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -27,6 +27,7 @@
 
 import com.sun.javadoc.*;
 import com.sun.tools.doclets.internal.toolkit.Configuration;
+import com.sun.tools.doclets.internal.toolkit.Content;
 import com.sun.tools.doclets.internal.toolkit.util.*;
 
 /**
@@ -60,8 +61,8 @@
 
     /**
      * Will return false because this inline tag may
-     * only appear in Methods.
-     * @return false since this is not a method.
+     * not appear in Fields.
+     * @return false
      */
     public boolean inField() {
         return false;
@@ -69,8 +70,8 @@
 
     /**
      * Will return false because this inline tag may
-     * only appear in Methods.
-     * @return false since this is not a method.
+     * not appear in Constructors.
+     * @return false
      */
     public boolean inConstructor() {
         return false;
@@ -78,8 +79,8 @@
 
     /**
      * Will return false because this inline tag may
-     * only appear in Methods.
-     * @return false since this is not a method.
+     * not appear in Overview.
+     * @return false
      */
     public boolean inOverview() {
         return false;
@@ -87,20 +88,20 @@
 
     /**
      * Will return false because this inline tag may
-     * only appear in Methods.
-     * @return false since this is not a method.
+     * not appear in Packages.
+     * @return false
      */
     public boolean inPackage() {
         return false;
     }
 
     /**
-     * Will return false because this inline tag may
-     * only appear in Methods.
-     * @return false since this is not a method.
+     * Will return true because this inline tag may
+     * appear in Type (Class).
+     * @return true
      */
     public boolean inType() {
-        return false;
+        return true;
     }
 
     /**
@@ -109,33 +110,44 @@
      * of @inheritDoc with documentation from it's superclass or superinterface.
      *
      * @param writer the writer that is writing the output.
-     * @param md the {@link MethodDoc} that we are documenting.
-     * @param holderTag the tag that holds the inheritDoc tag.
+     * @param ped the {@link ProgramElementDoc} that we are documenting.
+     * @param holderTag the tag that holds the inheritDoc tag or null for type
+     * (class) docs.
      * @param isFirstSentence true if we only want to inherit the first sentence.
      */
-    private TagletOutput retrieveInheritedDocumentation(TagletWriter writer,
-            MethodDoc md, Tag holderTag, boolean isFirstSentence) {
-        TagletOutput replacement = writer.getTagletOutputInstance();
+    private Content retrieveInheritedDocumentation(TagletWriter writer,
+            ProgramElementDoc ped, Tag holderTag, boolean isFirstSentence) {
+        Content replacement = writer.getOutputInstance();
 
         Configuration configuration = writer.configuration();
         Taglet inheritableTaglet = holderTag == null ?
             null : configuration.tagletManager.getTaglet(holderTag.name());
         if (inheritableTaglet != null &&
             !(inheritableTaglet instanceof InheritableTaglet)) {
+                String message = ped.name() +
+                    ((ped instanceof ExecutableMemberDoc)
+                        ? ((ExecutableMemberDoc)ped).flatSignature()
+                        : "");
                 //This tag does not support inheritence.
-                configuration.message.warning(md.position(),
-                "doclet.noInheritedDoc", md.name() + md.flatSignature());
+                configuration.message.warning(ped.position(),
+                "doclet.noInheritedDoc", message);
          }
         DocFinder.Output inheritedDoc =
-            DocFinder.search(new DocFinder.Input(md,
+            DocFinder.search(new DocFinder.Input(ped,
                 (InheritableTaglet) inheritableTaglet, holderTag,
                 isFirstSentence, true));
-        if (inheritedDoc.isValidInheritDocTag == false) {
-            configuration.message.warning(md.position(),
-                "doclet.noInheritedDoc", md.name() + md.flatSignature());
-        } else if (inheritedDoc.inlineTags.length > 0) {
-            replacement = writer.commentTagsToOutput(inheritedDoc.holderTag,
-                inheritedDoc.holder, inheritedDoc.inlineTags, isFirstSentence);
+        if (inheritedDoc.isValidInheritDocTag) {
+            if (inheritedDoc.inlineTags.length > 0) {
+                replacement = writer.commentTagsToOutput(inheritedDoc.holderTag,
+                    inheritedDoc.holder, inheritedDoc.inlineTags, isFirstSentence);
+            }
+        } else {
+            String message = ped.name() +
+                    ((ped instanceof ExecutableMemberDoc)
+                        ? ((ExecutableMemberDoc)ped).flatSignature()
+                        : "");
+            configuration.message.warning(ped.position(),
+                "doclet.noInheritedDoc", message);
         }
         return replacement;
     }
@@ -146,14 +158,14 @@
      * to the generated page.
      * @param tag the <code>Tag</code> representation of this custom tag.
      * @param tagletWriter the taglet writer for output.
-     * @return the TagletOutput representation of this <code>Tag</code>.
+     * @return the Content representation of this <code>Tag</code>.
      */
-    public TagletOutput getTagletOutput(Tag tag, TagletWriter tagletWriter) {
-        if (! (tag.holder() instanceof MethodDoc)) {
+    public Content getTagletOutput(Tag tag, TagletWriter tagletWriter) {
+        if (! (tag.holder() instanceof ProgramElementDoc)) {
             return tagletWriter.getOutputInstance();
         }
         return tag.name().equals("@inheritDoc") ?
-                retrieveInheritedDocumentation(tagletWriter, (MethodDoc) tag.holder(), null, tagletWriter.isFirstSentence) :
-                retrieveInheritedDocumentation(tagletWriter, (MethodDoc) tag.holder(), tag, tagletWriter.isFirstSentence);
+                retrieveInheritedDocumentation(tagletWriter, (ProgramElementDoc) tag.holder(), null, tagletWriter.isFirstSentence) :
+                retrieveInheritedDocumentation(tagletWriter, (ProgramElementDoc) tag.holder(), tag, tagletWriter.isFirstSentence);
     }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LegacyTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LegacyTaglet.java
index 2955406..2691c2b 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LegacyTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LegacyTaglet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
 package com.sun.tools.doclets.internal.toolkit.taglets;
 
 import com.sun.javadoc.*;
+import com.sun.tools.doclets.formats.html.markup.RawHtml;
+import com.sun.tools.doclets.internal.toolkit.Content;
 
 /**
  * This taglet acts as a wrapper to enable
@@ -115,20 +117,20 @@
     /**
      * {@inheritDoc}
      */
-    public TagletOutput getTagletOutput(Tag tag, TagletWriter writer)
+    public Content getTagletOutput(Tag tag, TagletWriter writer)
             throws IllegalArgumentException {
-        TagletOutput output = writer.getOutputInstance();
-        output.setOutput(legacyTaglet.toString(tag));
+        Content output = writer.getOutputInstance();
+        output.addContent(new RawHtml(legacyTaglet.toString(tag)));
         return output;
     }
 
     /**
      * {@inheritDoc}
      */
-    public TagletOutput getTagletOutput(Doc holder, TagletWriter writer)
+    public Content getTagletOutput(Doc holder, TagletWriter writer)
             throws IllegalArgumentException {
-        TagletOutput output = writer.getOutputInstance();
-        output.setOutput(legacyTaglet.toString(holder.tags(getName())));
+        Content output = writer.getOutputInstance();
+        output.addContent(new RawHtml(legacyTaglet.toString(holder.tags(getName()))));
         return output;
     }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LiteralTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LiteralTaglet.java
index 75cc3cf..8f3d6e6 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LiteralTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LiteralTaglet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,9 @@
 package com.sun.tools.doclets.internal.toolkit.taglets;
 
 import java.util.Map;
+
 import com.sun.javadoc.Tag;
-import com.sun.tools.doclets.Taglet;
+import com.sun.tools.doclets.internal.toolkit.Content;
 
 
 /**
@@ -47,60 +48,23 @@
  * @since 1.5
  */
 
-public class LiteralTaglet implements Taglet {
+public class LiteralTaglet extends BaseInlineTaglet {
 
     private static final String NAME = "literal";
 
-    public static void register(Map<String,Taglet> map) {
-           map.remove(NAME);
-           map.put(NAME, new LiteralTaglet());
+    public static void register(Map<String, Taglet> map) {
+        map.remove(NAME);
+        map.put(NAME, new LiteralTaglet());
     }
 
     public String getName() {
         return NAME;
     }
 
-    public String toString(Tag tag) {
-        return textToString(tag.text());
-    }
-
-    public String toString(Tag[] tags) { return null; }
-
-    public boolean inField() { return false; }
-
-    public boolean inConstructor() { return false; }
-
-    public boolean inMethod() { return false; }
-
-    public boolean inOverview() { return false; }
-
-    public boolean inPackage() { return false; }
-
-    public boolean inType() { return false; }
-
-    public boolean isInlineTag() { return true; }
-
-    /*
-     * Replace occurrences of the following characters:  < > &
+    /**
+     * {@inheritDoc}
      */
-    protected static String textToString(String text) {
-           StringBuilder buf = new StringBuilder();
-           for (int i = 0; i < text.length(); i++) {
-               char c = text.charAt(i);
-               switch (c) {
-                   case '<':
-                          buf.append("&lt;");
-                          break;
-                   case '>':
-                          buf.append("&gt;");
-                          break;
-                   case '&':
-                          buf.append("&amp;");
-                          break;
-                   default:
-                          buf.append(c);
-               }
-           }
-           return buf.toString();
+    public Content getTagletOutput(Tag tag, TagletWriter writer) {
+        return writer.literalTagOutput(tag);
     }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ParamTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ParamTaglet.java
index ad4bf8b..557d89c 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ParamTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ParamTaglet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -28,6 +28,7 @@
 import java.util.*;
 
 import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
 import com.sun.tools.doclets.internal.toolkit.util.*;
 
 /**
@@ -101,14 +102,14 @@
             }
         }
         ParamTag[] tags = input.isTypeVariableParamTag ?
-            input.method.typeParamTags() : input.method.paramTags();
+            ((MethodDoc)input.element).typeParamTags() : ((MethodDoc)input.element).paramTags();
         Map<String, String> rankMap = getRankMap(input.isTypeVariableParamTag ?
-            (Object[]) input.method.typeParameters() :
-            (Object[]) input.method.parameters());
+            (Object[]) ((MethodDoc)input.element).typeParameters() :
+            (Object[]) ((MethodDoc)input.element).parameters());
         for (int i = 0; i < tags.length; i++) {
             if (rankMap.containsKey(tags[i].parameterName()) &&
                     rankMap.get(tags[i].parameterName()).equals((input.tagId))) {
-                output.holder = input.method;
+                output.holder = input.element;
                 output.holderTag = tags[i];
                 output.inlineTags = input.isFirstSentence ?
                     tags[i].firstSentenceTags() : tags[i].inlineTags();
@@ -165,12 +166,12 @@
      * @param writer the TagletWriter that will write this tag.
      * @return the TagletOutput representation of these <code>ParamTag</code>s.
      */
-    public TagletOutput getTagletOutput(Doc holder, TagletWriter writer) {
+    public Content getTagletOutput(Doc holder, TagletWriter writer) {
         if (holder instanceof ExecutableMemberDoc) {
             ExecutableMemberDoc member = (ExecutableMemberDoc) holder;
-            TagletOutput output = getTagletOutput(false, member, writer,
+            Content output = getTagletOutput(false, member, writer,
                 member.typeParameters(), member.typeParamTags());
-            output.appendOutput(getTagletOutput(true, member, writer,
+            output.addContent(getTagletOutput(true, member, writer,
                 member.parameters(), member.paramTags()));
             return output;
         } else {
@@ -191,12 +192,12 @@
      *
      * @return the TagletOutput representation of these <code>ParamTag</code>s.
      */
-    private TagletOutput getTagletOutput(boolean isNonTypeParams, Doc holder,
+    private Content getTagletOutput(boolean isNonTypeParams, Doc holder,
             TagletWriter writer, Object[] formalParameters, ParamTag[] paramTags) {
-        TagletOutput result = writer.getOutputInstance();
+        Content result = writer.getOutputInstance();
         Set<String> alreadyDocumented = new HashSet<String>();
         if (paramTags.length > 0) {
-            result.appendOutput(
+            result.addContent(
                 processParamTags(isNonTypeParams, paramTags,
                 getRankMap(formalParameters), writer, alreadyDocumented)
             );
@@ -204,7 +205,7 @@
         if (alreadyDocumented.size() != formalParameters.length) {
             //Some parameters are missing corresponding @param tags.
             //Try to inherit them.
-            result.appendOutput(getInheritedTagletOutput (isNonTypeParams, holder,
+            result.addContent(getInheritedTagletOutput (isNonTypeParams, holder,
                 writer, formalParameters, alreadyDocumented));
         }
         return result;
@@ -214,10 +215,10 @@
      * Loop through each indivitual parameter.  It it does not have a
      * corresponding param tag, try to inherit it.
      */
-    private TagletOutput getInheritedTagletOutput(boolean isNonTypeParams, Doc holder,
+    private Content getInheritedTagletOutput(boolean isNonTypeParams, Doc holder,
             TagletWriter writer, Object[] formalParameters,
             Set<String> alreadyDocumented) {
-        TagletOutput result = writer.getOutputInstance();
+        Content result = writer.getOutputInstance();
         if ((! alreadyDocumented.contains(null)) &&
                 holder instanceof MethodDoc) {
             for (int i = 0; i < formalParameters.length; i++) {
@@ -231,7 +232,7 @@
                         String.valueOf(i), ! isNonTypeParams));
                 if (inheritedDoc.inlineTags != null &&
                         inheritedDoc.inlineTags.length > 0) {
-                    result.appendOutput(
+                    result.addContent(
                         processParamTag(isNonTypeParams, writer,
                             (ParamTag) inheritedDoc.holderTag,
                             isNonTypeParams ?
@@ -261,12 +262,12 @@
      *                of a rank of a parameter to its name.  This is
      *                used to ensure that the right name is used
      *                when parameter documentation is inherited.
-     * @return the TagletOutput representation of this <code>Tag</code>.
+     * @return the Content representation of this <code>Tag</code>.
      */
-    private TagletOutput processParamTags(boolean isNonTypeParams,
+    private Content processParamTags(boolean isNonTypeParams,
             ParamTag[] paramTags, Map<String, String> rankMap, TagletWriter writer,
             Set<String> alreadyDocumented) {
-        TagletOutput result = writer.getOutputInstance();
+        Content result = writer.getOutputInstance();
         if (paramTags.length > 0) {
             for (int i = 0; i < paramTags.length; ++i) {
                 ParamTag pt = paramTags[i];
@@ -287,7 +288,7 @@
                            "doclet.Type_Parameters_dup_warn",
                        paramName);
                 }
-                result.appendOutput(processParamTag(isNonTypeParams, writer, pt,
+                result.addContent(processParamTag(isNonTypeParams, writer, pt,
                      pt.parameterName(), alreadyDocumented.size() == 0));
                 alreadyDocumented.add(rank);
             }
@@ -295,7 +296,7 @@
         return result;
     }
     /**
-     * Convert the individual ParamTag into TagletOutput.
+     * Convert the individual ParamTag into Content.
      *
      * @param isNonTypeParams true if this is just a regular param tag.  False
      *                        if this is a type param tag.
@@ -307,16 +308,16 @@
      * @param isFirstParam    true if this is the first param tag being printed.
      *
      */
-    private TagletOutput processParamTag(boolean isNonTypeParams,
+    private Content processParamTag(boolean isNonTypeParams,
             TagletWriter writer, ParamTag paramTag, String name,
             boolean isFirstParam) {
-        TagletOutput result = writer.getOutputInstance();
+        Content result = writer.getOutputInstance();
         String header = writer.configuration().getText(
             isNonTypeParams ? "doclet.Parameters" : "doclet.TypeParameters");
         if (isFirstParam) {
-            result.appendOutput(writer.getParamHeader(header));
+            result.addContent(writer.getParamHeader(header));
         }
-        result.appendOutput(writer.paramTagOutput(paramTag,
+        result.addContent(writer.paramTagOutput(paramTag,
             name));
         return result;
     }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ReturnTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ReturnTaglet.java
index 9d98a96..1e9e18f 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ReturnTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ReturnTaglet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -26,6 +26,7 @@
 package com.sun.tools.doclets.internal.toolkit.taglets;
 
 import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
 import com.sun.tools.doclets.internal.toolkit.util.*;
 
 /**
@@ -50,9 +51,9 @@
      * {@inheritDoc}
      */
     public void inherit(DocFinder.Input input, DocFinder.Output output) {
-       Tag[] tags = input.method.tags("return");
+       Tag[] tags = input.element.tags("return");
         if (tags.length > 0) {
-            output.holder = input.method;
+            output.holder = input.element;
             output.holderTag = tags[0];
             output.inlineTags = input.isFirstSentence ?
                 tags[0].firstSentenceTags() : tags[0].inlineTags();
@@ -73,7 +74,7 @@
     /**
      * {@inheritDoc}
      */
-    public TagletOutput getTagletOutput(Doc holder, TagletWriter writer) {
+    public Content getTagletOutput(Doc holder, TagletWriter writer) {
         Type returnType = ((MethodDoc) holder).returnType();
         Tag[] tags = holder.tags(name);
 
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SeeTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SeeTaglet.java
index 4e3e810..de88897 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SeeTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SeeTaglet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -26,6 +26,7 @@
 package com.sun.tools.doclets.internal.toolkit.taglets;
 
 import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
 import com.sun.tools.doclets.internal.toolkit.util.*;
 
 /**
@@ -49,9 +50,9 @@
      * {@inheritDoc}
      */
     public void inherit(DocFinder.Input input, DocFinder.Output output) {
-        Tag[] tags = input.method.seeTags();
+        Tag[] tags = input.element.seeTags();
         if (tags.length > 0) {
-            output.holder = input.method;
+            output.holder = input.element;
             output.holderTag = tags[0];
             output.inlineTags = input.isFirstSentence ?
                 tags[0].firstSentenceTags() : tags[0].inlineTags();
@@ -61,7 +62,7 @@
     /**
      * {@inheritDoc}
      */
-    public TagletOutput getTagletOutput(Doc holder, TagletWriter writer) {
+    public Content getTagletOutput(Doc holder, TagletWriter writer) {
         SeeTag[] tags = holder.seeTags();
         if (tags.length == 0 && holder instanceof MethodDoc) {
             DocFinder.Output inheritedDoc =
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SimpleTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SimpleTaglet.java
index 4b21cbd..e201eb6 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SimpleTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SimpleTaglet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -26,6 +26,8 @@
 package com.sun.tools.doclets.internal.toolkit.taglets;
 
 import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
+import com.sun.tools.doclets.internal.toolkit.util.DocFinder;
 
 /**
  * A simple single argument custom tag.
@@ -38,7 +40,7 @@
  * @author Jamie Ho
  */
 
-public class SimpleTaglet extends BaseTaglet {
+public class SimpleTaglet extends BaseTaglet implements InheritableTaglet {
 
     /**
      * The marker in the location string for excluded tags.
@@ -199,17 +201,28 @@
         return false;
     }
 
+    @Override
+    public void inherit(DocFinder.Input input, DocFinder.Output output) {
+        Tag[] tags = input.element.tags(tagName);
+        if (tags.length > 0) {
+            output.holder = input.element;
+            output.holderTag = tags[0];
+            output.inlineTags = input.isFirstSentence
+                    ? tags[0].firstSentenceTags() : tags[0].inlineTags();
+        }
+    }
+
     /**
      * {@inheritDoc}
      */
-    public TagletOutput getTagletOutput(Tag tag, TagletWriter writer) {
+    public Content getTagletOutput(Tag tag, TagletWriter writer) {
         return header == null || tag == null ? null : writer.simpleTagOutput(tag, header);
     }
 
     /**
      * {@inheritDoc}
      */
-    public TagletOutput getTagletOutput(Doc holder, TagletWriter writer) {
+    public Content getTagletOutput(Doc holder, TagletWriter writer) {
         if (header == null || holder.tags(getName()).length == 0) {
             return null;
         }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/Taglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/Taglet.java
index 1e2664a..e10e21a 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/Taglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/Taglet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 package com.sun.tools.doclets.internal.toolkit.taglets;
 
 import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
 
 /**
  * The interface for a custom tag used by Doclets. A custom
@@ -132,14 +133,14 @@
 
     /**
      * Given the <code>Tag</code> representation of this custom
-     * tag, return its TagletOutput representation, which is output
+     * tag, return its Content representation, which is output
      * to the generated page.
      * @param tag the <code>Tag</code> representation of this custom tag.
      * @param writer a {@link TagletWriter} Taglet writer.
      * @throws IllegalArgumentException thrown when the method is not supported by the taglet.
-     * @return the TagletOutput representation of this <code>Tag</code>.
+     * @return the Content representation of this <code>Tag</code>.
      */
-    public abstract TagletOutput getTagletOutput(Tag tag, TagletWriter writer) throws IllegalArgumentException;
+    public abstract Content getTagletOutput(Tag tag, TagletWriter writer) throws IllegalArgumentException;
 
     /**
      * Given a <code>Doc</code> object, check if it holds any tags of
@@ -150,6 +151,8 @@
      * @throws IllegalArgumentException thrown when the method is not supported by the taglet.
      * @return the TagletOutput representation of this <code>Tag</code>.
      */
-    public abstract TagletOutput getTagletOutput(Doc holder, TagletWriter writer) throws IllegalArgumentException;
+    public abstract Content getTagletOutput(Doc holder, TagletWriter writer) throws IllegalArgumentException;
 
+    @Override
+    public abstract String toString();
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java
index 7b928fa..377cd67 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java
@@ -158,8 +158,7 @@
 
     /**
      * True if we want to use JavaFX-related tags (@propertyGetter,
-     * @propertySetter, @propertyDescription, @defaultValue, @treatAsPrivate,
-     * @expert).
+     * @propertySetter, @propertyDescription, @defaultValue, @treatAsPrivate).
      */
     private boolean javafx;
 
@@ -184,7 +183,7 @@
         this.showauthor = showauthor;
         this.javafx = javafx;
         this.message = message;
-        initStandardTags();
+        initStandardTaglets();
         initStandardTagsLowercase();
     }
 
@@ -454,9 +453,9 @@
      * @return the array of <code>Taglet</code>s that can
      * appear in packages.
      */
-    public Taglet[] getPackageCustomTags() {
+    public Taglet[] getPackageCustomTaglets() {
         if (packageTags == null) {
-            initCustomTagArrays();
+            initCustomTagletArrays();
         }
         return packageTags;
     }
@@ -467,9 +466,9 @@
      * @return the array of <code>Taglet</code>s that can
      * appear in classes or interfaces.
      */
-    public Taglet[] getTypeCustomTags() {
+    public Taglet[] getTypeCustomTaglets() {
         if (typeTags == null) {
-            initCustomTagArrays();
+            initCustomTagletArrays();
         }
         return typeTags;
     }
@@ -480,9 +479,9 @@
      * @return the array of <code>Taglet</code>s that can
      * appear in comments.
      */
-    public Taglet[] getInlineCustomTags() {
+    public Taglet[] getInlineCustomTaglets() {
         if (inlineTags == null) {
-            initCustomTagArrays();
+            initCustomTagletArrays();
         }
         return inlineTags;
     }
@@ -493,9 +492,9 @@
      * @return the array of <code>Taglet</code>s that can
      * appear in field.
      */
-    public Taglet[] getFieldCustomTags() {
+    public Taglet[] getFieldCustomTaglets() {
         if (fieldTags == null) {
-            initCustomTagArrays();
+            initCustomTagletArrays();
         }
         return fieldTags;
     }
@@ -506,9 +505,9 @@
      * @return the array of <code>Taglet</code>s that can
      * appear in the serialized form.
      */
-    public Taglet[] getSerializedFormTags() {
+    public Taglet[] getSerializedFormTaglets() {
         if (serializedFormTags == null) {
-            initCustomTagArrays();
+            initCustomTagletArrays();
         }
         return serializedFormTags;
     }
@@ -517,19 +516,19 @@
      * @return the array of <code>Taglet</code>s that can
      * appear in the given Doc.
      */
-    public Taglet[] getCustomTags(Doc doc) {
+    public Taglet[] getCustomTaglets(Doc doc) {
         if (doc instanceof ConstructorDoc) {
-            return getConstructorCustomTags();
+            return getConstructorCustomTaglets();
         } else if (doc instanceof MethodDoc) {
-            return getMethodCustomTags();
+            return getMethodCustomTaglets();
         } else if (doc instanceof FieldDoc) {
-            return getFieldCustomTags();
+            return getFieldCustomTaglets();
         } else if (doc instanceof ClassDoc) {
-            return getTypeCustomTags();
+            return getTypeCustomTaglets();
         } else if (doc instanceof PackageDoc) {
-            return getPackageCustomTags();
+            return getPackageCustomTaglets();
         } else if (doc instanceof RootDoc) {
-            return getOverviewCustomTags();
+            return getOverviewCustomTaglets();
         }
         return null;
     }
@@ -540,9 +539,9 @@
      * @return the array of <code>Taglet</code>s that can
      * appear in constructors.
      */
-    public Taglet[] getConstructorCustomTags() {
+    public Taglet[] getConstructorCustomTaglets() {
         if (constructorTags == null) {
-            initCustomTagArrays();
+            initCustomTagletArrays();
         }
         return constructorTags;
     }
@@ -553,9 +552,9 @@
      * @return the array of <code>Taglet</code>s that can
      * appear in methods.
      */
-    public Taglet[] getMethodCustomTags() {
+    public Taglet[] getMethodCustomTaglets() {
         if (methodTags == null) {
-            initCustomTagArrays();
+            initCustomTagletArrays();
         }
         return methodTags;
     }
@@ -566,9 +565,9 @@
      * @return the array of <code>Taglet</code>s that can
      * appear in overview.
      */
-    public Taglet[] getOverviewCustomTags() {
+    public Taglet[] getOverviewCustomTaglets() {
         if (overviewTags == null) {
-            initCustomTagArrays();
+            initCustomTagletArrays();
         }
         return overviewTags;
     }
@@ -576,7 +575,7 @@
     /**
      * Initialize the custom tag arrays.
      */
-    private void initCustomTagArrays() {
+    private void initCustomTagletArrays() {
         Iterator<Taglet> it = customTags.values().iterator();
         ArrayList<Taglet> pTags = new ArrayList<Taglet>(customTags.size());
         ArrayList<Taglet> tTags = new ArrayList<Taglet>(customTags.size());
@@ -631,88 +630,72 @@
     /**
      * Initialize standard Javadoc tags for ordering purposes.
      */
-    private void initStandardTags() {
+    private void initStandardTaglets() {
         Taglet temp;
-        customTags.put((temp = new ParamTaglet()).getName(), temp);
-        customTags.put((temp = new ReturnTaglet()).getName(), temp);
-        customTags.put((temp = new ThrowsTaglet()).getName(), temp);
-        customTags.put((temp = new SimpleTaglet("exception",
-            null, SimpleTaglet.METHOD + SimpleTaglet.CONSTRUCTOR)).getName(), temp);
-        if (!nosince) {
-            customTags.put((temp = new SimpleTaglet("since", message.getText("doclet.Since"),
-               SimpleTaglet.ALL)).getName(), temp);
-        }
-        if (showversion) {
-            customTags.put((temp = new SimpleTaglet("version", message.getText("doclet.Version"),
-                SimpleTaglet.PACKAGE + SimpleTaglet.TYPE + SimpleTaglet.OVERVIEW)).getName(), temp);
-        }
-        if (showauthor) {
-            customTags.put((temp = new SimpleTaglet("author", message.getText("doclet.Author"),
-                SimpleTaglet.PACKAGE + SimpleTaglet.TYPE + SimpleTaglet.OVERVIEW)).getName(), temp);
-        }
-        customTags.put((temp = new SimpleTaglet("serialData", message.getText("doclet.SerialData"),
-            SimpleTaglet.EXCLUDED)).getName(), temp);
+        addStandardTaglet(new ParamTaglet());
+        addStandardTaglet(new ReturnTaglet());
+        addStandardTaglet(new ThrowsTaglet());
+        addStandardTaglet(new SimpleTaglet("exception", null,
+                SimpleTaglet.METHOD + SimpleTaglet.CONSTRUCTOR));
+        addStandardTaglet(!nosince, new SimpleTaglet("since", message.getText("doclet.Since"),
+               SimpleTaglet.ALL));
+        addStandardTaglet(showversion, new SimpleTaglet("version", message.getText("doclet.Version"),
+                SimpleTaglet.PACKAGE + SimpleTaglet.TYPE + SimpleTaglet.OVERVIEW));
+        addStandardTaglet(showauthor, new SimpleTaglet("author", message.getText("doclet.Author"),
+                SimpleTaglet.PACKAGE + SimpleTaglet.TYPE + SimpleTaglet.OVERVIEW));
+        addStandardTaglet(new SimpleTaglet("serialData", message.getText("doclet.SerialData"),
+            SimpleTaglet.EXCLUDED));
         customTags.put((temp = new SimpleTaglet("factory", message.getText("doclet.Factory"),
             SimpleTaglet.METHOD)).getName(), temp);
-        customTags.put((temp = new SeeTaglet()).getName(), temp);
+        addStandardTaglet(new SeeTaglet());
         //Standard inline tags
-        customTags.put((temp = new DocRootTaglet()).getName(), temp);
-        customTags.put((temp = new InheritDocTaglet()).getName(), temp);
-        customTags.put((temp = new ValueTaglet()).getName(), temp);
-        customTags.put((temp = new LegacyTaglet(new LiteralTaglet())).getName(),
-            temp);
-        customTags.put((temp = new LegacyTaglet(new CodeTaglet())).getName(),
-            temp);
+        addStandardTaglet(new DocRootTaglet());
+        addStandardTaglet(new InheritDocTaglet());
+        addStandardTaglet(new ValueTaglet());
+        addStandardTaglet(new LiteralTaglet());
+        addStandardTaglet(new CodeTaglet());
 
-        //Keep track of the names of standard tags for error
-        //checking purposes.
-        standardTags.add("param");
-        standardTags.add("return");
-        standardTags.add("throws");
-        standardTags.add("exception");
-        standardTags.add("since");
-        standardTags.add("version");
-        standardTags.add("author");
-        standardTags.add("see");
+        // Keep track of the names of standard tags for error
+        // checking purposes. The following are not handled above.
+        // See, for example, com.sun.tools.javadoc.Comment
         standardTags.add("deprecated");
         standardTags.add("link");
         standardTags.add("linkplain");
-        standardTags.add("inheritDoc");
-        standardTags.add("docRoot");
-        standardTags.add("value");
         standardTags.add("serial");
-        standardTags.add("serialData");
         standardTags.add("serialField");
         standardTags.add("Text");
-        standardTags.add("literal");
-        standardTags.add("code");
 
         if (javafx) {
-            initJavaFXTags();
+            initJavaFXTaglets();
         }
     }
 
     /**
      * Initialize JavaFX-related tags.
      */
-    private void initJavaFXTags() {
-        Taglet temp;
-        customTags.put((temp = new PropertyGetterTaglet()).getName(), temp);
-        customTags.put((temp = new PropertySetterTaglet()).getName(), temp);
-        customTags.put((temp = new SimpleTaglet("propertyDescription", message.getText("doclet.PropertyDescription"),
-            SimpleTaglet.FIELD + SimpleTaglet.METHOD)).getName(), temp);
-        customTags.put((temp = new SimpleTaglet("defaultValue", message.getText("doclet.DefaultValue"),
-            SimpleTaglet.FIELD + SimpleTaglet.METHOD)).getName(), temp);
-        customTags.put((temp = new SimpleTaglet("treatAsPrivate", null,
-                SimpleTaglet.FIELD + SimpleTaglet.METHOD + SimpleTaglet.TYPE)).getName(), temp);
-        customTags.put((temp = new LegacyTaglet(new ExpertTaglet())).getName(), temp);
+    private void initJavaFXTaglets() {
+        addStandardTaglet(new PropertyGetterTaglet());
+        addStandardTaglet(new PropertySetterTaglet());
+        addStandardTaglet(new SimpleTaglet("propertyDescription",
+                message.getText("doclet.PropertyDescription"),
+                SimpleTaglet.FIELD + SimpleTaglet.METHOD));
+        addStandardTaglet(new SimpleTaglet("defaultValue", message.getText("doclet.DefaultValue"),
+            SimpleTaglet.FIELD + SimpleTaglet.METHOD));
+        addStandardTaglet(new SimpleTaglet("treatAsPrivate", null,
+                SimpleTaglet.FIELD + SimpleTaglet.METHOD + SimpleTaglet.TYPE));
+    }
 
-        standardTags.add("propertyGetter");
-        standardTags.add("propertySetter");
-        standardTags.add("propertyDescription");
-        standardTags.add("defaultValue");
-        standardTags.add("treatAsPrivate");
-        standardTags.add("expert");
+    void addStandardTaglet(Taglet taglet) {
+        String name = taglet.getName();
+        customTags.put(name, taglet);
+        standardTags.add(name);
+    }
+
+    void addStandardTaglet(boolean enable, Taglet taglet) {
+        String name = taglet.getName();
+        if (enable)
+            customTags.put(name, taglet);
+        standardTags.add(name);
     }
 
     /**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletOutput.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletOutput.java
deleted file mode 100644
index c7bbef4..0000000
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletOutput.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.doclets.internal.toolkit.taglets;
-
-/**
- * The interface for taglet output.  This interface is needed because
- * different doclets work with different formats of output.  A single taglet can
- * work with any doclet that provides an implementation of taglet output.
- *
- *  <p><b>This is NOT part of any supported API.
- *  If you write code that depends on this, you do so at your own risk.
- *  This code and its internal interfaces are subject to change or
- *  deletion without notice.</b>
- *
- * @author Jamie Ho
- * @since 1.5
- */
-public interface TagletOutput {
-
-    /**
-     * Set the output for the taglet.
-     * @param o an object representing the output.
-     */
-    public abstract void setOutput(Object o);
-
-    /**
-     * Append the given output to this output.
-     * @param o a TagletOutput representing the output.
-     */
-    public abstract void appendOutput(TagletOutput o);
-
-    /**
-     * Return true if this output has any occurances of @inheritDoc.
-     * @return true if inheritDoc tag is found.
-     */
-    public abstract boolean hasInheritDocTag();
-}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletWriter.java
index fe0093f..9f77cc8 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletWriter.java
@@ -53,15 +53,23 @@
     }
 
     /**
-     * @return an instance of the output object.
+     * @return an instance of an output object.
      */
-    public abstract TagletOutput getOutputInstance();
+    public abstract Content getOutputInstance();
+
+    /**
+     * Return the output for a {@code...} tag.
+     *
+     * @param tag the tag.
+     * @return the output of the taglet.
+     */
+    protected abstract Content codeTagOutput(Tag tag);
 
     /**
      * Returns the output for the DocRoot inline tag.
      * @return the output for the DocRoot inline tag.
      */
-    protected abstract TagletOutput getDocRootOutput();
+    protected abstract Content getDocRootOutput();
 
     /**
      * Return the deprecated tag output.
@@ -69,7 +77,15 @@
      * @param doc the doc to write deprecated documentation for.
      * @return the output of the deprecated tag.
      */
-    protected abstract TagletOutput deprecatedTagOutput(Doc doc);
+    protected abstract Content deprecatedTagOutput(Doc doc);
+
+    /**
+     * Return the output for a {@literal...} tag.
+     *
+     * @param tag the tag.
+     * @return the output of the taglet.
+     */
+    protected abstract Content literalTagOutput(Tag tag);
 
     /**
      * Returns {@link MessageRetriever} for output purposes.
@@ -84,7 +100,7 @@
      * @param header the header to display.
      * @return the header for the param tags.
      */
-    protected abstract TagletOutput getParamHeader(String header);
+    protected abstract Content getParamHeader(String header);
 
     /**
      * Return the output for param tags.
@@ -93,16 +109,25 @@
      * @param paramName the name of the parameter.
      * @return the output of the param tag.
      */
-    protected abstract TagletOutput paramTagOutput(ParamTag paramTag,
+    protected abstract Content paramTagOutput(ParamTag paramTag,
         String paramName);
 
     /**
+     * Return the output for property tags.
+     *
+     * @param propertyTag the parameter to document.
+     * @param prefix the text with which to prefix the property name.
+     * @return the output of the param tag.
+     */
+    protected abstract Content propertyTagOutput(Tag propertyTag, String prefix);
+
+    /**
      * Return the return tag output.
      *
      * @param returnTag the return tag to output.
      * @return the output of the return tag.
      */
-    protected abstract TagletOutput returnTagOutput(Tag returnTag);
+    protected abstract Content returnTagOutput(Tag returnTag);
 
     /**
      * Return the see tag output.
@@ -110,7 +135,7 @@
      * @param seeTags the array of See tags.
      * @return the output of the see tags.
      */
-    protected abstract TagletOutput seeTagOutput(Doc holder, SeeTag[] seeTags);
+    protected abstract Content seeTagOutput(Doc holder, SeeTag[] seeTags);
 
     /**
      * Return the output for a simple tag.
@@ -118,7 +143,7 @@
      * @param simpleTags the array of simple tags.
      * @return the output of the simple tags.
      */
-    protected abstract TagletOutput simpleTagOutput(Tag[] simpleTags,
+    protected abstract Content simpleTagOutput(Tag[] simpleTags,
         String header);
 
     /**
@@ -127,14 +152,14 @@
      * @param simpleTag the simple tag.
      * @return the output of the simple tag.
      */
-    protected abstract TagletOutput simpleTagOutput(Tag simpleTag, String header);
+    protected abstract Content simpleTagOutput(Tag simpleTag, String header);
 
     /**
      * Return the header for the throws tag.
      *
      * @return the header for the throws tag.
      */
-    protected abstract TagletOutput getThrowsHeader();
+    protected abstract Content getThrowsHeader();
 
     /**
      * Return the header for the throws tag.
@@ -142,7 +167,7 @@
      * @param throwsTag the throws tag.
      * @return the output of the throws tag.
      */
-    protected abstract TagletOutput throwsTagOutput(ThrowsTag throwsTag);
+    protected abstract Content throwsTagOutput(ThrowsTag throwsTag);
 
     /**
      * Return the output for the throws tag.
@@ -150,7 +175,7 @@
      * @param throwsType the throws type.
      * @return the output of the throws type.
      */
-    protected abstract TagletOutput throwsTagOutput(Type throwsType);
+    protected abstract Content throwsTagOutput(Type throwsType);
 
     /**
      * Return the output for the value tag.
@@ -161,7 +186,7 @@
      *                    constant field itself.
      * @return the output of the value tag.
      */
-    protected abstract TagletOutput valueTagOutput(FieldDoc field,
+    protected abstract Content valueTagOutput(FieldDoc field,
         String constantVal, boolean includeLink);
 
     /**
@@ -175,10 +200,10 @@
      * @param output the output buffer to store the output in.
      */
     public static void genTagOuput(TagletManager tagletManager, Doc doc,
-            Taglet[] taglets, TagletWriter writer, TagletOutput output) {
+            Taglet[] taglets, TagletWriter writer, Content output) {
         tagletManager.checkTags(doc, doc.tags(), false);
         tagletManager.checkTags(doc, doc.inlineTags(), true);
-        TagletOutput currentOutput = null;
+        Content currentOutput = null;
         for (int i = 0; i < taglets.length; i++) {
             currentOutput = null;
             if (doc instanceof ClassDoc && taglets[i] instanceof ParamTaglet) {
@@ -203,7 +228,7 @@
             }
             if (currentOutput != null) {
                 tagletManager.seenCustomTag(taglets[i].getName());
-                output.appendOutput(currentOutput);
+                output.addContent(currentOutput);
             }
         }
     }
@@ -217,16 +242,16 @@
      * @param tagletWriter The taglet writer to write the output.
      * @return The output of the inline tag.
      */
-    public static TagletOutput getInlineTagOuput(TagletManager tagletManager,
+    public static Content getInlineTagOuput(TagletManager tagletManager,
             Tag holderTag, Tag inlineTag, TagletWriter tagletWriter) {
-        Taglet[] definedTags = tagletManager.getInlineCustomTags();
+        Taglet[] definedTags = tagletManager.getInlineCustomTaglets();
         //This is a custom inline tag.
         for (int j = 0; j < definedTags.length; j++) {
             if (("@"+definedTags[j].getName()).equals(inlineTag.name())) {
                 //Given a name of a seen custom tag, remove it from the
                 // set of unseen custom tags.
                 tagletManager.seenCustomTag(definedTags[j].getName());
-                TagletOutput output = definedTags[j].getTagletOutput(
+                Content output = definedTags[j].getTagletOutput(
                     holderTag != null &&
                         definedTags[j].getName().equals("inheritDoc") ?
                             holderTag : inlineTag, tagletWriter);
@@ -245,9 +270,9 @@
      * @param holderTag the tag that holds the documentation.
      * @param tags   array of text tags and inline tags (often alternating)
      *               present in the text of interest for this doc.
-     * @return the {@link TagletOutput} representing the comments.
+     * @return the {@link Content} representing the comments.
      */
-    public abstract TagletOutput commentTagsToOutput(Tag holderTag, Tag[] tags);
+    public abstract Content commentTagsToOutput(Tag holderTag, Tag[] tags);
 
     /**
      * Converts inline tags and text to TagOutput, expanding the
@@ -258,9 +283,9 @@
      * @param holderDoc specific doc where comment resides.
      * @param tags   array of text tags and inline tags (often alternating)
      *               present in the text of interest for this doc.
-     * @return the {@link TagletOutput} representing the comments.
+     * @return the {@link Content} representing the comments.
      */
-    public abstract TagletOutput commentTagsToOutput(Doc holderDoc, Tag[] tags);
+    public abstract Content commentTagsToOutput(Doc holderDoc, Tag[] tags);
 
     /**
      * Converts inline tags and text to TagOutput, expanding the
@@ -273,18 +298,13 @@
      * @param tags   array of text tags and inline tags (often alternating)
      *               present in the text of interest for this doc.
      * @param isFirstSentence true if this is the first sentence.
-     * @return the {@link TagletOutput} representing the comments.
+     * @return the {@link Content} representing the comments.
      */
-    public abstract TagletOutput commentTagsToOutput(Tag holderTag,
+    public abstract Content commentTagsToOutput(Tag holderTag,
         Doc holderDoc, Tag[] tags, boolean isFirstSentence);
 
     /**
      * @return an instance of the configuration used for this doclet.
      */
     public abstract Configuration configuration();
-
-    /**
-     * @return an instance of the taglet output object.
-     */
-    public abstract TagletOutput getTagletOutputInstance();
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ThrowsTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ThrowsTaglet.java
index 7b8b365..dfe1fbb 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ThrowsTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ThrowsTaglet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -28,6 +28,7 @@
 import java.util.*;
 
 import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
 import com.sun.tools.doclets.internal.toolkit.util.*;
 
 /**
@@ -60,15 +61,15 @@
                 throwsTag.exceptionName() :
                 throwsTag.exception().qualifiedName();
         } else {
-            exception = input.method.containingClass().findClass(input.tagId);
+            exception = input.element.containingClass().findClass(input.tagId);
         }
 
-        ThrowsTag[] tags = input.method.throwsTags();
+        ThrowsTag[] tags = ((MethodDoc)input.element).throwsTags();
         for (int i = 0; i < tags.length; i++) {
             if (input.tagId.equals(tags[i].exceptionName()) ||
                 (tags[i].exception() != null &&
                     (input.tagId.equals(tags[i].exception().qualifiedName())))) {
-                output.holder = input.method;
+                output.holder = input.element;
                 output.holderTag = tags[i];
                 output.inlineTags = input.isFirstSentence ?
                     tags[i].firstSentenceTags() : tags[i].inlineTags();
@@ -83,10 +84,10 @@
     /**
      * Add links for exceptions that are declared but not documented.
      */
-    private TagletOutput linkToUndocumentedDeclaredExceptions(
+    private Content linkToUndocumentedDeclaredExceptions(
             Type[] declaredExceptionTypes, Set<String> alreadyDocumented,
             TagletWriter writer) {
-        TagletOutput result = writer.getOutputInstance();
+        Content result = writer.getOutputInstance();
         //Add links to the exceptions declared but not documented.
         for (int i = 0; i < declaredExceptionTypes.length; i++) {
             if (declaredExceptionTypes[i].asClassDoc() != null &&
@@ -95,9 +96,9 @@
                 ! alreadyDocumented.contains(
                     declaredExceptionTypes[i].asClassDoc().qualifiedName())) {
                 if (alreadyDocumented.size() == 0) {
-                    result.appendOutput(writer.getThrowsHeader());
+                    result.addContent(writer.getThrowsHeader());
                 }
-                result.appendOutput(writer.throwsTagOutput(declaredExceptionTypes[i]));
+                result.addContent(writer.throwsTagOutput(declaredExceptionTypes[i]));
                 alreadyDocumented.add(declaredExceptionTypes[i].asClassDoc().name());
             }
         }
@@ -108,10 +109,10 @@
      * Inherit throws documentation for exceptions that were declared but not
      * documented.
      */
-    private TagletOutput inheritThrowsDocumentation(Doc holder,
+    private Content inheritThrowsDocumentation(Doc holder,
             Type[] declaredExceptionTypes, Set<String> alreadyDocumented,
             TagletWriter writer) {
-        TagletOutput result = writer.getOutputInstance();
+        Content result = writer.getOutputInstance();
         if (holder instanceof MethodDoc) {
             Set<Tag> declaredExceptionTags = new LinkedHashSet<Tag>();
             for (int j = 0; j < declaredExceptionTypes.length; j++) {
@@ -125,7 +126,7 @@
                 }
                 declaredExceptionTags.addAll(inheritedDoc.tagList);
             }
-            result.appendOutput(throwsTagsOutput(
+            result.addContent(throwsTagsOutput(
                 declaredExceptionTags.toArray(new ThrowsTag[] {}),
                 writer, alreadyDocumented, false));
         }
@@ -135,18 +136,18 @@
     /**
      * {@inheritDoc}
      */
-    public TagletOutput getTagletOutput(Doc holder, TagletWriter writer) {
+    public Content getTagletOutput(Doc holder, TagletWriter writer) {
         ExecutableMemberDoc execHolder = (ExecutableMemberDoc) holder;
         ThrowsTag[] tags = execHolder.throwsTags();
-        TagletOutput result = writer.getOutputInstance();
+        Content result = writer.getOutputInstance();
         HashSet<String> alreadyDocumented = new HashSet<String>();
         if (tags.length > 0) {
-            result.appendOutput(throwsTagsOutput(
+            result.addContent(throwsTagsOutput(
                 execHolder.throwsTags(), writer, alreadyDocumented, true));
         }
-        result.appendOutput(inheritThrowsDocumentation(holder,
+        result.addContent(inheritThrowsDocumentation(holder,
             execHolder.thrownExceptionTypes(), alreadyDocumented, writer));
-        result.appendOutput(linkToUndocumentedDeclaredExceptions(
+        result.addContent(linkToUndocumentedDeclaredExceptions(
             execHolder.thrownExceptionTypes(), alreadyDocumented, writer));
         return result;
     }
@@ -160,11 +161,11 @@
      * @param alreadyDocumented the set of exceptions that have already
      *        been documented.
      * @param allowDups True if we allow duplicate throws tags to be documented.
-     * @return the TagletOutput representation of this <code>Tag</code>.
+     * @return the Content representation of this <code>Tag</code>.
      */
-    protected TagletOutput throwsTagsOutput(ThrowsTag[] throwTags,
+    protected Content throwsTagsOutput(ThrowsTag[] throwTags,
         TagletWriter writer, Set<String> alreadyDocumented, boolean allowDups) {
-        TagletOutput result = writer.getOutputInstance();
+        Content result = writer.getOutputInstance();
         if (throwTags.length > 0) {
             for (int i = 0; i < throwTags.length; ++i) {
                 ThrowsTag tt = throwTags[i];
@@ -174,9 +175,9 @@
                     continue;
                 }
                 if (alreadyDocumented.size() == 0) {
-                    result.appendOutput(writer.getThrowsHeader());
+                    result.addContent(writer.getThrowsHeader());
                 }
-                result.appendOutput(writer.throwsTagOutput(tt));
+                result.addContent(writer.throwsTagOutput(tt));
                 alreadyDocumented.add(cd != null ?
                     cd.qualifiedName() : tt.exceptionName());
             }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java
index 90794bf..f4d58c8 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -29,6 +29,7 @@
 
 import com.sun.javadoc.*;
 import com.sun.tools.doclets.internal.toolkit.Configuration;
+import com.sun.tools.doclets.internal.toolkit.Content;
 import com.sun.tools.doclets.internal.toolkit.util.*;
 
 /**
@@ -160,7 +161,7 @@
     /**
      * {@inheritDoc}
      */
-    public TagletOutput getTagletOutput(Tag tag, TagletWriter writer) {
+    public Content getTagletOutput(Tag tag, TagletWriter writer) {
         FieldDoc field = getFieldDoc(
             writer.configuration(), tag, tag.text());
         if (field == null) {
@@ -169,7 +170,7 @@
                 "doclet.value_tag_invalid_reference", tag.text());
         } else if (field.constantValue() != null) {
             return writer.valueTagOutput(field,
-                Util.escapeHtmlChars(field.constantValueExpression()),
+                field.constantValueExpression(),
                 ! field.equals(tag.holder()));
         } else {
             //Referenced field is not a constant.
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFinder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFinder.java
index a0e4015..d68b09d 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFinder.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFinder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -48,9 +48,9 @@
      */
     public static class Input {
         /**
-         * The method to search documentation from.
+         * The element to search documentation from.
          */
-        public MethodDoc method = null;
+        public ProgramElementDoc element;
         /**
          * The taglet to search for documentation on behalf of. Null if we want
          * to search for overall documentation.
@@ -84,54 +84,55 @@
          */
         public boolean isTypeVariableParamTag = false;
 
-        public Input() {}
-
-        public Input(MethodDoc method, InheritableTaglet taglet, Tag tag,
+        public Input(ProgramElementDoc element, InheritableTaglet taglet, Tag tag,
                 boolean isFirstSentence, boolean isInheritDocTag) {
-            this.method = method;
+            this(element);
             this.taglet = taglet;
             this.tag = tag;
             this.isFirstSentence = isFirstSentence;
             this.isInheritDocTag = isInheritDocTag;
         }
 
-        public Input(MethodDoc method, InheritableTaglet taglet, String tagId) {
-            this.method = method;
+        public Input(ProgramElementDoc element, InheritableTaglet taglet, String tagId) {
+            this(element);
             this.taglet = taglet;
             this.tagId = tagId;
         }
 
-        public Input(MethodDoc method, InheritableTaglet taglet, String tagId,
+        public Input(ProgramElementDoc element, InheritableTaglet taglet, String tagId,
             boolean isTypeVariableParamTag) {
-            this.method = method;
+            this(element);
             this.taglet = taglet;
             this.tagId = tagId;
             this.isTypeVariableParamTag = isTypeVariableParamTag;
         }
 
-        public Input(MethodDoc method, InheritableTaglet taglet) {
-            this.method = method;
+        public Input(ProgramElementDoc element, InheritableTaglet taglet) {
+            this(element);
             this.taglet = taglet;
         }
 
-        public Input(MethodDoc method) {
-            this.method = method;
+        public Input(ProgramElementDoc element) {
+            if (element == null)
+                throw new NullPointerException();
+            this.element = element;
         }
 
-        public Input(MethodDoc method, boolean isFirstSentence) {
-            this.method = method;
+        public Input(ProgramElementDoc element, boolean isFirstSentence) {
+            this(element);
             this.isFirstSentence = isFirstSentence;
         }
 
         public Input copy() {
-            Input clone = new Input();
-            clone.method = this.method;
+            Input clone = new Input(this.element);
             clone.taglet = this.taglet;
             clone.tagId = this.tagId;
             clone.tag = this.tag;
             clone.isFirstSentence = this.isFirstSentence;
             clone.isInheritDocTag = this.isInheritDocTag;
             clone.isTypeVariableParamTag = this.isTypeVariableParamTag;
+            if (clone.element == null)
+                throw new NullPointerException();
             return clone;
 
         }
@@ -164,8 +165,8 @@
 
         /**
          * When automatically inheriting throws tags, you sometime must inherit
-         * more than one tag.  For example if the method declares that it throws
-         * IOException and the overidden method has throws tags for IOException and
+         * more than one tag.  For example if the element declares that it throws
+         * IOException and the overridden element has throws tags for IOException and
          * ZipException, both tags would be inherited because ZipException is a
          * subclass of IOException.  This subclass of DocFinder.Output allows
          * multiple tag inheritence.
@@ -174,9 +175,9 @@
     }
 
     /**
-     * Search for the requested comments in the given method.  If it does not
-     * have comments, return documentation from the overriden method if possible.
-     * If the overriden method does not exist or does not have documentation to
+     * Search for the requested comments in the given element.  If it does not
+     * have comments, return documentation from the overriden element if possible.
+     * If the overriden element does not exist or does not have documentation to
      * inherit, search for documentation to inherit from implemented methods.
      *
      * @param input the input object used to perform the search.
@@ -186,14 +187,14 @@
     public static Output search(Input input) {
         Output output = new Output();
         if (input.isInheritDocTag) {
-            //Do nothing because "method" does not have any documentation.
+            //Do nothing because "element" does not have any documentation.
             //All it has it {@inheritDoc}.
         } else if (input.taglet == null) {
             //We want overall documentation.
             output.inlineTags = input.isFirstSentence ?
-                input.method.firstSentenceTags() :
-                input.method.inlineTags();
-            output.holder = input.method;
+                input.element.firstSentenceTags() :
+                input.element.inlineTags();
+            output.holder = input.element;
         } else {
             input.taglet.inherit(input, output);
         }
@@ -204,25 +205,38 @@
         output.isValidInheritDocTag = false;
         Input inheritedSearchInput = input.copy();
         inheritedSearchInput.isInheritDocTag = false;
-        if (input.method.overriddenMethod() != null) {
-            inheritedSearchInput.method = input.method.overriddenMethod();
-            output = search(inheritedSearchInput);
-            output.isValidInheritDocTag = true;
-            if (output != null && output.inlineTags.length > 0) {
-                return output;
+        if (input.element instanceof MethodDoc) {
+            MethodDoc overriddenMethod = ((MethodDoc) input.element).overriddenMethod();
+            if (overriddenMethod != null) {
+                inheritedSearchInput.element = overriddenMethod;
+                output = search(inheritedSearchInput);
+                output.isValidInheritDocTag = true;
+                if (output.inlineTags.length > 0) {
+                    return output;
+                }
             }
-        }
-        //NOTE:  When we fix the bug where ClassDoc.interfaceTypes() does
-        //       not pass all implemented interfaces, we will use the
-        //       appropriate method here.
-        MethodDoc[] implementedMethods =
-            (new ImplementedMethods(input.method, null)).build(false);
-        for (int i = 0; i < implementedMethods.length; i++) {
-            inheritedSearchInput.method = implementedMethods[i];
-            output = search(inheritedSearchInput);
-            output.isValidInheritDocTag = true;
-            if (output != null && output.inlineTags.length > 0) {
-                return output;
+            //NOTE:  When we fix the bug where ClassDoc.interfaceTypes() does
+            //       not pass all implemented interfaces, we will use the
+            //       appropriate element here.
+            MethodDoc[] implementedMethods =
+                (new ImplementedMethods((MethodDoc) input.element, null)).build(false);
+            for (int i = 0; i < implementedMethods.length; i++) {
+                inheritedSearchInput.element = implementedMethods[i];
+                output = search(inheritedSearchInput);
+                output.isValidInheritDocTag = true;
+                if (output.inlineTags.length > 0) {
+                    return output;
+                }
+            }
+        } else if (input.element instanceof ClassDoc) {
+            ProgramElementDoc superclass = ((ClassDoc) input.element).superclass();
+            if (superclass != null) {
+                inheritedSearchInput.element = superclass;
+                output = search(inheritedSearchInput);
+                output.isValidInheritDocTag = true;
+                if (output.inlineTags.length > 0) {
+                    return output;
+                }
             }
         }
         return output;
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletConstants.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletConstants.java
index 878a06b..c76b2ed 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletConstants.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletConstants.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,7 @@
     /**
      * The default package name.
      */
-    public static final String DEFAULT_PACKAGE_NAME = "&lt;Unnamed&gt;";
+    public static final String DEFAULT_PACKAGE_NAME = "<Unnamed>";
 
     /**
      * The default package file name.
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
index 7eb0c7f..acdae45 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
@@ -420,69 +420,6 @@
     }
 
     /**
-     * Given a string, escape all special html characters and
-     * return the result.
-     *
-     * @param s The string to check.
-     * @return the original string with all of the HTML characters escaped.
-     */
-    public static String escapeHtmlChars(String s) {
-        for (int i = 0; i < s.length(); i++) {
-            char ch = s.charAt(i);
-            switch (ch) {
-                // only start building a new string if we need to
-                case '<': case '>': case '&':
-                    StringBuilder sb = new StringBuilder(s.substring(0, i));
-                    for ( ; i < s.length(); i++) {
-                        ch = s.charAt(i);
-                        switch (ch) {
-                            case '<': sb.append("&lt;");  break;
-                            case '>': sb.append("&gt;");  break;
-                            case '&': sb.append("&amp;"); break;
-                            default:  sb.append(ch);      break;
-                        }
-                    }
-                    return sb.toString();
-            }
-        }
-        return s;
-    }
-
-    /**
-     * Escape all special html characters in a string buffer.
-     *
-     * @param sb The string buffer to update
-     */
-    public static void escapeHtmlChars(StringBuilder sb) {
-        // scan backwards, replacing characters as needed.
-        for (int i = sb.length() - 1; i >= 0; i--) {
-            switch (sb.charAt(i)) {
-                case '<': sb.replace(i, i+1, "&lt;"); break;
-                case '>': sb.replace(i, i+1, "&gt;"); break;
-                case '&': sb.replace(i, i+1, "&amp;"); break;
-            }
-        }
-    }
-
-    /**
-     * Given a string, strips all html characters and
-     * return the result.
-     *
-     * @param rawString The string to check.
-     * @return the original string with all of the HTML characters
-     * stripped.
-     *
-     */
-    public static String stripHtml(String rawString) {
-        // remove HTML tags
-        rawString = rawString.replaceAll("\\<.*?>", " ");
-        // consolidate multiple spaces between a word to a single space
-        rawString = rawString.replaceAll("\\b\\s{2,}\\b", " ");
-        // remove extra whitespaces
-        return rawString.trim();
-    }
-
-    /**
      * Given an annotation, return true if it should be documented and false
      * otherwise.
      *
@@ -656,20 +593,42 @@
     }
 
     /**
-     * Replace all tabs with the appropriate number of spaces.
+     * Replace all tabs in a string with the appropriate number of spaces.
+     * The string may be a multi-line string.
      * @param configuration the doclet configuration defining the setting for the
      *                      tab length.
-     * @param sb the StringBuilder in which to replace the tabs
+     * @param text the text for which the tabs should be expanded
+     * @return the text with all tabs expanded
      */
-    public static void replaceTabs(Configuration configuration, StringBuilder sb) {
-        int tabLength = configuration.sourcetab;
-        String whitespace = configuration.tabSpaces;
-        int index = 0;
-        while ((index = sb.indexOf("\t", index)) != -1) {
-            int spaceCount = tabLength - index % tabLength;
-            sb.replace(index, index+1, whitespace.substring(0, spaceCount));
-            index += spaceCount;
+    public static String replaceTabs(Configuration configuration, String text) {
+        if (text.indexOf("\t") == -1)
+            return text;
+
+        final int tabLength = configuration.sourcetab;
+        final String whitespace = configuration.tabSpaces;
+        final int textLength = text.length();
+        StringBuilder result = new StringBuilder(textLength);
+        int pos = 0;
+        int lineLength = 0;
+        for (int i = 0; i < textLength; i++) {
+            char ch = text.charAt(i);
+            switch (ch) {
+                case '\n': case '\r':
+                    lineLength = 0;
+                    break;
+                case '\t':
+                    result.append(text, pos, i);
+                    int spaceCount = tabLength - lineLength % tabLength;
+                    result.append(whitespace, 0, spaceCount);
+                    lineLength += spaceCount;
+                    pos = i + 1;
+                    break;
+                default:
+                    lineLength++;
+            }
         }
+        result.append(text, pos, textLength);
+        return result.toString();
     }
 
     /**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkFactory.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkFactory.java
index 97e6fe7..6ecea31 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkFactory.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkFactory.java
@@ -26,6 +26,7 @@
 package com.sun.tools.doclets.internal.toolkit.util.links;
 
 import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Content;
 
 /**
  * A factory that constructs links from given link information.
@@ -41,11 +42,11 @@
 public abstract class LinkFactory {
 
     /**
-     * Return an empty instance of the link output object.
+     * Return an empty instance of a content object.
      *
-     * @return an empty instance of the link output object.
+     * @return an empty instance of a content object.
      */
-    protected abstract LinkOutput getOutputInstance();
+    protected abstract Content newContent();
 
     /**
      * Constructs a link from the given link information.
@@ -53,63 +54,59 @@
      * @param linkInfo the information about the link.
      * @return the output of the link.
      */
-    public LinkOutput getLinkOutput(LinkInfo linkInfo) {
+    public Content getLink(LinkInfo linkInfo) {
         if (linkInfo.type != null) {
             Type type = linkInfo.type;
-            LinkOutput linkOutput = getOutputInstance();
+            Content link = newContent();
             if (type.isPrimitive()) {
                 //Just a primitive.
-                linkInfo.displayLength += type.typeName().length();
-                linkOutput.append(type.typeName());
+                link.addContent(type.typeName());
             } else if (type.asAnnotatedType() != null && type.dimension().length() == 0) {
-                linkOutput.append(getTypeAnnotationLinks(linkInfo));
+                link.addContent(getTypeAnnotationLinks(linkInfo));
                 linkInfo.type = type.asAnnotatedType().underlyingType();
-                linkOutput.append(getLinkOutput(linkInfo));
-                return linkOutput;
+                link.addContent(getLink(linkInfo));
+                return link;
             } else if (type.asWildcardType() != null) {
                 //Wildcard type.
                 linkInfo.isTypeBound = true;
-                linkInfo.displayLength += 1;
-                linkOutput.append("?");
+                link.addContent("?");
                 WildcardType wildcardType = type.asWildcardType();
                 Type[] extendsBounds = wildcardType.extendsBounds();
                 for (int i = 0; i < extendsBounds.length; i++) {
-                    linkInfo.displayLength += i > 0 ? 2 : 9;
-                    linkOutput.append(i > 0 ? ", " : " extends ");
+                    link.addContent(i > 0 ? ", " : " extends ");
                     setBoundsLinkInfo(linkInfo, extendsBounds[i]);
-                    linkOutput.append(getLinkOutput(linkInfo));
+                    link.addContent(getLink(linkInfo));
                 }
                 Type[] superBounds = wildcardType.superBounds();
                 for (int i = 0; i < superBounds.length; i++) {
-                    linkInfo.displayLength += i > 0 ? 2 : 7;
-                    linkOutput.append(i > 0 ? ", " : " super ");
+                    link.addContent(i > 0 ? ", " : " super ");
                     setBoundsLinkInfo(linkInfo, superBounds[i]);
-                    linkOutput.append(getLinkOutput(linkInfo));
+                    link.addContent(getLink(linkInfo));
                 }
             } else if (type.asTypeVariable()!= null) {
-                linkOutput.append(getTypeAnnotationLinks(linkInfo));
+                link.addContent(getTypeAnnotationLinks(linkInfo));
                 linkInfo.isTypeBound = true;
                 //A type variable.
                 Doc owner = type.asTypeVariable().owner();
                 if ((! linkInfo.excludeTypeParameterLinks) &&
                         owner instanceof ClassDoc) {
                     linkInfo.classDoc = (ClassDoc) owner;
-                    linkInfo.label = type.typeName();
-                    linkOutput.append(getClassLink(linkInfo));
+                    Content label = newContent();
+                    label.addContent(type.typeName());
+                    linkInfo.label = label;
+                    link.addContent(getClassLink(linkInfo));
                 } else {
                     //No need to link method type parameters.
-                    linkInfo.displayLength += type.typeName().length();
-                    linkOutput.append(type.typeName());
+                    link.addContent(type.typeName());
                 }
 
                 Type[] bounds = type.asTypeVariable().bounds();
                 if (! linkInfo.excludeTypeBounds) {
                     linkInfo.excludeTypeBounds = true;
                     for (int i = 0; i < bounds.length; i++) {
-                        linkInfo.displayLength += i > 0 ? 2 : 9;
-                        linkOutput.append(i > 0 ? " & " : " extends ");
+                        link.addContent(i > 0 ? " & " : " extends ");
                         setBoundsLinkInfo(linkInfo, bounds[i]);
-                        linkOutput.append(getLinkOutput(linkInfo));
+                        link.addContent(getLink(linkInfo));
                     }
                 }
             } else if (type.asClassDoc() != null) {
@@ -118,15 +115,15 @@
                         linkInfo.excludeTypeBoundsLinks) {
                     //Since we are excluding type parameter links, we should not
                     //be linking to the type bound.
-                    linkInfo.displayLength += type.typeName().length();
-                    linkOutput.append(type.typeName());
-                    linkOutput.append(getTypeParameterLinks(linkInfo));
-                    return linkOutput;
+                    link.addContent(type.typeName());
+                    link.addContent(getTypeParameterLinks(linkInfo));
+                    return link;
                 } else {
                     linkInfo.classDoc = type.asClassDoc();
-                    linkOutput = getClassLink(linkInfo);
+                    link = newContent();
+                    link.addContent(getClassLink(linkInfo));
                     if (linkInfo.includeTypeAsSepLink) {
-                        linkOutput.append(getTypeParameterLinks(linkInfo, false));
+                        link.addContent(getTypeParameterLinks(linkInfo, false));
                     }
                 }
             }
@@ -135,36 +132,37 @@
                 if (type.dimension().length() > 2) {
                     //Javadoc returns var args as array.
                     //Strip out the first [] from the var arg.
-                    linkInfo.displayLength += type.dimension().length()-2;
-                    linkOutput.append(type.dimension().substring(2));
+                    link.addContent(type.dimension().substring(2));
                 }
-                linkInfo.displayLength += 3;
-                linkOutput.append("...");
+                link.addContent("...");
             } else {
                 while (type != null && type.dimension().length() > 0) {
-                    linkInfo.displayLength += type.dimension().length();
                     if (type.asAnnotatedType() != null) {
                         linkInfo.type = type;
-                        linkOutput.append(" ");
-                        linkOutput.append(getTypeAnnotationLinks(linkInfo));
-                        linkOutput.append("[]");
+                        link.addContent(" ");
+                        link.addContent(getTypeAnnotationLinks(linkInfo));
+                        link.addContent("[]");
                         type = type.asAnnotatedType().underlyingType().getElementType();
                     } else {
-                        linkOutput.append("[]");
+                        link.addContent("[]");
                         type = type.getElementType();
                     }
                 }
                 linkInfo.type = type;
-                linkOutput.insert(0, getTypeAnnotationLinks(linkInfo));
+                Content newLink = newContent();
+                newLink.addContent(getTypeAnnotationLinks(linkInfo));
+                newLink.addContent(link);
+                link = newLink;
             }
-            return linkOutput;
+            return link;
         } else if (linkInfo.classDoc != null) {
             //Just a class link
-            LinkOutput linkOutput = getClassLink(linkInfo);
+            Content link = newContent();
+            link.addContent(getClassLink(linkInfo));
             if (linkInfo.includeTypeAsSepLink) {
-                linkOutput.append(getTypeParameterLinks(linkInfo, false));
+                link.addContent(getTypeParameterLinks(linkInfo, false));
             }
-            return linkOutput;
+            return link;
         } else {
             return null;
         }
@@ -183,7 +181,7 @@
      *
      * @return the link for the given class.
      */
-    protected abstract LinkOutput getClassLink(LinkInfo linkInfo);
+    protected abstract Content getClassLink(LinkInfo linkInfo);
 
     /**
      * Return the link to the given type parameter.
@@ -191,10 +189,10 @@
      * @param linkInfo     the information about the link to construct.
      * @param typeParam the type parameter to link to.
      */
-    protected abstract LinkOutput getTypeParameterLink(LinkInfo linkInfo,
+    protected abstract Content getTypeParameterLink(LinkInfo linkInfo,
         Type typeParam);
 
-    protected abstract LinkOutput getTypeAnnotationLink(LinkInfo linkInfo,
+    protected abstract Content getTypeAnnotationLink(LinkInfo linkInfo,
             AnnotationDesc annotation);
 
     /**
@@ -203,7 +201,7 @@
      * @param linkInfo     the information about the link to construct.
      * @return the links to the type parameters.
      */
-    public LinkOutput getTypeParameterLinks(LinkInfo linkInfo) {
+    public Content getTypeParameterLinks(LinkInfo linkInfo) {
         return getTypeParameterLinks(linkInfo, true);
     }
 
@@ -215,8 +213,8 @@
      *                     the type parameters portion of the link.
      * @return the links to the type parameters.
      */
-    public LinkOutput getTypeParameterLinks(LinkInfo linkInfo, boolean isClassLabel) {
-        LinkOutput output = getOutputInstance();
+    public Content getTypeParameterLinks(LinkInfo linkInfo, boolean isClassLabel) {
+        Content links = newContent();
         Type[] vars;
         if (linkInfo.executableMemberDoc != null) {
             vars = linkInfo.executableMemberDoc.typeParameters();
@@ -227,62 +225,37 @@
             vars = linkInfo.classDoc.typeParameters();
         } else {
             //Nothing to document.
-            return output;
+            return links;
         }
         if (((linkInfo.includeTypeInClassLinkLabel && isClassLabel) ||
              (linkInfo.includeTypeAsSepLink && ! isClassLabel)
               )
             && vars.length > 0) {
-            linkInfo.displayLength += 1;
-            output.append(getLessThanString());
+            links.addContent("<");
             for (int i = 0; i < vars.length; i++) {
                 if (i > 0) {
-                    linkInfo.displayLength += 1;
-                    output.append(",");
+                    links.addContent(",");
                 }
-                output.append(getTypeParameterLink(linkInfo, vars[i]));
+                links.addContent(getTypeParameterLink(linkInfo, vars[i]));
             }
-            linkInfo.displayLength += 1;
-            output.append(getGreaterThanString());
+            links.addContent(">");
         }
-        return output;
+        return links;
     }
 
-    public LinkOutput getTypeAnnotationLinks(LinkInfo linkInfo) {
-        LinkOutput output = getOutputInstance();
+    public Content getTypeAnnotationLinks(LinkInfo linkInfo) {
+        Content links = newContent();
         if (linkInfo.type.asAnnotatedType() == null)
-            return output;
+            return links;
         AnnotationDesc[] annotations = linkInfo.type.asAnnotatedType().annotations();
         for (int i = 0; i < annotations.length; i++) {
             if (i > 0) {
-                linkInfo.displayLength += 1;
-                output.append(" ");
+                links.addContent(" ");
             }
-            output.append(getTypeAnnotationLink(linkInfo, annotations[i]));
+            links.addContent(getTypeAnnotationLink(linkInfo, annotations[i]));
         }
 
-        linkInfo.displayLength += 1;
-        output.append(" ");
-        return output;
-    }
-
-    /**
-     * Return &amp;lt;, which is used in type parameters.  Override this
-     * if your doclet uses something different.
-     *
-     * @return return &amp;lt;, which is used in type parameters.
-     */
-    protected String getLessThanString() {
-        return "&lt;";
-    }
-
-    /**
-     * Return &amp;gt;, which is used in type parameters.  Override this
-     * if your doclet uses something different.
-     *
-     * @return return &amp;gt;, which is used in type parameters.
-     */
-    protected String getGreaterThanString() {
-        return "&gt;";
+        links.addContent(" ");
+        return links;
     }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkInfo.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkInfo.java
index e46a9f7..842dd61 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkInfo.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkInfo.java
@@ -27,6 +27,7 @@
 
 import com.sun.javadoc.*;
 import com.sun.tools.doclets.internal.toolkit.Configuration;
+import com.sun.tools.doclets.internal.toolkit.Content;
 
 /**
  * Encapsulates information about a link.
@@ -77,7 +78,7 @@
     /**
      * The label for the link.
      */
-    public String label;
+    public Content label;
 
     /**
      * True if the link should be strong.
@@ -90,7 +91,7 @@
     public boolean includeTypeInClassLinkLabel = true;
 
     /**
-     * True if we should include the type as seperate link.  False otherwise.
+     * True if we should include the type as separate link.  False otherwise.
      */
     public boolean includeTypeAsSepLink = false;
 
@@ -116,24 +117,11 @@
     public boolean linkToSelf = true;
 
     /**
-     * The display length for the link.
-     */
-    public int displayLength = 0;
-
-    /**
-     * Return the id indicating where the link appears in the documentation.
-     * This is used for special processing of different types of links.
+     * Return an empty instance of a content object.
      *
-     * @return the id indicating where the link appears in the documentation.
+     * @return an empty instance of a content object.
      */
-    public abstract int getContext();
-
-    /**
-     * Set the context.
-     *
-     * @param c the context id to set.
-     */
-    public abstract void setContext(int c);
+    protected abstract Content newContent();
 
     /**
      * Return true if this link is linkable and false if we can't link to the
@@ -150,13 +138,17 @@
      * @param configuration the current configuration of the doclet.
      * @return the label for this class link.
      */
-    public String getClassLinkLabel(Configuration configuration) {
-        if (label != null && label.length() > 0) {
+    public Content getClassLinkLabel(Configuration configuration) {
+        if (label != null && !label.isEmpty()) {
             return label;
         } else if (isLinkable()) {
-            return classDoc.name();
+            Content label = newContent();
+            label.addContent(classDoc.name());
+            return label;
         } else {
-            return configuration.getClassName(classDoc);
+            Content label = newContent();
+            label.addContent(configuration.getClassName(classDoc));
+            return label;
         }
     }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java
index f1d9d35..701813d 100644
--- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java
+++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java
@@ -42,7 +42,6 @@
 import javax.lang.model.element.ElementKind;
 import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.Name;
-import javax.lang.model.element.TypeElement;
 import javax.lang.model.type.TypeKind;
 import javax.lang.model.type.TypeMirror;
 import javax.tools.Diagnostic.Kind;
@@ -70,7 +69,8 @@
 import com.sun.source.doctree.ThrowsTree;
 import com.sun.source.doctree.ValueTree;
 import com.sun.source.doctree.VersionTree;
-import com.sun.source.util.DocTreeScanner;
+import com.sun.source.util.DocTreePath;
+import com.sun.source.util.DocTreePathScanner;
 import com.sun.source.util.TreePath;
 import com.sun.tools.doclint.HtmlTag.AttrKind;
 import com.sun.tools.javac.tree.DocPretty;
@@ -85,7 +85,7 @@
  * risk.  This code and its internal interfaces are subject to change
  * or deletion without notice.</b></p>
  */
-public class Checker extends DocTreeScanner<Void, Void> {
+public class Checker extends DocTreePathScanner<Void, Void> {
     final Env env;
 
     Set<Element> foundParams = new HashSet<Element>();
@@ -152,7 +152,7 @@
         foundInheritDoc = false;
         foundReturn = false;
 
-        scan(tree, (Void) null);
+        scan(new DocTreePath(p, tree), null);
 
         if (!isOverridingMethod) {
             switch (env.currElement.getKind()) {
@@ -620,47 +620,36 @@
     }
 
     @Override
+    @SuppressWarnings("fallthrough")
     public Void visitParam(ParamTree tree, Void ignore) {
         boolean typaram = tree.isTypeParameter();
         IdentifierTree nameTree = tree.getName();
-        Element e = env.currElement;
-        switch (e.getKind()) {
-            case METHOD: case CONSTRUCTOR: {
-                ExecutableElement ee = (ExecutableElement) e;
-                checkParamDeclared(nameTree, typaram ? ee.getTypeParameters() : ee.getParameters());
-                break;
-            }
+        Element paramElement = nameTree != null ? env.trees.getElement(new DocTreePath(getCurrentPath(), nameTree)) : null;
 
-            case CLASS: case INTERFACE: {
-                TypeElement te = (TypeElement) e;
-                if (typaram) {
-                    checkParamDeclared(nameTree, te.getTypeParameters());
-                } else {
-                    env.messages.error(REFERENCE, tree, "dc.invalid.param");
+        if (paramElement == null) {
+            switch (env.currElement.getKind()) {
+                case CLASS: case INTERFACE: {
+                    if (!typaram) {
+                        env.messages.error(REFERENCE, tree, "dc.invalid.param");
+                        break;
+                    }
                 }
-                break;
-            }
+                case METHOD: case CONSTRUCTOR: {
+                    env.messages.error(REFERENCE, nameTree, "dc.param.name.not.found");
+                    break;
+                }
 
-            default:
-                env.messages.error(REFERENCE, tree, "dc.invalid.param");
-                break;
+                default:
+                    env.messages.error(REFERENCE, tree, "dc.invalid.param");
+                    break;
+            }
+        } else {
+            foundParams.add(paramElement);
         }
+
         warnIfEmpty(tree, tree.getDescription());
         return super.visitParam(tree, ignore);
     }
-    // where
-    private void checkParamDeclared(IdentifierTree nameTree, List<? extends Element> list) {
-        Name name = nameTree.getName();
-        boolean found = false;
-        for (Element e: list) {
-            if (name.equals(e.getSimpleName())) {
-                foundParams.add(e);
-                found = true;
-            }
-        }
-        if (!found)
-            env.messages.error(REFERENCE, nameTree, "dc.param.name.not.found");
-    }
 
     private void checkParamsDocumented(List<? extends Element> list) {
         if (foundInheritDoc)
@@ -678,7 +667,7 @@
 
     @Override
     public Void visitReference(ReferenceTree tree, Void ignore) {
-        Element e = env.trees.getElement(env.currPath, tree);
+        Element e = env.trees.getElement(getCurrentPath());
         if (e == null)
             env.messages.error(REFERENCE, tree, "dc.ref.not.found");
         return super.visitReference(tree, ignore);
@@ -716,7 +705,7 @@
     @Override
     public Void visitThrows(ThrowsTree tree, Void ignore) {
         ReferenceTree exName = tree.getExceptionName();
-        Element ex = env.trees.getElement(env.currPath, exName);
+        Element ex = env.trees.getElement(new DocTreePath(getCurrentPath(), exName));
         if (ex == null) {
             env.messages.error(REFERENCE, tree, "dc.ref.not.found");
         } else if (ex.asType().getKind() == TypeKind.DECLARED
diff --git a/langtools/src/share/classes/com/sun/tools/doclint/Env.java b/langtools/src/share/classes/com/sun/tools/doclint/Env.java
index 979c01a..ffe3a7a 100644
--- a/langtools/src/share/classes/com/sun/tools/doclint/Env.java
+++ b/langtools/src/share/classes/com/sun/tools/doclint/Env.java
@@ -29,6 +29,7 @@
 import java.util.Set;
 
 import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
 import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.Modifier;
 import javax.lang.model.type.TypeMirror;
@@ -144,7 +145,7 @@
         AccessKind ak = null;
         for (TreePath p = path; p != null; p = p.getParentPath()) {
             Element e = trees.getElement(p);
-            if (e != null) {
+            if (e != null && e.getKind() != ElementKind.PACKAGE) {
                 ak = min(ak, AccessKind.of(e.getModifiers()));
             }
         }
diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java
index 545b883..19dde2a 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java
@@ -33,6 +33,7 @@
 import javax.lang.model.element.AnnotationMirror;
 import javax.lang.model.element.AnnotationValue;
 import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
 import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.type.DeclaredType;
@@ -44,12 +45,12 @@
 
 import com.sun.source.doctree.DocCommentTree;
 import com.sun.source.doctree.DocTree;
-import com.sun.source.doctree.ReferenceTree;
 import com.sun.source.tree.CatchTree;
 import com.sun.source.tree.CompilationUnitTree;
 import com.sun.source.tree.Scope;
 import com.sun.source.tree.Tree;
 import com.sun.source.util.DocSourcePositions;
+import com.sun.source.util.DocTreePath;
 import com.sun.source.util.DocTreeScanner;
 import com.sun.source.util.DocTrees;
 import com.sun.source.util.JavacTask;
@@ -314,7 +315,7 @@
         return TreePath.getPath(treeTopLevel.snd, treeTopLevel.fst);
     }
 
-    public Element getElement(TreePath path) {
+    public Symbol getElement(TreePath path) {
         JCTree tree = (JCTree) path.getLeaf();
         Symbol sym = TreeInfo.symbolFor(tree);
         if (sym == null) {
@@ -332,22 +333,25 @@
                         }
                     }
                 }
-            } else if (tree.hasTag(Tag.TOPLEVEL)) {
-                JCCompilationUnit cu = (JCCompilationUnit) tree;
-                if (cu.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE)) {
-                    sym = cu.packge;
-                }
             }
         }
         return sym;
     }
 
     @Override
-    public Element getElement(TreePath path, ReferenceTree reference) {
-        if (!(reference instanceof DCReference))
-            return null;
-        DCReference ref = (DCReference) reference;
+    public Element getElement(DocTreePath path) {
+        DocTree forTree = path.getLeaf();
+        if (forTree instanceof DCReference)
+            return attributeDocReference(path.getTreePath(), ((DCReference) forTree));
+        if (forTree instanceof DCIdentifier) {
+            if (path.getParentPath().getLeaf() instanceof DCParam) {
+                return attributeParamIdentifier(path.getTreePath(), (DCParam) path.getParentPath().getLeaf());
+            }
+        }
+        return null;
+    }
 
+    private Symbol attributeDocReference(TreePath path, DCReference ref) {
         Env<AttrContext> env = getAttrContext(path);
 
         Log.DeferredDiagnosticHandler deferredDiagnosticHandler =
@@ -427,6 +431,30 @@
         }
     }
 
+    private Symbol attributeParamIdentifier(TreePath path, DCParam ptag) {
+        Symbol javadocSymbol = getElement(path);
+        if (javadocSymbol == null)
+            return null;
+        ElementKind kind = javadocSymbol.getKind();
+        List<? extends Symbol> params = List.nil();
+        if (kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) {
+            MethodSymbol ee = (MethodSymbol) javadocSymbol;
+            params = ptag.isTypeParameter()
+                    ? ee.getTypeParameters()
+                    : ee.getParameters();
+        } else if (kind.isClass() || kind.isInterface()) {
+            ClassSymbol te = (ClassSymbol) javadocSymbol;
+            params = te.getTypeParameters();
+        }
+
+        for (Symbol param : params) {
+            if (param.getSimpleName() == ptag.getName().getName()) {
+                return param;
+            }
+        }
+        return null;
+    }
+
     /** @see com.sun.tools.javadoc.ClassDocImpl#findField */
     private VarSymbol findField(ClassSymbol tsym, Name fieldName) {
         return searchField(tsym, fieldName, new HashSet<ClassSymbol>());
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java b/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java
index 5d1af11..5be0865 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java
@@ -76,11 +76,24 @@
     private List<Attribute.Compound> attributes = DECL_NOT_STARTED;
 
     /*
-     * This field should never be null
+     * Type attributes for this symbol.
+     * This field should never be null.
      */
     private List<Attribute.TypeCompound> type_attributes = List.<Attribute.TypeCompound>nil();
 
     /*
+     * Type attributes of initializers in this class.
+     * Unused if the current symbol is not a ClassSymbol.
+     */
+    private List<Attribute.TypeCompound> init_type_attributes = List.<Attribute.TypeCompound>nil();
+
+    /*
+     * Type attributes of class initializers in this class.
+     * Unused if the current symbol is not a ClassSymbol.
+     */
+    private List<Attribute.TypeCompound> clinit_type_attributes = List.<Attribute.TypeCompound>nil();
+
+    /*
      * The Symbol this Annotations instance belongs to
      */
     private final Symbol sym;
@@ -97,6 +110,14 @@
         return type_attributes;
     }
 
+    public List<Attribute.TypeCompound> getInitTypeAttributes() {
+        return init_type_attributes;
+    }
+
+    public List<Attribute.TypeCompound> getClassInitTypeAttributes() {
+        return clinit_type_attributes;
+    }
+
     public void setDeclarationAttributes(List<Attribute.Compound> a) {
         Assert.check(pendingCompletion() || !isStarted());
         if (a == null) {
@@ -112,12 +133,28 @@
         type_attributes = a;
     }
 
+    public void setInitTypeAttributes(List<Attribute.TypeCompound> a) {
+        if (a == null) {
+            throw new NullPointerException();
+        }
+        init_type_attributes = a;
+    }
+
+    public void setClassInitTypeAttributes(List<Attribute.TypeCompound> a) {
+        if (a == null) {
+            throw new NullPointerException();
+        }
+        clinit_type_attributes = a;
+    }
+
     public void setAttributes(Annotations other) {
         if (other == null) {
             throw new NullPointerException();
         }
         setDeclarationAttributes(other.getDeclarationAttributes());
         setTypeAttributes(other.getTypeAttributes());
+        setInitTypeAttributes(other.getInitTypeAttributes());
+        setClassInitTypeAttributes(other.getClassInitTypeAttributes());
     }
 
     public void setDeclarationAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.Compound> ctx) {
@@ -232,6 +269,28 @@
         return this;
     }
 
+    public Annotations appendInitTypeAttributes(List<Attribute.TypeCompound> l) {
+        if (l.isEmpty()) {
+            ; // no-op
+        } else if (init_type_attributes.isEmpty()) {
+            init_type_attributes = l;
+        } else {
+            init_type_attributes = init_type_attributes.appendList(l);
+        }
+        return this;
+    }
+
+    public Annotations appendClassInitTypeAttributes(List<Attribute.TypeCompound> l) {
+        if (l.isEmpty()) {
+            ; // no-op
+        } else if (clinit_type_attributes.isEmpty()) {
+            clinit_type_attributes = l;
+        } else {
+            clinit_type_attributes = clinit_type_attributes.appendList(l);
+        }
+        return this;
+    }
+
     public Annotations prepend(List<Attribute.Compound> l) {
         attributes = filterDeclSentinels(attributes);
 
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java
index 4ba35b3..ec76bbf 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java
@@ -230,6 +230,42 @@
             this.position = position;
         }
 
+        public boolean hasUnknownPosition() {
+            return position == null || position.type == TargetType.UNKNOWN;
+        }
+
+        public boolean isContainerTypeCompound() {
+            if (isSynthesized() && values.size() == 1)
+                return getFirstEmbeddedTC() != null;
+            return false;
+        }
+
+        private TypeCompound getFirstEmbeddedTC() {
+            if (values.size() == 1) {
+                Pair<MethodSymbol, Attribute> val = values.get(0);
+                if (val.fst.getSimpleName().contentEquals("value")
+                        && val.snd instanceof Array) {
+                    Array arr = (Array) val.snd;
+                    if (arr.values.length != 0
+                            && arr.values[0] instanceof Attribute.TypeCompound)
+                        return (Attribute.TypeCompound) arr.values[0];
+                }
+            }
+            return null;
+        }
+
+        public boolean tryFixPosition() {
+            if (!isContainerTypeCompound())
+                return false;
+
+            TypeCompound from = getFirstEmbeddedTC();
+            if (from != null && from.position != null &&
+                    from.position.type != TargetType.UNKNOWN) {
+                position = from.position;
+                return true;
+            }
+            return false;
+        }
     }
 
     /** The value for an annotation element of an array type.
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java
index 3a8982f..76e5410 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java
@@ -31,6 +31,7 @@
 
 import com.sun.tools.javac.api.Messages;
 import com.sun.tools.javac.code.Type.AnnotatedType;
+import com.sun.tools.javac.code.Type.ArrayType;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.util.List;
@@ -127,7 +128,7 @@
     }
 
     /**
-     * Get a localized string represenation for a given type.
+     * Get a localized string representation for a given type.
      *
      * @param t type to be displayed
      * @param locale the locale in which the string is to be rendered
@@ -138,7 +139,7 @@
     }
 
     /**
-     * Get a localized string represenation for a given symbol.
+     * Get a localized string representation for a given symbol.
      *
      * @param s symbol to be displayed
      * @param locale the locale in which the string is to be rendered
@@ -182,7 +183,33 @@
 
     @Override
     public String visitArrayType(ArrayType t, Locale locale) {
-        return visit(t.elemtype, locale) + "[]";
+        StringBuilder res = new StringBuilder();
+        printBaseElementType(t, res, locale);
+        printBrackets(t, res, locale);
+        return res.toString();
+    }
+
+    void printBaseElementType(Type t, StringBuilder sb, Locale locale) {
+        Type arrel = t;
+        while (arrel.getKind() == TypeKind.ARRAY) {
+            arrel = arrel.unannotatedType();
+            arrel = ((ArrayType) arrel).elemtype;
+        }
+        sb.append(visit(arrel, locale));
+    }
+
+    void printBrackets(Type t, StringBuilder sb, Locale locale) {
+        Type arrel = t;
+        while (arrel.getKind() == TypeKind.ARRAY) {
+            if (arrel.isAnnotated()) {
+                sb.append(' ');
+                sb.append(arrel.getAnnotationMirrors());
+                sb.append(' ');
+            }
+            sb.append("[]");
+            arrel = arrel.unannotatedType();
+            arrel = ((ArrayType) arrel).elemtype;
+        }
     }
 
     @Override
@@ -237,10 +264,22 @@
     public String visitAnnotatedType(AnnotatedType t, Locale locale) {
         if (t.typeAnnotations != null &&
                 t.typeAnnotations.nonEmpty()) {
-            // TODO: better logic for arrays, ...
-            return "(" + t.typeAnnotations + " :: " + visit(t.underlyingType, locale) + ")";
+            if (t.underlyingType.getKind() == TypeKind.ARRAY) {
+                StringBuilder res = new StringBuilder();
+                printBaseElementType(t, res, locale);
+                printBrackets(t, res, locale);
+                return res.toString();
+            } else if (t.underlyingType.getKind() == TypeKind.DECLARED &&
+                    t.underlyingType.getEnclosingType() != Type.noType) {
+                return visit(t.underlyingType.getEnclosingType(), locale) +
+                        ". " +
+                        t.typeAnnotations +
+                        " " + className((ClassType)t.underlyingType, false, locale);
+            } else {
+                return t.typeAnnotations + " " + visit(t.underlyingType, locale);
+            }
         } else {
-            return "({} :: " + visit(t.underlyingType, locale) + ")";
+            return visit(t.underlyingType, locale);
         }
     }
 
@@ -253,7 +292,7 @@
 
     /**
      * Converts a class name into a (possibly localized) string. Anonymous
-     * inner classes gets converted into a localized string.
+     * inner classes get converted into a localized string.
      *
      * @param t the type of the class whose name is to be rendered
      * @param longform if set, the class' fullname is displayed - if unset the
@@ -266,7 +305,7 @@
         if (sym.name.length() == 0 && (sym.flags() & COMPOUND) != 0) {
             StringBuilder s = new StringBuilder(visit(t.supertype_field, locale));
             for (List<Type> is = t.interfaces_field; is.nonEmpty(); is = is.tail) {
-                s.append("&");
+                s.append('&');
                 s.append(visit(is.head, locale));
             }
             return s.toString();
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java
index aebfda5..5f968f4 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java
@@ -131,7 +131,6 @@
     public final Type methodHandleLookupType;
     public final Type methodTypeType;
     public final Type nativeHeaderType;
-    public final Type nativeHeaderType_old;
     public final Type throwableType;
     public final Type errorType;
     public final Type interruptedExceptionType;
@@ -526,7 +525,6 @@
                              autoCloseableType.tsym);
         trustMeType = enterClass("java.lang.SafeVarargs");
         nativeHeaderType = enterClass("java.lang.annotation.Native");
-        nativeHeaderType_old = enterClass("javax.tools.annotation.GenerateNativeHeader");
         lambdaMetafactory = enterClass("java.lang.invoke.LambdaMetafactory");
         functionalInterfaceType = enterClass("java.lang.FunctionalInterface");
 
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java
index 0d2a146..43784a2 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java
@@ -25,8 +25,6 @@
 
 package com.sun.tools.javac.code;
 
-import com.sun.tools.javac.model.JavacAnnoConstructs;
-import com.sun.tools.javac.model.JavacTypes;
 import java.lang.annotation.Annotation;
 import java.util.Collections;
 import java.util.EnumMap;
@@ -34,10 +32,10 @@
 import java.util.Map;
 import java.util.Set;
 
-import javax.lang.model.element.AnnotationMirror;
 import javax.lang.model.type.*;
 
 import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.model.JavacAnnoConstructs;
 import com.sun.tools.javac.util.*;
 import static com.sun.tools.javac.code.BoundKind.*;
 import static com.sun.tools.javac.code.Flags.*;
@@ -729,7 +727,7 @@
                     return s.toString();
                 } else if (sym.name.isEmpty()) {
                     String s;
-                    ClassType norm = (ClassType) tsym.type;
+                    ClassType norm = (ClassType) tsym.type.unannotatedType();
                     if (norm == null) {
                         s = Log.getLocalizedString("anonymous.class", (Object)null);
                     } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
@@ -781,7 +779,7 @@
             return
                 getEnclosingType().isErroneous() ||
                 isErroneous(getTypeArguments()) ||
-                this != tsym.type && tsym.type.isErroneous();
+                this != tsym.type.unannotatedType() && tsym.type.isErroneous();
         }
 
         public boolean isParameterized() {
@@ -1693,7 +1691,10 @@
 
         @Override
         public String toString() {
-            // TODO more logic for arrays, etc.
+            // This method is only used for internal debugging output.
+            // See
+            // com.sun.tools.javac.code.Printer.visitAnnotatedType(AnnotatedType, Locale)
+            // for the user-visible logic.
             if (typeAnnotations != null &&
                     !typeAnnotations.isEmpty()) {
                 return "(" + typeAnnotations.toString() + " :: " + underlyingType.toString() + ")";
@@ -1705,9 +1706,13 @@
         @Override
         public boolean contains(Type t)          { return underlyingType.contains(t); }
 
-        // TODO: attach annotations?
         @Override
-        public Type withTypeVar(Type t)          { return underlyingType.withTypeVar(t); }
+        public Type withTypeVar(Type t) {
+            // Don't create a new AnnotatedType, as 'this' will
+            // get its annotations set later.
+            underlyingType = underlyingType.withTypeVar(t);
+            return this;
+        }
 
         // TODO: attach annotations?
         @Override
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java
index d61a9f6..89f6ea4 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java
@@ -27,6 +27,7 @@
 
 import java.util.Iterator;
 
+import com.sun.tools.javac.tree.JCTree.JCLambda;
 import com.sun.tools.javac.util.*;
 
 /** A type annotation position.
@@ -145,9 +146,18 @@
     // For class extends, implements, and throws clauses
     public int type_index = Integer.MIN_VALUE;
 
-    // For exception parameters, index into exception table
+    // For exception parameters, index into exception table.
+    // In com.sun.tools.javac.jvm.Gen.genCatch we first set the type_index
+    // to the catch type index - that value is only temporary.
+    // Then in com.sun.tools.javac.jvm.Code.fillExceptionParameterPositions
+    // we use that value to determine the exception table index.
     public int exception_index = Integer.MIN_VALUE;
 
+    // If this type annotation is within a lambda expression,
+    // store a pointer to the lambda expression tree in order
+    // to allow a later translation to the right method.
+    public JCLambda onLambda = null;
+
     public TypeAnnotationPosition() {}
 
     @Override
@@ -258,6 +268,11 @@
         sb.append(", pos = ");
         sb.append(pos);
 
+        if (onLambda != null) {
+            sb.append(", onLambda hash = ");
+            sb.append(onLambda.hashCode());
+        }
+
         sb.append(']');
         return sb.toString();
     }
@@ -271,6 +286,17 @@
         return !type.isLocal() || isValidOffset;
     }
 
+
+    public boolean matchesPos(int pos) {
+        return this.pos == pos;
+    }
+
+    public void updatePosOffset(int to) {
+        offset = to;
+        lvarOffset = new int[]{to};
+        isValidOffset = true;
+    }
+
     /**
      * Decode the binary representation for a type path and set
      * the {@code location} field.
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
index 94c57fe..6ac82e5 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
@@ -49,12 +49,16 @@
 import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind;
 import com.sun.tools.javac.code.TypeTag;
 import com.sun.tools.javac.code.Symbol.VarSymbol;
+import com.sun.tools.javac.code.Symbol.MethodSymbol;
+import com.sun.tools.javac.comp.Annotate;
 import com.sun.tools.javac.comp.Annotate.Annotator;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.JCBlock;
 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
 import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.JCTree.JCLambda;
 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCNewClass;
 import com.sun.tools.javac.tree.JCTree.JCTypeApply;
 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
 import com.sun.tools.javac.tree.TreeScanner;
@@ -81,17 +85,18 @@
      * determine the correct positions for type annotations.
      * This version only visits types in signatures and should be
      * called from MemberEnter.
-     * The method returns the Annotator object that should be added
-     * to the correct Annotate queue for later processing.
+     * The method takes the Annotate object as parameter and
+     * adds an Annotator to the correct Annotate queue for
+     * later processing.
      */
-    public static Annotator organizeTypeAnnotationsSignatures(final Symtab syms, final Names names,
-            final Log log, final JCClassDecl tree) {
-        return new Annotator() {
+    public static void organizeTypeAnnotationsSignatures(final Symtab syms, final Names names,
+            final Log log, final JCClassDecl tree, Annotate annotate) {
+        annotate.afterRepeated( new Annotator() {
             @Override
             public void enterAnnotation() {
                 new TypeAnnotationPositions(syms, names, log, true).scan(tree);
             }
-        };
+        } );
     }
 
     /**
@@ -102,9 +107,103 @@
         new TypeAnnotationPositions(syms, names, log, false).scan(tree);
     }
 
-    private static class TypeAnnotationPositions extends TreeScanner {
+    public enum AnnotationType { DECLARATION, TYPE, BOTH };
 
-        private enum AnnotationType { DECLARATION, TYPE, BOTH };
+    /**
+     * Determine whether an annotation is a declaration annotation,
+     * a type annotation, or both.
+     */
+    public static AnnotationType annotationType(Symtab syms, Names names,
+            Attribute.Compound a, Symbol s) {
+        Attribute.Compound atTarget =
+            a.type.tsym.attribute(syms.annotationTargetType.tsym);
+        if (atTarget == null) {
+            return inferTargetMetaInfo(a, s);
+        }
+        Attribute atValue = atTarget.member(names.value);
+        if (!(atValue instanceof Attribute.Array)) {
+            Assert.error("annotationType(): bad @Target argument " + atValue +
+                    " (" + atValue.getClass() + ")");
+            return AnnotationType.DECLARATION; // error recovery
+        }
+        Attribute.Array arr = (Attribute.Array) atValue;
+        boolean isDecl = false, isType = false;
+        for (Attribute app : arr.values) {
+            if (!(app instanceof Attribute.Enum)) {
+                Assert.error("annotationType(): unrecognized Attribute kind " + app +
+                        " (" + app.getClass() + ")");
+                isDecl = true;
+                continue;
+            }
+            Attribute.Enum e = (Attribute.Enum) app;
+            if (e.value.name == names.TYPE) {
+                if (s.kind == Kinds.TYP)
+                    isDecl = true;
+            } else if (e.value.name == names.FIELD) {
+                if (s.kind == Kinds.VAR &&
+                        s.owner.kind != Kinds.MTH)
+                    isDecl = true;
+            } else if (e.value.name == names.METHOD) {
+                if (s.kind == Kinds.MTH &&
+                        !s.isConstructor())
+                    isDecl = true;
+            } else if (e.value.name == names.PARAMETER) {
+                if (s.kind == Kinds.VAR &&
+                        s.owner.kind == Kinds.MTH &&
+                        (s.flags() & Flags.PARAMETER) != 0)
+                    isDecl = true;
+            } else if (e.value.name == names.CONSTRUCTOR) {
+                if (s.kind == Kinds.MTH &&
+                        s.isConstructor())
+                    isDecl = true;
+            } else if (e.value.name == names.LOCAL_VARIABLE) {
+                if (s.kind == Kinds.VAR &&
+                        s.owner.kind == Kinds.MTH &&
+                        (s.flags() & Flags.PARAMETER) == 0)
+                    isDecl = true;
+            } else if (e.value.name == names.ANNOTATION_TYPE) {
+                if (s.kind == Kinds.TYP &&
+                        (s.flags() & Flags.ANNOTATION) != 0)
+                    isDecl = true;
+            } else if (e.value.name == names.PACKAGE) {
+                if (s.kind == Kinds.PCK)
+                    isDecl = true;
+            } else if (e.value.name == names.TYPE_USE) {
+                if (s.kind == Kinds.TYP ||
+                        s.kind == Kinds.VAR ||
+                        (s.kind == Kinds.MTH && !s.isConstructor() &&
+                        !s.type.getReturnType().hasTag(TypeTag.VOID)) ||
+                        (s.kind == Kinds.MTH && s.isConstructor()))
+                    isType = true;
+            } else if (e.value.name == names.TYPE_PARAMETER) {
+                /* Irrelevant in this case */
+                // TYPE_PARAMETER doesn't aid in distinguishing between
+                // Type annotations and declaration annotations on an
+                // Element
+            } else {
+                Assert.error("annotationType(): unrecognized Attribute name " + e.value.name +
+                        " (" + e.value.name.getClass() + ")");
+                isDecl = true;
+            }
+        }
+        if (isDecl && isType) {
+            return AnnotationType.BOTH;
+        } else if (isType) {
+            return AnnotationType.TYPE;
+        } else {
+            return AnnotationType.DECLARATION;
+        }
+    }
+
+    /** Infer the target annotation kind, if none is give.
+     * We only infer declaration annotations.
+     */
+    private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) {
+        return AnnotationType.DECLARATION;
+    }
+
+
+    private static class TypeAnnotationPositions extends TreeScanner {
 
         private final Symtab syms;
         private final Names names;
@@ -154,7 +253,7 @@
             ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<Attribute.TypeCompound>();
 
             for (Attribute.Compound a : annotations) {
-                switch (annotationType(a, sym)) {
+                switch (annotationType(syms, names, a, sym)) {
                 case DECLARATION:
                     declAnnos.append(a);
                     break;
@@ -175,6 +274,10 @@
             sym.annotations.reset();
             sym.annotations.setDeclarationAttributes(declAnnos.toList());
 
+            if (typeAnnos.isEmpty()) {
+                return;
+            }
+
             List<Attribute.TypeCompound> typeAnnotations = typeAnnos.toList();
 
             if (type == null) {
@@ -190,16 +293,33 @@
 
             if (sym.getKind() == ElementKind.METHOD) {
                 sym.type.asMethodType().restype = type;
+            } else if (sym.getKind() == ElementKind.PARAMETER) {
+                sym.type = type;
+                if (sym.getQualifiedName().equals(names._this)) {
+                    sym.owner.type.asMethodType().recvtype = type;
+                    // note that the typeAnnotations will also be added to the owner below.
+                } else {
+                    MethodType methType = sym.owner.type.asMethodType();
+                    List<VarSymbol> params = ((MethodSymbol)sym.owner).params;
+                    List<Type> oldArgs = methType.argtypes;
+                    ListBuffer<Type> newArgs = new ListBuffer<Type>();
+                    while (params.nonEmpty()) {
+                        if (params.head == sym) {
+                            newArgs.add(type);
+                        } else {
+                            newArgs.add(oldArgs.head);
+                        }
+                        oldArgs = oldArgs.tail;
+                        params = params.tail;
+                    }
+                    methType.argtypes = newArgs.toList();
+                }
             } else {
                 sym.type = type;
             }
 
             sym.annotations.appendUniqueTypes(typeAnnotations);
-            if (sym.getKind() == ElementKind.PARAMETER &&
-                    sym.getQualifiedName().equals(names._this)) {
-                sym.owner.type.asMethodType().recvtype = type;
-                // note that the typeAnnotations will also be added to the owner below.
-            }
+
             if (sym.getKind() == ElementKind.PARAMETER ||
                     sym.getKind() == ElementKind.LOCAL_VARIABLE ||
                     sym.getKind() == ElementKind.RESOURCE_VARIABLE ||
@@ -276,10 +396,21 @@
                     TypeAnnotationPosition p = a.position;
                     p.location = p.location.prependList(depth.toList());
                 }
+                typetree.type = toreturn;
                 return toreturn;
             } else if (type.hasTag(TypeTag.TYPEVAR)) {
                 // Nothing to do for type variables.
                 return type;
+            } else if (type.getKind() == TypeKind.UNION) {
+                // There is a TypeKind, but no TypeTag.
+                JCTypeUnion tutree = (JCTypeUnion) typetree;
+                JCExpression fst = tutree.alternatives.get(0);
+                Type res = typeWithAnnotations(fst, fst.type, annotations, log);
+                fst.type = res;
+                // TODO: do we want to set res as first element in uct.alternatives?
+                // UnionClassType uct = (com.sun.tools.javac.code.Type.UnionClassType)type;
+                // Return the un-annotated union-type.
+                return type;
             } else {
                 Type enclTy = type;
                 Element enclEl = type.asElement();
@@ -357,6 +488,7 @@
                 }
 
                 Type ret = typeWithAnnotations(type, enclTy, annotations);
+                typetree.type = ret;
                 return ret;
             }
         }
@@ -480,94 +612,6 @@
             return new Attribute.TypeCompound(a, p);
         }
 
-        private AnnotationType annotationType(Attribute.Compound a, Symbol s) {
-            Attribute.Compound atTarget =
-                a.type.tsym.attribute(syms.annotationTargetType.tsym);
-            if (atTarget == null) {
-                return inferTargetMetaInfo(a, s);
-            }
-            Attribute atValue = atTarget.member(names.value);
-            if (!(atValue instanceof Attribute.Array)) {
-                Assert.error("annotationType(): bad @Target argument " + atValue +
-                        " (" + atValue.getClass() + ")");
-                return AnnotationType.DECLARATION; // error recovery
-            }
-            Attribute.Array arr = (Attribute.Array) atValue;
-            boolean isDecl = false, isType = false;
-            for (Attribute app : arr.values) {
-                if (!(app instanceof Attribute.Enum)) {
-                    Assert.error("annotationType(): unrecognized Attribute kind " + app +
-                            " (" + app.getClass() + ")");
-                    isDecl = true;
-                    continue;
-                }
-                Attribute.Enum e = (Attribute.Enum) app;
-                if (e.value.name == names.TYPE) {
-                    if (s.kind == Kinds.TYP)
-                        isDecl = true;
-                } else if (e.value.name == names.FIELD) {
-                    if (s.kind == Kinds.VAR &&
-                            s.owner.kind != Kinds.MTH)
-                        isDecl = true;
-                } else if (e.value.name == names.METHOD) {
-                    if (s.kind == Kinds.MTH &&
-                            !s.isConstructor())
-                        isDecl = true;
-                } else if (e.value.name == names.PARAMETER) {
-                    if (s.kind == Kinds.VAR &&
-                            s.owner.kind == Kinds.MTH &&
-                            (s.flags() & Flags.PARAMETER) != 0)
-                        isDecl = true;
-                } else if (e.value.name == names.CONSTRUCTOR) {
-                    if (s.kind == Kinds.MTH &&
-                            s.isConstructor())
-                        isDecl = true;
-                } else if (e.value.name == names.LOCAL_VARIABLE) {
-                    if (s.kind == Kinds.VAR &&
-                            s.owner.kind == Kinds.MTH &&
-                            (s.flags() & Flags.PARAMETER) == 0)
-                        isDecl = true;
-                } else if (e.value.name == names.ANNOTATION_TYPE) {
-                    if (s.kind == Kinds.TYP &&
-                            (s.flags() & Flags.ANNOTATION) != 0)
-                        isDecl = true;
-                } else if (e.value.name == names.PACKAGE) {
-                    if (s.kind == Kinds.PCK)
-                        isDecl = true;
-                } else if (e.value.name == names.TYPE_USE) {
-                    if (s.kind == Kinds.TYP ||
-                            s.kind == Kinds.VAR ||
-                            (s.kind == Kinds.MTH && !s.isConstructor() &&
-                            !s.type.getReturnType().hasTag(TypeTag.VOID)) ||
-                            (s.kind == Kinds.MTH && s.isConstructor()))
-                        isType = true;
-                } else if (e.value.name == names.TYPE_PARAMETER) {
-                    /* Irrelevant in this case */
-                    // TYPE_PARAMETER doesn't aid in distinguishing between
-                    // Type annotations and declaration annotations on an
-                    // Element
-                } else {
-                    Assert.error("annotationType(): unrecognized Attribute name " + e.value.name +
-                            " (" + e.value.name.getClass() + ")");
-                    isDecl = true;
-                }
-            }
-            if (isDecl && isType) {
-                return AnnotationType.BOTH;
-            } else if (isType) {
-                return AnnotationType.TYPE;
-            } else {
-                return AnnotationType.DECLARATION;
-            }
-        }
-
-        /** Infer the target annotation kind, if none is give.
-         * We only infer declaration annotations.
-         */
-        private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) {
-            return AnnotationType.DECLARATION;
-        }
-
 
         /* This is the beginning of the second part of organizing
          * type annotations: determine the type annotation positions.
@@ -585,7 +629,13 @@
 
             switch (frame.getKind()) {
                 case TYPE_CAST:
+                    JCTypeCast frameTC = (JCTypeCast) frame;
                     p.type = TargetType.CAST;
+                    if (frameTC.clazz.hasTag(Tag.TYPEINTERSECTION)) {
+                        // This case was already handled by INTERSECTION_TYPE
+                    } else {
+                        p.type_index = 0;
+                    }
                     p.pos = frame.pos;
                     return;
 
@@ -595,8 +645,22 @@
                     return;
 
                 case NEW_CLASS:
-                    JCNewClass frameNewClass = (JCNewClass)frame;
-                    if (frameNewClass.typeargs.contains(tree)) {
+                    JCNewClass frameNewClass = (JCNewClass) frame;
+                    if (frameNewClass.def != null) {
+                        // Special handling for anonymous class instantiations
+                        JCClassDecl frameClassDecl = frameNewClass.def;
+                        if (frameClassDecl.extending == tree) {
+                            p.type = TargetType.CLASS_EXTENDS;
+                            p.type_index = -1;
+                        } else if (frameClassDecl.implementing.contains(tree)) {
+                            p.type = TargetType.CLASS_EXTENDS;
+                            p.type_index = frameClassDecl.implementing.indexOf(tree);
+                        } else {
+                            // In contrast to CLASS below, typarams cannot occur here.
+                            Assert.error("Could not determine position of tree " + tree +
+                                    " within frame " + frame);
+                        }
+                    } else if (frameNewClass.typeargs.contains(tree)) {
                         p.type = TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT;
                         p.type_index = frameNewClass.typeargs.indexOf(tree);
                     } else {
@@ -649,6 +713,8 @@
                 }
 
                 case PARAMETERIZED_TYPE: {
+                    List<JCTree> newPath = path.tail;
+
                     if (((JCTypeApply)frame).clazz == tree) {
                         // generic: RAW; noop
                     } else if (((JCTypeApply)frame).arguments.contains(tree)) {
@@ -656,13 +722,21 @@
                         int arg = taframe.arguments.indexOf(tree);
                         p.location = p.location.prepend(new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg));
 
-                        locateNestedTypes(taframe.type, p);
+                        Type typeToUse;
+                        if (newPath.tail != null && newPath.tail.head.hasTag(Tag.NEWCLASS)) {
+                            // If we are within an anonymous class instantiation, use its type,
+                            // because it contains a correctly nested type.
+                            typeToUse = newPath.tail.head.type;
+                        } else {
+                            typeToUse = taframe.type;
+                        }
+
+                        locateNestedTypes(typeToUse, p);
                     } else {
                         Assert.error("Could not determine type argument position of tree " + tree +
                                 " within frame " + frame);
                     }
 
-                    List<JCTree> newPath = path.tail;
                     resolveFrame(newPath.head, newPath.tail.head, newPath, p);
                     return;
                 }
@@ -780,6 +854,9 @@
                         default:
                             Assert.error("Found unexpected type annotation for variable: " + v + " with kind: " + v.getKind());
                     }
+                    if (v.getKind() != ElementKind.FIELD) {
+                        v.owner.annotations.appendUniqueTypes(v.getRawTypeAttributes());
+                    }
                     return;
 
                 case ANNOTATED_TYPE: {
@@ -789,6 +866,11 @@
                         // not care about inner types.
                         JCAnnotatedType atypetree = (JCAnnotatedType) frame;
                         final Type utype = atypetree.underlyingType.type;
+                        if (utype == null) {
+                            // This might happen during DeferredAttr;
+                            // we will be back later.
+                            return;
+                        }
                         Symbol tsym = utype.tsym;
                         if (tsym.getKind().equals(ElementKind.TYPE_PARAMETER) ||
                                 utype.getKind().equals(TypeKind.WILDCARD) ||
@@ -806,8 +888,6 @@
                 }
 
                 case UNION_TYPE: {
-                    // TODO: can we store any information here to help in
-                    // determining the final position?
                     List<JCTree> newPath = path.tail;
                     resolveFrame(newPath.head, newPath.tail.head, newPath, p);
                     return;
@@ -873,11 +953,20 @@
 
         private static int methodParamIndex(List<JCTree> path, JCTree param) {
             List<JCTree> curr = path;
-            while (curr.head.getTag() != Tag.METHODDEF) {
+            while (curr.head.getTag() != Tag.METHODDEF &&
+                    curr.head.getTag() != Tag.LAMBDA) {
                 curr = curr.tail;
             }
-            JCMethodDecl method = (JCMethodDecl)curr.head;
-            return method.params.indexOf(param);
+            if (curr.head.getTag() == Tag.METHODDEF) {
+                JCMethodDecl method = (JCMethodDecl)curr.head;
+                return method.params.indexOf(param);
+            } else if (curr.head.getTag() == Tag.LAMBDA) {
+                JCLambda lambda = (JCLambda)curr.head;
+                return lambda.params.indexOf(param);
+            } else {
+                Assert.error("methodParamIndex expected to find method or lambda for param: " + param);
+                return -1;
+            }
         }
 
         // Each class (including enclosed inner classes) is visited separately.
@@ -889,6 +978,7 @@
             if (isInClass)
                 return;
             isInClass = true;
+
             if (sigOnly) {
                 scan(tree.mods);
                 scan(tree.typarams);
@@ -910,7 +1000,9 @@
                 return;
             }
             if (sigOnly) {
-                {
+                if (!tree.mods.annotations.isEmpty()) {
+                    // Nothing to do for separateAnnotationsKinds if
+                    // there are no annotations of either kind.
                     TypeAnnotationPosition pos = new TypeAnnotationPosition();
                     pos.type = TargetType.METHOD_RETURN;
                     if (tree.sym.isConstructor()) {
@@ -923,7 +1015,10 @@
                                 tree.sym, pos);
                     }
                 }
-                if (tree.recvparam != null && tree.recvparam.sym != null) {
+                if (tree.recvparam != null && tree.recvparam.sym != null &&
+                        !tree.recvparam.mods.annotations.isEmpty()) {
+                    // Nothing to do for separateAnnotationsKinds if
+                    // there are no annotations of either kind.
                     // TODO: make sure there are no declaration annotations.
                     TypeAnnotationPosition pos = new TypeAnnotationPosition();
                     pos.type = TargetType.METHOD_RECEIVER;
@@ -933,11 +1028,15 @@
                 }
                 int i = 0;
                 for (JCVariableDecl param : tree.params) {
-                    TypeAnnotationPosition pos = new TypeAnnotationPosition();
-                    pos.type = TargetType.METHOD_FORMAL_PARAMETER;
-                    pos.parameter_index = i;
-                    pos.pos = param.vartype.pos;
-                    separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
+                    if (!param.mods.annotations.isEmpty()) {
+                        // Nothing to do for separateAnnotationsKinds if
+                        // there are no annotations of either kind.
+                        TypeAnnotationPosition pos = new TypeAnnotationPosition();
+                        pos.type = TargetType.METHOD_FORMAL_PARAMETER;
+                        pos.parameter_index = i;
+                        pos.pos = param.vartype.pos;
+                        separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
+                    }
                     ++i;
                 }
             }
@@ -958,16 +1057,53 @@
             pop();
         }
 
+        /* Store a reference to the current lambda expression, to
+         * be used by all type annotations within this expression.
+         */
+        private JCLambda currentLambda = null;
+
+        public void visitLambda(JCLambda tree) {
+            JCLambda prevLambda = currentLambda;
+            try {
+                currentLambda = tree;
+
+                int i = 0;
+                for (JCVariableDecl param : tree.params) {
+                    if (!param.mods.annotations.isEmpty()) {
+                        // Nothing to do for separateAnnotationsKinds if
+                        // there are no annotations of either kind.
+                        TypeAnnotationPosition pos = new TypeAnnotationPosition();
+                        pos.type = TargetType.METHOD_FORMAL_PARAMETER;
+                        pos.parameter_index = i;
+                        pos.pos = param.vartype.pos;
+                        pos.onLambda = tree;
+                        separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
+                    }
+                    ++i;
+                }
+
+                push(tree);
+                scan(tree.body);
+                scan(tree.params);
+                pop();
+            } finally {
+                currentLambda = prevLambda;
+            }
+        }
+
         /**
          * Resolve declaration vs. type annotations in variable declarations and
          * then determine the positions.
          */
         @Override
         public void visitVarDef(final JCVariableDecl tree) {
-            if (tree.sym == null) {
+            if (tree.mods.annotations.isEmpty()) {
+                // Nothing to do for separateAnnotationsKinds if
+                // there are no annotations of either kind.
+            } else if (tree.sym == null) {
                 // Something is wrong already. Quietly ignore.
             } else if (tree.sym.getKind() == ElementKind.PARAMETER) {
-                // Parameters are handled in visitMethodDef above.
+                // Parameters are handled in visitMethodDef or visitLambda.
             } else if (tree.sym.getKind() == ElementKind.FIELD) {
                 if (sigOnly) {
                     TypeAnnotationPosition pos = new TypeAnnotationPosition();
@@ -979,16 +1115,19 @@
                 TypeAnnotationPosition pos = new TypeAnnotationPosition();
                 pos.type = TargetType.LOCAL_VARIABLE;
                 pos.pos = tree.pos;
+                pos.onLambda = currentLambda;
                 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
             } else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
                 TypeAnnotationPosition pos = new TypeAnnotationPosition();
                 pos.type = TargetType.EXCEPTION_PARAMETER;
                 pos.pos = tree.pos;
+                pos.onLambda = currentLambda;
                 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
             } else if (tree.sym.getKind() == ElementKind.RESOURCE_VARIABLE) {
                 TypeAnnotationPosition pos = new TypeAnnotationPosition();
                 pos.type = TargetType.RESOURCE_VARIABLE;
                 pos.pos = tree.pos;
+                pos.onLambda = currentLambda;
                 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
             } else if (tree.sym.getKind() == ElementKind.ENUM_CONSTANT) {
                 // No type annotations can occur here.
@@ -1031,6 +1170,40 @@
         }
 
         @Override
+        public void visitNewClass(JCNewClass tree) {
+            if (tree.def != null &&
+                    !tree.def.mods.annotations.isEmpty()) {
+                JCClassDecl classdecl = tree.def;
+                TypeAnnotationPosition pos = new TypeAnnotationPosition();
+                pos.type = TargetType.CLASS_EXTENDS;
+                pos.pos = tree.pos;
+                if (classdecl.extending == tree.clazz) {
+                    pos.type_index = -1;
+                } else if (classdecl.implementing.contains(tree.clazz)) {
+                    pos.type_index = classdecl.implementing.indexOf(tree.clazz);
+                } else {
+                    // In contrast to CLASS elsewhere, typarams cannot occur here.
+                    Assert.error("Could not determine position of tree " + tree);
+                }
+                Type before = classdecl.sym.type;
+                separateAnnotationsKinds(classdecl, tree.clazz.type, classdecl.sym, pos);
+
+                // classdecl.sym.type now contains an annotated type, which
+                // is not what we want there.
+                // TODO: should we put this type somewhere in the superclass/interface?
+                classdecl.sym.type = before;
+            }
+
+            scan(tree.encl);
+            scan(tree.typeargs);
+            scan(tree.clazz);
+            scan(tree.args);
+
+            // The class body will already be scanned.
+            // scan(tree.def);
+        }
+
+        @Override
         public void visitNewArray(JCNewArray tree) {
             findPosition(tree, tree, tree.annotations);
             int dimAnnosCount = tree.dimAnnotations.size();
@@ -1040,6 +1213,7 @@
             for (int i = 0; i < dimAnnosCount; ++i) {
                 TypeAnnotationPosition p = new TypeAnnotationPosition();
                 p.pos = tree.pos;
+                p.onLambda = currentLambda;
                 p.type = TargetType.NEW;
                 if (i != 0) {
                     depth = depth.append(TypePathEntry.ARRAY);
@@ -1053,18 +1227,23 @@
             // int i = dimAnnosCount == 0 ? 0 : dimAnnosCount - 1;
             // TODO: is depth.size == i here?
             JCExpression elemType = tree.elemtype;
+            depth = depth.append(TypePathEntry.ARRAY);
             while (elemType != null) {
                 if (elemType.hasTag(JCTree.Tag.ANNOTATED_TYPE)) {
                     JCAnnotatedType at = (JCAnnotatedType)elemType;
                     TypeAnnotationPosition p = new TypeAnnotationPosition();
                     p.type = TargetType.NEW;
                     p.pos = tree.pos;
-                    p.location = p.location.appendList(depth.toList());
+                    p.onLambda = currentLambda;
+                    locateNestedTypes(elemType.type, p);
+                    p.location = p.location.prependList(depth.toList());
                     setTypeAnnotationPos(at.annotations, p);
                     elemType = at.underlyingType;
                 } else if (elemType.hasTag(JCTree.Tag.TYPEARRAY)) {
                     depth = depth.append(TypePathEntry.ARRAY);
                     elemType = ((JCArrayTypeTree)elemType).elemtype;
+                } else if (elemType.hasTag(JCTree.Tag.SELECT)) {
+                    elemType = ((JCFieldAccess)elemType).selected;
                 } else {
                     break;
                 }
@@ -1076,10 +1255,11 @@
             if (!annotations.isEmpty()) {
                 /*
                 System.out.println("Finding pos for: " + annotations);
-                System.out.println("    tree: " + tree);
-                System.out.println("    frame: " + frame);
+                System.out.println("    tree: " + tree + " kind: " + tree.getKind());
+                System.out.println("    frame: " + frame + " kind: " + frame.getKind());
                 */
                 TypeAnnotationPosition p = new TypeAnnotationPosition();
+                p.onLambda = currentLambda;
                 resolveFrame(tree, frame, frames.toList(), p);
                 setTypeAnnotationPos(annotations, p);
             }
@@ -1088,8 +1268,17 @@
         private static void setTypeAnnotationPos(List<JCAnnotation> annotations,
                 TypeAnnotationPosition position) {
             for (JCAnnotation anno : annotations) {
-                ((Attribute.TypeCompound) anno.attribute).position = position;
+                // attribute might be null during DeferredAttr;
+                // we will be back later.
+                if (anno.attribute != null) {
+                    ((Attribute.TypeCompound) anno.attribute).position = position;
+                }
             }
         }
+
+        @Override
+        public String toString() {
+            return super.toString() + ": sigOnly: " + sigOnly;
+        }
     }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java
index 083dc22..0927a33 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java
@@ -26,7 +26,6 @@
 package com.sun.tools.javac.code;
 
 import java.lang.ref.SoftReference;
-import java.util.Comparator;
 import java.util.HashSet;
 import java.util.HashMap;
 import java.util.Locale;
@@ -34,8 +33,6 @@
 import java.util.Set;
 import java.util.WeakHashMap;
 
-import javax.lang.model.type.TypeKind;
-
 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
 import com.sun.tools.javac.code.Lint.LintCategory;
 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
@@ -204,7 +201,7 @@
                     WildcardType unb = new WildcardType(syms.objectType,
                                                         BoundKind.UNBOUND,
                                                         syms.boundClass,
-                                                        (TypeVar)parms.head);
+                                                        (TypeVar)parms.head.unannotatedType());
                     if (!containsType(args.head, unb))
                         return false;
                     parms = parms.tail;
@@ -268,7 +265,7 @@
                         List<Type> opens = openVars.toList();
                         ListBuffer<Type> qs = new ListBuffer<Type>();
                         for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) {
-                            qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head));
+                            qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head.unannotatedType()));
                         }
                         res = subst(res, opens, qs.toList());
                     }
@@ -581,12 +578,12 @@
             //simply replace the wildcards with its bound
             for (Type t : formalInterface.getTypeArguments()) {
                 if (actualTypeargs.head.hasTag(WILDCARD)) {
-                    WildcardType wt = (WildcardType)actualTypeargs.head;
+                    WildcardType wt = (WildcardType)actualTypeargs.head.unannotatedType();
                     Type bound;
                     switch (wt.kind) {
                         case EXTENDS:
                         case UNBOUND:
-                            CapturedType capVar = (CapturedType)capturedTypeargs.head;
+                            CapturedType capVar = (CapturedType)capturedTypeargs.head.unannotatedType();
                             //use declared bound if it doesn't depend on formal type-args
                             bound = capVar.bound.containsAny(capturedSite.getTypeArguments()) ?
                                     wt.type : capVar.bound;
@@ -964,6 +961,9 @@
                 isSameTypeStrict.visit(t, s) :
                 isSameTypeLoose.visit(t, s);
     }
+    public boolean isSameAnnotatedType(Type t, Type s) {
+        return isSameAnnotatedType.visit(t, s);
+    }
     // where
         abstract class SameTypeVisitor extends TypeRelation {
 
@@ -982,7 +982,7 @@
                     if (s.tag == TYPEVAR) {
                         //type-substitution does not preserve type-var types
                         //check that type var symbols and bounds are indeed the same
-                        return sameTypeVars((TypeVar)t, (TypeVar)s);
+                        return sameTypeVars((TypeVar)t.unannotatedType(), (TypeVar)s.unannotatedType());
                     }
                     else {
                         //special case for s == ? super X, where upper(s) = u
@@ -1096,7 +1096,9 @@
          * Standard type-equality relation - type variables are considered
          * equals if they share the same type symbol.
          */
-        TypeRelation isSameTypeLoose = new SameTypeVisitor() {
+        TypeRelation isSameTypeLoose = new LooseSameTypeVisitor();
+
+        private class LooseSameTypeVisitor extends SameTypeVisitor {
             @Override
             boolean sameTypeVars(TypeVar tv1, TypeVar tv2) {
                 return tv1.tsym == tv2.tsym && visit(tv1.getUpperBound(), tv2.getUpperBound());
@@ -1126,12 +1128,29 @@
                 if (!s.hasTag(WILDCARD)) {
                     return false;
                 } else {
-                    WildcardType t2 = (WildcardType)s;
+                    WildcardType t2 = (WildcardType)s.unannotatedType();
                     return t.kind == t2.kind &&
                             isSameType(t.type, t2.type, true);
                 }
             }
         };
+
+        /**
+         * A version of LooseSameTypeVisitor that takes AnnotatedTypes
+         * into account.
+         */
+        TypeRelation isSameAnnotatedType = new LooseSameTypeVisitor() {
+            @Override
+            public Boolean visitAnnotatedType(AnnotatedType t, Type s) {
+                if (!s.isAnnotated())
+                    return false;
+                if (!t.getAnnotationMirrors().containsAll(s.getAnnotationMirrors()))
+                    return false;
+                if (!s.getAnnotationMirrors().containsAll(t.getAnnotationMirrors()))
+                    return false;
+                return visit(t.underlyingType, s);
+            }
+        };
     // </editor-fold>
 
     // <editor-fold defaultstate="collapsed" desc="Contains Type">
@@ -1140,7 +1159,7 @@
         case UNDETVAR:
             if (s.tag == WILDCARD) {
                 UndetVar undetvar = (UndetVar)t;
-                WildcardType wt = (WildcardType)s;
+                WildcardType wt = (WildcardType)s.unannotatedType();
                 switch(wt.kind) {
                     case UNBOUND: //similar to ? extends Object
                     case EXTENDS: {
@@ -1207,7 +1226,7 @@
 
             private Type U(Type t) {
                 while (t.tag == WILDCARD) {
-                    WildcardType w = (WildcardType)t;
+                    WildcardType w = (WildcardType)t.unannotatedType();
                     if (w.isSuperBound())
                         return w.bound == null ? syms.objectType : w.bound.bound;
                     else
@@ -1218,7 +1237,7 @@
 
             private Type L(Type t) {
                 while (t.tag == WILDCARD) {
-                    WildcardType w = (WildcardType)t;
+                    WildcardType w = (WildcardType)t.unannotatedType();
                     if (w.isExtendsBound())
                         return syms.botType;
                     else
@@ -1276,15 +1295,15 @@
         };
 
     public boolean isCaptureOf(Type s, WildcardType t) {
-        if (s.tag != TYPEVAR || !((TypeVar)s).isCaptured())
+        if (s.tag != TYPEVAR || !((TypeVar)s.unannotatedType()).isCaptured())
             return false;
-        return isSameWildcard(t, ((CapturedType)s).wildcard);
+        return isSameWildcard(t, ((CapturedType)s.unannotatedType()).wildcard);
     }
 
     public boolean isSameWildcard(WildcardType t, Type s) {
         if (s.tag != WILDCARD)
             return false;
-        WildcardType w = (WildcardType)s;
+        WildcardType w = (WildcardType)s.unannotatedType();
         return w.kind == t.kind && w.type == t.type;
     }
 
@@ -1373,8 +1392,8 @@
 
                 if (t.isCompound() || s.isCompound()) {
                     return !t.isCompound() ?
-                            visitIntersectionType((IntersectionClassType)s, t, true) :
-                            visitIntersectionType((IntersectionClassType)t, s, false);
+                            visitIntersectionType((IntersectionClassType)s.unannotatedType(), t, true) :
+                            visitIntersectionType((IntersectionClassType)t.unannotatedType(), s, false);
                 }
 
                 if (s.tag == CLASS || s.tag == ARRAY) {
@@ -3070,7 +3089,7 @@
             for (Type t : tvars) {
                 if (!first) s.append(", ");
                 first = false;
-                appendTyparamString(((TypeVar)t), s);
+                appendTyparamString(((TypeVar)t.unannotatedType()), s);
             }
             s.append('>');
             return s.toString();
@@ -3710,9 +3729,9 @@
                !currentS.isEmpty()) {
             if (currentS.head != currentT.head) {
                 captured = true;
-                WildcardType Ti = (WildcardType)currentT.head;
+                WildcardType Ti = (WildcardType)currentT.head.unannotatedType();
                 Type Ui = currentA.head.getUpperBound();
-                CapturedType Si = (CapturedType)currentS.head;
+                CapturedType Si = (CapturedType)currentS.head.unannotatedType();
                 if (Ui == null)
                     Ui = syms.objectType;
                 switch (Ti.kind) {
@@ -3749,6 +3768,7 @@
             ListBuffer<Type> result = lb();
             for (Type t : types) {
                 if (t.tag == WILDCARD) {
+                    t = t.unannotatedType();
                     Type bound = ((WildcardType)t).getExtendsBound();
                     if (bound == null)
                         bound = syms.objectType;
@@ -3842,7 +3862,7 @@
 
     private boolean giveWarning(Type from, Type to) {
         List<Type> bounds = to.isCompound() ?
-                ((IntersectionClassType)to).getComponents() : List.of(to);
+                ((IntersectionClassType)to.unannotatedType()).getComponents() : List.of(to);
         for (Type b : bounds) {
             Type subFrom = asSub(from, b.tsym);
             if (b.isParameterized() &&
@@ -4107,7 +4127,7 @@
 
         Type B(Type t) {
             while (t.tag == WILDCARD) {
-                WildcardType w = (WildcardType)t;
+                WildcardType w = (WildcardType)t.unannotatedType();
                 t = high ?
                     w.getExtendsBound() :
                     w.getSuperBound();
@@ -4182,7 +4202,7 @@
 
         public boolean equals(Object obj) {
             return (obj instanceof UniqueType) &&
-                types.isSameType(type, ((UniqueType)obj).type);
+                types.isSameAnnotatedType(type, ((UniqueType)obj).type);
         }
 
         public String toString() {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java
index 3c5d9be..ebc6fa3 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java
@@ -216,18 +216,42 @@
     Attribute.Compound enterAnnotation(JCAnnotation a,
                                        Type expected,
                                        Env<AttrContext> env) {
+        return enterAnnotation(a, expected, env, false);
+    }
+
+    Attribute.TypeCompound enterTypeAnnotation(JCAnnotation a,
+            Type expected,
+            Env<AttrContext> env) {
+        return (Attribute.TypeCompound) enterAnnotation(a, expected, env, true);
+    }
+
+    // boolean typeAnnotation determines whether the method returns
+    // a Compound (false) or TypeCompound (true).
+    Attribute.Compound enterAnnotation(JCAnnotation a,
+            Type expected,
+            Env<AttrContext> env,
+            boolean typeAnnotation) {
         // The annotation might have had its type attributed (but not checked)
         // by attr.attribAnnotationTypes during MemberEnter, in which case we do not
         // need to do it again.
         Type at = (a.annotationType.type != null ? a.annotationType.type
                   : attr.attribType(a.annotationType, env));
         a.type = chk.checkType(a.annotationType.pos(), at, expected);
-        if (a.type.isErroneous())
-            return new Attribute.Compound(a.type, List.<Pair<MethodSymbol,Attribute>>nil());
+        if (a.type.isErroneous()) {
+            if (typeAnnotation) {
+                return new Attribute.TypeCompound(a.type, List.<Pair<MethodSymbol,Attribute>>nil(), null);
+            } else {
+                return new Attribute.Compound(a.type, List.<Pair<MethodSymbol,Attribute>>nil());
+            }
+        }
         if ((a.type.tsym.flags() & Flags.ANNOTATION) == 0) {
             log.error(a.annotationType.pos(),
                       "not.annotation.type", a.type.toString());
-            return new Attribute.Compound(a.type, List.<Pair<MethodSymbol,Attribute>>nil());
+            if (typeAnnotation) {
+                return new Attribute.TypeCompound(a.type, List.<Pair<MethodSymbol,Attribute>>nil(), null);
+            } else {
+                return new Attribute.Compound(a.type, List.<Pair<MethodSymbol,Attribute>>nil());
+            }
         }
         List<JCExpression> args = a.args;
         if (args.length() == 1 && !args.head.hasTag(ASSIGN)) {
@@ -266,12 +290,21 @@
                            ((MethodSymbol)method, value));
             t.type = result;
         }
-        // TODO: this should be a TypeCompound if "a" is a JCTypeAnnotation.
-        // However, how do we find the correct position?
-        Attribute.Compound ac = new Attribute.Compound(a.type, buf.toList());
-        // TODO: is this something we want? Who would use it?
-        // a.attribute = ac;
-        return ac;
+        if (typeAnnotation) {
+            if (a.attribute == null || !(a.attribute instanceof Attribute.TypeCompound)) {
+                // Create a new TypeCompound
+                Attribute.TypeCompound tc = new Attribute.TypeCompound(a.type, buf.toList(), new TypeAnnotationPosition());
+                a.attribute = tc;
+                return tc;
+            } else {
+                // Use an existing TypeCompound
+                return a.attribute;
+            }
+        } else {
+            Attribute.Compound ac = new Attribute.Compound(a.type, buf.toList());
+            a.attribute = ac;
+            return ac;
+        }
     }
 
     Attribute enterAttributeValue(Type expected,
@@ -354,15 +387,6 @@
         return new Attribute.Error(attr.attribExpr(tree, env, expected));
     }
 
-    Attribute.TypeCompound enterTypeAnnotation(JCAnnotation a,
-            Type expected,
-            Env<AttrContext> env) {
-        Attribute.Compound c = enterAnnotation(a, expected, env);
-        Attribute.TypeCompound tc = new Attribute.TypeCompound(c.type, c.values, new TypeAnnotationPosition());
-        a.attribute = tc;
-        return tc;
-    }
-
     /* *********************************
      * Support for repeating annotations
      ***********************************/
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
index 3499886..bff462f 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
@@ -768,7 +768,12 @@
         JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
 
         try {
-            memberEnter.typeAnnotate(initializer, env, env.info.enclVar);
+            // Use null as symbol to not attach the type annotation to any symbol.
+            // The initializer will later also be visited and then we'll attach
+            // to the symbol.
+            // This prevents having multiple type annotations, just because of
+            // lazy constant value evaluation.
+            memberEnter.typeAnnotate(initializer, env, null);
             annotate.flush();
             Type itype = attribExpr(initializer, env, type);
             if (itype.constValue() != null)
@@ -935,11 +940,6 @@
                 Env<AttrContext> newEnv = memberEnter.methodEnv(tree, env);
                 attribType(tree.recvparam, newEnv);
                 chk.validate(tree.recvparam, newEnv);
-                if (!(tree.recvparam.type == m.owner.type || types.isSameType(tree.recvparam.type, m.owner.type))) {
-                    // The == covers the common non-generic case, but for generic classes we need isSameType;
-                    // note that equals didn't work.
-                    log.error(tree.recvparam.pos(), "incorrect.receiver.type");
-                }
             }
 
             // annotation method checks
@@ -1056,7 +1056,10 @@
         Lint prevLint = chk.setLint(lint);
 
         // Check that the variable's declared type is well-formed.
-        chk.validate(tree.vartype, env);
+        boolean isImplicitLambdaParameter = env.tree.hasTag(LAMBDA) &&
+                ((JCLambda)env.tree).paramKind == JCLambda.ParameterKind.IMPLICIT &&
+                (tree.sym.flags() & PARAMETER) != 0;
+        chk.validate(tree.vartype, env, !isImplicitLambdaParameter);
         deferredLintHandler.flush(tree.pos());
 
         try {
@@ -1112,6 +1115,18 @@
             memberEnter.typeAnnotate(tree, localEnv, localEnv.info.scope.owner);
             annotate.flush();
 
+            {
+                // Store init and clinit type annotations with the ClassSymbol
+                // to allow output in Gen.normalizeDefs.
+                ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
+                List<Attribute.TypeCompound> tas = localEnv.info.scope.owner.getRawTypeAttributes();
+                if ((tree.flags & STATIC) != 0) {
+                    cs.annotations.appendClassInitTypeAttributes(tas);
+                } else {
+                    cs.annotations.appendInitTypeAttributes(tas);
+                }
+            }
+
             attribStats(tree.stats, localEnv);
         } else {
             // Create a new local environment with a local scope.
@@ -1338,7 +1353,7 @@
                         //check that resource type cannot throw InterruptedException
                         checkAutoCloseable(resource.pos(), localEnv, resource.type);
 
-                        VarSymbol var = (VarSymbol)TreeInfo.symbolFor(resource);
+                        VarSymbol var = ((JCVariableDecl) resource).sym;
                         var.setData(ElementKind.RESOURCE_VARIABLE);
                     } else {
                         attribTree(resource, tryEnv, twrResult);
@@ -2131,6 +2146,11 @@
                     tree.constructor,
                     localEnv,
                     new ResultInfo(VAL, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
+            } else {
+                if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
+                    checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations,
+                            tree.clazz.type.tsym);
+                }
             }
 
             if (tree.constructor != null && tree.constructor.kind == MTH)
@@ -2195,6 +2215,20 @@
                 }
             }
 
+    private void checkForDeclarationAnnotations(List<? extends JCAnnotation> annotations,
+            Symbol sym) {
+        // Ensure that no declaration annotations are present.
+        // Note that a tree type might be an AnnotatedType with
+        // empty annotations, if only declaration annotations were given.
+        // This method will raise an error for such a type.
+        for (JCAnnotation ai : annotations) {
+            if (TypeAnnotations.annotationType(syms, names, ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) {
+                log.error(ai.pos(), "annotation.type.not.applicable");
+            }
+        }
+    }
+
+
     /** Make an attributed null check tree.
      */
     public JCExpression makeNullCheck(JCExpression arg) {
@@ -2221,6 +2255,10 @@
                 attribExpr(l.head, localEnv, syms.intType);
                 owntype = new ArrayType(owntype, syms.arrayClass);
             }
+            if (tree.elemtype.hasTag(ANNOTATED_TYPE)) {
+                checkForDeclarationAnnotations(((JCAnnotatedType) tree.elemtype).annotations,
+                        tree.elemtype.type.tsym);
+            }
         } else {
             // we are seeing an untyped aggregate { ... }
             // this is allowed only if the prototype is an array
@@ -2309,7 +2347,7 @@
                     Type argType = arityMismatch ?
                             syms.errType :
                             actuals.head;
-                    params.head.vartype = make.Type(argType);
+                    params.head.vartype = make.at(params.head).Type(argType);
                     params.head.sym = null;
                     actuals = actuals.isEmpty() ?
                             actuals :
@@ -2356,7 +2394,8 @@
                     for (JCDiagnostic deferredDiag : lambdaDeferredHandler.getDiagnostics()) {
                         if (deferredDiag.getKind() == JCDiagnostic.Kind.ERROR) {
                             resultInfo.checkContext
-                                    .report(that, diags.fragment("bad.arg.types.in.lambda", TreeInfo.types(that.params)));
+                                    .report(that, diags.fragment("bad.arg.types.in.lambda", TreeInfo.types(that.params),
+                                    deferredDiag)); //hidden diag parameter
                             //we mark the lambda as erroneous - this is crucial in the recovery step
                             //as parameter-dependent type error won't be reported in that stage,
                             //meaning that a lambda will be deemed erroeneous only if there is
@@ -2606,10 +2645,11 @@
                 return;
             }
 
-            if (TreeInfo.isStaticSelector(that.expr, names) &&
-                    (that.getMode() != ReferenceMode.NEW || !that.expr.type.isRaw())) {
-                //if the qualifier is a type, validate it
-                chk.validate(that.expr, env);
+            if (TreeInfo.isStaticSelector(that.expr, names)) {
+                //if the qualifier is a type, validate it; raw warning check is
+                //omitted as we don't know at this stage as to whether this is a
+                //raw selector (because of inference)
+                chk.validate(that.expr, env, false);
             }
 
             //attrib type-arguments
@@ -2695,6 +2735,13 @@
 
             if (resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) {
 
+                if (that.getMode() == ReferenceMode.INVOKE &&
+                        TreeInfo.isStaticSelector(that.expr, names) &&
+                        that.kind.isUnbound() &&
+                        !desc.getParameterTypes().head.isParameterized()) {
+                    chk.checkRaw(that.expr, localEnv);
+                }
+
                 if (!that.kind.isUnbound() &&
                         that.getMode() == ReferenceMode.INVOKE &&
                         TreeInfo.isStaticSelector(that.expr, names) &&
@@ -3763,6 +3810,12 @@
                     }
                 }
                 owntype = new ClassType(clazzOuter, actuals, clazztype.tsym);
+                if (clazztype.isAnnotated()) {
+                    // Use the same AnnotatedType, because it will have
+                    // its annotations set later.
+                    ((AnnotatedType)clazztype).underlyingType = owntype;
+                    owntype = clazztype;
+                }
             } else {
                 if (formals.length() != 0) {
                     log.error(tree.pos(), "wrong.number.type.args",
@@ -3961,7 +4014,14 @@
 
         ListBuffer<Attribute.TypeCompound> buf = ListBuffer.lb();
         for (JCAnnotation anno : annotations) {
-            buf.append((Attribute.TypeCompound) anno.attribute);
+            if (anno.attribute != null) {
+                // TODO: this null-check is only needed for an obscure
+                // ordering issue, where annotate.flush is called when
+                // the attribute is not set yet. For an example failure
+                // try the referenceinfos/NestedTypes.java test.
+                // Any better solutions?
+                buf.append((Attribute.TypeCompound) anno.attribute);
+            }
         }
         return buf.toList();
     }
@@ -4266,15 +4326,12 @@
         tree.accept(typeAnnotationsValidator);
     }
     //where
-    private final JCTree.Visitor typeAnnotationsValidator =
-        new TreeScanner() {
+    private final JCTree.Visitor typeAnnotationsValidator = new TreeScanner() {
+
+        private boolean checkAllAnnotations = false;
+
         public void visitAnnotation(JCAnnotation tree) {
-            if (tree.hasTag(TYPE_ANNOTATION)) {
-                // TODO: It seems to WMD as if the annotation in
-                // parameters, in particular also the recvparam, are never
-                // of type JCTypeAnnotation and therefore never checked!
-                // Luckily this check doesn't really do anything that isn't
-                // also done elsewhere.
+            if (tree.hasTag(TYPE_ANNOTATION) || checkAllAnnotations) {
                 chk.validateTypeAnnotation(tree, false);
             }
             super.visitAnnotation(tree);
@@ -4288,15 +4345,10 @@
             // super.visitTypeParameter(tree);
         }
         public void visitMethodDef(JCMethodDecl tree) {
-            // Static methods cannot have receiver type annotations.
-            // In test case FailOver15.java, the nested method getString has
-            // a null sym, because an unknown class is instantiated.
-            // I would say it's safe to skip.
-            if (tree.sym != null && (tree.sym.flags() & Flags.STATIC) != 0) {
-                if (tree.recvparam != null) {
-                    // TODO: better error message. Is the pos good?
-                    log.error(tree.recvparam.pos(), "annotation.type.not.applicable");
-                }
+            if (tree.recvparam != null &&
+                    tree.recvparam.vartype.type.getKind() != TypeKind.ERROR) {
+                checkForDeclarationAnnotations(tree.recvparam.mods.annotations,
+                        tree.recvparam.vartype.type.tsym);
             }
             if (tree.restype != null && tree.restype.type != null) {
                 validateAnnotatedType(tree.restype, tree.restype.type);
@@ -4318,9 +4370,30 @@
                 validateAnnotatedType(tree.clazz, tree.clazz.type);
             super.visitTypeTest(tree);
         }
-        // TODO: what else do we need?
-        // public void visitNewClass(JCNewClass tree) {
-        // public void visitNewArray(JCNewArray tree) {
+        public void visitNewClass(JCNewClass tree) {
+            if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
+                boolean prevCheck = this.checkAllAnnotations;
+                try {
+                    this.checkAllAnnotations = true;
+                    scan(((JCAnnotatedType)tree.clazz).annotations);
+                } finally {
+                    this.checkAllAnnotations = prevCheck;
+                }
+            }
+            super.visitNewClass(tree);
+        }
+        public void visitNewArray(JCNewArray tree) {
+            if (tree.elemtype != null && tree.elemtype.hasTag(ANNOTATED_TYPE)) {
+                boolean prevCheck = this.checkAllAnnotations;
+                try {
+                    this.checkAllAnnotations = true;
+                    scan(((JCAnnotatedType)tree.elemtype).annotations);
+                } finally {
+                    this.checkAllAnnotations = prevCheck;
+                }
+            }
+            super.visitNewArray(tree);
+        }
 
         /* I would want to model this after
          * com.sun.tools.javac.comp.Check.Validator.visitSelectInternal(JCFieldAccess)
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
index 01fc16a..cd550d6 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
@@ -1213,7 +1213,7 @@
 
     /** Validate a type expression. That is,
      *  check that all type arguments of a parametric type are within
-     *  their bounds. This must be done in a second phase after type attributon
+     *  their bounds. This must be done in a second phase after type attribution
      *  since a class might have a subclass as type parameter bound. E.g:
      *
      *  <pre>{@code
@@ -1361,23 +1361,23 @@
             for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail)
                 validateTree(l.head, checkRaw, isOuter);
         }
+    }
 
-        void checkRaw(JCTree tree, Env<AttrContext> env) {
-            if (lint.isEnabled(LintCategory.RAW) &&
-                tree.type.hasTag(CLASS) &&
-                !TreeInfo.isDiamond(tree) &&
-                !withinAnonConstr(env) &&
-                tree.type.isRaw()) {
-                log.warning(LintCategory.RAW,
-                        tree.pos(), "raw.class.use", tree.type, tree.type.tsym.type);
-            }
+    void checkRaw(JCTree tree, Env<AttrContext> env) {
+        if (lint.isEnabled(LintCategory.RAW) &&
+            tree.type.hasTag(CLASS) &&
+            !TreeInfo.isDiamond(tree) &&
+            !withinAnonConstr(env) &&
+            tree.type.isRaw()) {
+            log.warning(LintCategory.RAW,
+                    tree.pos(), "raw.class.use", tree.type, tree.type.tsym.type);
         }
-
-        boolean withinAnonConstr(Env<AttrContext> env) {
+    }
+    //where
+        private boolean withinAnonConstr(Env<AttrContext> env) {
             return env.enclClass.name.isEmpty() &&
                     env.enclMethod != null && env.enclMethod.name == names.init;
         }
-    }
 
 /* *************************************************************************
  * Exception checking
@@ -3024,9 +3024,9 @@
         // collect an inventory of the annotation elements
         Set<MethodSymbol> members = new LinkedHashSet<MethodSymbol>();
         for (Scope.Entry e = a.annotationType.type.tsym.members().elems;
-             e != null;
-             e = e.sibling)
-            if (e.sym.kind == MTH)
+                e != null;
+                e = e.sibling)
+            if (e.sym.kind == MTH && e.sym.name != names.clinit)
                 members.add((MethodSymbol) e.sym);
 
         // remove the ones that are assigned values
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
index bcf4e6b..a7d98fd 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
@@ -25,12 +25,11 @@
 package com.sun.tools.javac.comp;
 
 import com.sun.tools.javac.tree.*;
-import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
 import com.sun.tools.javac.tree.TreeMaker;
-import com.sun.tools.javac.tree.TreeScanner;
 import com.sun.tools.javac.tree.TreeTranslator;
+import com.sun.tools.javac.code.Attribute;
 import com.sun.tools.javac.code.Kinds;
 import com.sun.tools.javac.code.Scope;
 import com.sun.tools.javac.code.Symbol;
@@ -46,7 +45,6 @@
 import com.sun.tools.javac.comp.Lower.BasicFreeVarCollector;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
 
@@ -166,7 +164,7 @@
         return translate(tree, newContext != null ? newContext : context);
     }
 
-    public <T extends JCTree> T translate(T tree, TranslationContext<?> newContext) {
+    <T extends JCTree> T translate(T tree, TranslationContext<?> newContext) {
         TranslationContext<?> prevContext = context;
         try {
             context = newContext;
@@ -177,7 +175,7 @@
         }
     }
 
-    public <T extends JCTree> List<T> translate(List<T> trees, TranslationContext<?> newContext) {
+    <T extends JCTree> List<T> translate(List<T> trees, TranslationContext<?> newContext) {
         ListBuffer<T> buf = ListBuffer.lb();
         for (T tree : trees) {
             buf.append(translate(tree, newContext));
@@ -238,6 +236,24 @@
         MethodSymbol sym = (MethodSymbol)localContext.translatedSym;
         MethodType lambdaType = (MethodType) sym.type;
 
+        {
+            MethodSymbol owner = (MethodSymbol) localContext.owner;
+            ListBuffer<Attribute.TypeCompound> ownerTypeAnnos = new ListBuffer<Attribute.TypeCompound>();
+            ListBuffer<Attribute.TypeCompound> lambdaTypeAnnos = new ListBuffer<Attribute.TypeCompound>();
+
+            for (Attribute.TypeCompound tc : owner.getRawTypeAttributes()) {
+                if (tc.position.onLambda == tree) {
+                    lambdaTypeAnnos.append(tc);
+                } else {
+                    ownerTypeAnnos.append(tc);
+                }
+            }
+            if (lambdaTypeAnnos.nonEmpty()) {
+                owner.annotations.setTypeAttributes(ownerTypeAnnos.toList());
+                sym.annotations.setTypeAttributes(lambdaTypeAnnos.toList());
+            }
+        }
+
         //create the method declaration hoisting the lambda body
         JCMethodDecl lambdaDecl = make.MethodDef(make.Modifiers(sym.flags_field),
                 sym.name,
@@ -373,12 +389,15 @@
             if (lambdaContext.getSymbolMap(PARAM).containsKey(tree.sym)) {
                 Symbol translatedSym = lambdaContext.getSymbolMap(PARAM).get(tree.sym);
                 result = make.Ident(translatedSym).setType(tree.type);
+                translatedSym.annotations.setTypeAttributes(tree.sym.getRawTypeAttributes());
             } else if (lambdaContext.getSymbolMap(LOCAL_VAR).containsKey(tree.sym)) {
                 Symbol translatedSym = lambdaContext.getSymbolMap(LOCAL_VAR).get(tree.sym);
                 result = make.Ident(translatedSym).setType(tree.type);
+                translatedSym.annotations.setTypeAttributes(tree.sym.getRawTypeAttributes());
             } else if (lambdaContext.getSymbolMap(TYPE_VAR).containsKey(tree.sym)) {
                 Symbol translatedSym = lambdaContext.getSymbolMap(TYPE_VAR).get(tree.sym);
                 result = make.Ident(translatedSym).setType(translatedSym.type);
+                translatedSym.annotations.setTypeAttributes(tree.sym.getRawTypeAttributes());
             } else if (lambdaContext.getSymbolMap(CAPTURED_VAR).containsKey(tree.sym)) {
                 Symbol translatedSym = lambdaContext.getSymbolMap(CAPTURED_VAR).get(tree.sym);
                 result = make.Ident(translatedSym).setType(tree.type);
@@ -1252,8 +1271,17 @@
                 List<Type> ptypes = ((MethodType) consSym.type).getParameterTypes();
                 Type classType = consSym.owner.type;
 
+                // Build lambda parameters
+                // partially cloned from TreeMaker.Params until 8014021 is fixed
+                Symbol owner = owner();
+                ListBuffer<JCVariableDecl> paramBuff = new ListBuffer<JCVariableDecl>();
+                int i = 0;
+                for (List<Type> l = ptypes; l.nonEmpty(); l = l.tail) {
+                    paramBuff.append(make.Param(make.paramName(i++), l.head, owner));
+                }
+                List<JCVariableDecl> params = paramBuff.toList();
+
                 // Make new-class call
-                List<JCVariableDecl> params = make.Params(ptypes, owner());
                 JCNewClass nc = makeNewClass(classType, make.Idents(params));
                 nc.pos = tree.pos;
 
@@ -1274,7 +1302,11 @@
 
         @Override
         public void visitSelect(JCFieldAccess tree) {
-            if (context() != null && lambdaSelectSymbolFilter(tree.sym)) {
+            if (context() != null && tree.sym.kind == VAR &&
+                        (tree.sym.name == names._this ||
+                         tree.sym.name == names._super)) {
+                // A select of this or super means, if we are in a lambda,
+                // we much have an instance context
                 TranslationContext<?> localContext = context();
                 while (localContext != null) {
                     if (localContext.tree.hasTag(LAMBDA)) {
@@ -1525,13 +1557,6 @@
                     && sym.name != names.init;
         }
 
-        private boolean lambdaSelectSymbolFilter(Symbol sym) {
-            return (sym.kind == VAR || sym.kind == MTH) &&
-                        !sym.isStatic() &&
-                        (sym.name == names._this ||
-                        sym.name == names._super);
-        }
-
         /**
          * This is used to filter out those new class expressions that need to
          * be qualified with an enclosing tree
@@ -1667,24 +1692,33 @@
              * synthetic lambda body
              */
             Symbol translate(Name name, final Symbol sym, LambdaSymbolKind skind) {
+                Symbol ret;
                 switch (skind) {
                     case CAPTURED_THIS:
-                        return sym;  // self represented
+                        ret = sym;  // self represented
+                        break;
                     case TYPE_VAR:
                         // Just erase the type var
-                        return new VarSymbol(sym.flags(), name,
+                        ret = new VarSymbol(sym.flags(), name,
                                 types.erasure(sym.type), sym.owner);
+                        break;
                     case CAPTURED_VAR:
-                        return new VarSymbol(SYNTHETIC | FINAL, name, types.erasure(sym.type), translatedSym) {
+                        ret = new VarSymbol(SYNTHETIC | FINAL, name, types.erasure(sym.type), translatedSym) {
                             @Override
                             public Symbol baseSymbol() {
                                 //keep mapping with original captured symbol
                                 return sym;
                             }
                         };
+                        break;
                     default:
-                        return makeSyntheticVar(FINAL, name, types.erasure(sym.type), translatedSym);
+                        ret = makeSyntheticVar(FINAL, name, types.erasure(sym.type), translatedSym);
                 }
+                if (ret != sym) {
+                    ret.annotations.setDeclarationAttributes(sym.getRawAttributes());
+                    ret.annotations.setTypeAttributes(sym.getRawTypeAttributes());
+                }
+                return ret;
             }
 
             void addSymbol(Symbol sym, LambdaSymbolKind skind) {
@@ -1755,12 +1789,13 @@
                 }
                 boolean inInterface = translatedSym.owner.isInterface();
                 boolean thisReferenced = !getSymbolMap(CAPTURED_THIS).isEmpty();
-                boolean needInstance = thisReferenced || inInterface;
 
-                // If instance access isn't needed, make it static
-                // Interface methods much be public default methods, otherwise make it private
-                translatedSym.flags_field = SYNTHETIC | (needInstance? 0 : STATIC) |
-                        (inInterface? PUBLIC | DEFAULT : PRIVATE);
+                // If instance access isn't needed, make it static.
+                // Interface instance methods must be default methods.
+                // Awaiting VM channges, default methods are public
+                translatedSym.flags_field = SYNTHETIC |
+                        ((inInterface && thisReferenced)? PUBLIC : PRIVATE) |
+                        (thisReferenced? (inInterface? DEFAULT : 0) : STATIC);
 
                 //compute synthetic params
                 ListBuffer<JCVariableDecl> params = ListBuffer.lb();
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
index 6b1caf6..7ed2894 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
@@ -28,6 +28,7 @@
 import java.util.*;
 
 import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Type.AnnotatedType;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.main.Option.PkgInfo;
 import com.sun.tools.javac.tree.*;
@@ -2767,10 +2768,28 @@
         }
 
     public void visitAnnotatedType(JCAnnotatedType tree) {
-        // No need to retain type annotations any longer.
+        // No need to retain type annotations in the tree
         // tree.annotations = translate(tree.annotations);
+        tree.annotations = List.nil();
         tree.underlyingType = translate(tree.underlyingType);
-        result = tree.underlyingType;
+        // but maintain type annotations in the type.
+        if (tree.type.isAnnotated()) {
+            if (tree.underlyingType.type.isAnnotated()) {
+                // The erasure of a type variable might be annotated.
+                // Merge all annotations.
+                AnnotatedType newat = (AnnotatedType) tree.underlyingType.type;
+                AnnotatedType at = (AnnotatedType) tree.type;
+                at.underlyingType = newat.underlyingType;
+                newat.typeAnnotations = at.typeAnnotations.appendList(newat.typeAnnotations);
+                tree.type = newat;
+            } else {
+                // Create a new AnnotatedType to have the correct tag.
+                AnnotatedType oldat = (AnnotatedType) tree.type;
+                tree.type = new AnnotatedType(tree.underlyingType.type);
+                ((AnnotatedType) tree.type).typeAnnotations = oldat.typeAnnotations;
+            }
+        }
+        result = tree;
     }
 
     public void visitTypeCast(JCTypeCast tree) {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
index 1e2d1e1..74e3d97 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
@@ -31,7 +31,6 @@
 import java.util.Map;
 import java.util.Set;
 
-import javax.lang.model.type.TypeKind;
 import javax.tools.JavaFileObject;
 
 import com.sun.tools.javac.code.*;
@@ -617,7 +616,26 @@
             if (TreeInfo.isEnumInit(tree)) {
                 attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype);
             } else {
+                // Make sure type annotations are processed.
+                // But we don't have a symbol to attach them to yet - use null.
+                typeAnnotate(tree.vartype, env, null);
                 attr.attribType(tree.vartype, localEnv);
+                if (tree.nameexpr != null) {
+                    attr.attribExpr(tree.nameexpr, localEnv);
+                    MethodSymbol m = localEnv.enclMethod.sym;
+                    if (m.isConstructor()) {
+                        Type outertype = m.owner.owner.type;
+                        if (outertype.hasTag(TypeTag.CLASS)) {
+                            checkType(tree.vartype, outertype, "incorrect.constructor.receiver.type");
+                            checkType(tree.nameexpr, outertype, "incorrect.constructor.receiver.name");
+                        } else {
+                            log.error(tree, "receiver.parameter.not.applicable.constructor.toplevel.class");
+                        }
+                    } else {
+                        checkType(tree.vartype, m.owner.type, "incorrect.receiver.type");
+                        checkType(tree.nameexpr, m.owner.type, "incorrect.receiver.name");
+                    }
+                }
             }
         } finally {
             chk.setDeferredLintHandler(prevLintHandler);
@@ -651,10 +669,16 @@
             enclScope.enter(v);
         }
         annotateLater(tree.mods.annotations, localEnv, v);
-        typeAnnotate(tree.vartype, env, tree.sym);
+        typeAnnotate(tree.vartype, env, v);
         annotate.flush();
         v.pos = tree.pos;
     }
+    // where
+    void checkType(JCTree tree, Type type, String diag) {
+        if (!tree.type.isErroneous() && !types.isSameType(tree.type, type)) {
+            log.error(tree, diag, type, tree.type);
+        }
+    }
 
     /** Create a fresh environment for a variable's initializer.
      *  If the variable is a field, the owner of the environment's scope
@@ -1040,9 +1064,12 @@
                 isFirst = true;
             }
         }
-        annotate.afterRepeated(TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree));
+        TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree, annotate);
     }
 
+    /*
+     * If the symbol is non-null, attach the type annotation to it.
+     */
     private void actualEnterTypeAnnotations(final List<JCAnnotation> annotations,
             final Env<AttrContext> env,
             final Symbol s) {
@@ -1075,8 +1102,10 @@
             }
         }
 
-        s.annotations.appendTypeAttributesWithCompletion(
-                annotate.new AnnotateRepeatedContext<Attribute.TypeCompound>(env, annotated, pos, log, true));
+        if (s != null) {
+            s.annotations.appendTypeAttributesWithCompletion(
+                    annotate.new AnnotateRepeatedContext<Attribute.TypeCompound>(env, annotated, pos, log, true));
+        }
     }
 
     public void typeAnnotate(final JCTree tree, final Env<AttrContext> env, final Symbol sym) {
@@ -1150,6 +1179,33 @@
             // Do not annotate the body, just the signature.
             // scan(tree.body);
         }
+
+        @Override
+        public void visitVarDef(final JCVariableDecl tree) {
+            if (sym != null && sym.kind == Kinds.VAR) {
+                // Don't visit a parameter once when the sym is the method
+                // and once when the sym is the parameter.
+                scan(tree.mods);
+                scan(tree.vartype);
+            }
+            scan(tree.init);
+        }
+
+        @Override
+        public void visitClassDef(JCClassDecl tree) {
+            // We can only hit a classdef if it is declared within
+            // a method. Ignore it - the class will be visited
+            // separately later.
+        }
+
+        @Override
+        public void visitNewClass(JCNewClass tree) {
+            if (tree.def == null) {
+                // For an anonymous class instantiation the class
+                // will be visited separately.
+                super.visitNewClass(tree);
+            }
+        }
     }
 
 
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
index 03ae288..de949a7 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
@@ -37,7 +37,10 @@
 import com.sun.tools.javac.comp.Infer.InferenceContext;
 import com.sun.tools.javac.comp.Infer.FreeTypeListener;
 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
+import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.DiagnosticRewriter;
+import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template;
 import com.sun.tools.javac.jvm.*;
+import com.sun.tools.javac.main.Option;
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
@@ -94,6 +97,7 @@
     public final boolean allowDefaultMethods;
     public final boolean allowStructuralMostSpecific;
     private final boolean debugResolve;
+    private final boolean compactMethodDiags;
     final EnumSet<VerboseResolutionMode> verboseResolutionMode;
 
     Scope polymorphicSignatureScope;
@@ -124,6 +128,8 @@
         varargsEnabled = source.allowVarargs();
         Options options = Options.instance(context);
         debugResolve = options.isSet("debugresolve");
+        compactMethodDiags = options.isSet(Option.XDIAGS, "compact") ||
+                options.isUnset(Option.XDIAGS) && options.isUnset("rawDiagnostics");
         verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
         Target target = Target.instance(context);
         allowMethodHandles = target.hasMethodHandles();
@@ -661,6 +667,10 @@
             this.basicKey = basicKey;
             this.inferKey = inferKey;
         }
+
+        String regex() {
+            return String.format("([a-z]*\\.)*(%s|%s)", basicKey, inferKey);
+        }
     }
 
     /**
@@ -691,6 +701,7 @@
                                     Warner warn) {
             //should we expand formals?
             boolean useVarargs = deferredAttrContext.phase.isVarargsRequired();
+            List<JCExpression> trees = TreeInfo.args(env.tree);
 
             //inference context used during this method check
             InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
@@ -699,17 +710,19 @@
 
             if (varargsFormal == null &&
                     argtypes.size() != formals.size()) {
-                reportMC(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
+                reportMC(env.tree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
             }
 
             while (argtypes.nonEmpty() && formals.head != varargsFormal) {
-                checkArg(false, argtypes.head, formals.head, deferredAttrContext, warn);
+                DiagnosticPosition pos = trees != null ? trees.head : null;
+                checkArg(pos, false, argtypes.head, formals.head, deferredAttrContext, warn);
                 argtypes = argtypes.tail;
                 formals = formals.tail;
+                trees = trees != null ? trees.tail : trees;
             }
 
             if (formals.head != varargsFormal) {
-                reportMC(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
+                reportMC(env.tree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
             }
 
             if (useVarargs) {
@@ -717,8 +730,10 @@
                 //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
                 final Type elt = types.elemtype(varargsFormal);
                 while (argtypes.nonEmpty()) {
-                    checkArg(true, argtypes.head, elt, deferredAttrContext, warn);
+                    DiagnosticPosition pos = trees != null ? trees.head : null;
+                    checkArg(pos, true, argtypes.head, elt, deferredAttrContext, warn);
                     argtypes = argtypes.tail;
+                    trees = trees != null ? trees.tail : trees;
                 }
             }
         }
@@ -726,9 +741,9 @@
         /**
          * Does the actual argument conforms to the corresponding formal?
          */
-        abstract void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn);
+        abstract void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn);
 
-        protected void reportMC(MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) {
+        protected void reportMC(DiagnosticPosition pos, MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) {
             boolean inferDiag = inferenceContext != infer.emptyContext;
             InapplicableMethodException ex = inferDiag ?
                     infer.inferenceException : inapplicableMethodException;
@@ -738,7 +753,8 @@
                 args2[0] = inferenceContext.inferenceVars();
                 args = args2;
             }
-            throw ex.setMessage(inferDiag ? diag.inferKey : diag.basicKey, args);
+            String key = inferDiag ? diag.inferKey : diag.basicKey;
+            throw ex.setMessage(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args));
         }
 
         public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
@@ -752,7 +768,7 @@
      */
     MethodCheck arityMethodCheck = new AbstractMethodCheck() {
         @Override
-        void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
+        void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
             //do nothing - actual always compatible to formals
         }
     };
@@ -778,9 +794,9 @@
     MethodCheck resolveMethodCheck = new AbstractMethodCheck() {
 
         @Override
-        void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
+        void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
             ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn);
-            mresult.check(null, actual);
+            mresult.check(pos, actual);
         }
 
         @Override
@@ -809,7 +825,7 @@
             } else {
                 if (!isAccessible(env, t)) {
                     Symbol location = env.enclClass.sym;
-                    reportMC(MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location);
+                    reportMC(env.tree, MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location);
                 }
             }
         }
@@ -822,7 +838,7 @@
 
                 @Override
                 public void report(DiagnosticPosition pos, JCDiagnostic details) {
-                    reportMC(methodDiag, deferredAttrContext.inferenceContext, details);
+                    reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details);
                 }
             };
             return new MethodResultInfo(to, checkContext);
@@ -3327,6 +3343,18 @@
             }
             else {
                 Candidate c = errCandidate();
+                if (compactMethodDiags) {
+                    for (Map.Entry<Template, DiagnosticRewriter> _entry :
+                            MethodResolutionDiagHelper.rewriters.entrySet()) {
+                        if (_entry.getKey().matches(c.details)) {
+                            JCDiagnostic simpleDiag =
+                                    _entry.getValue().rewriteDiagnostic(diags, pos,
+                                        log.currentSource(), dkind, c.details);
+                            simpleDiag.setFlag(DiagnosticFlag.COMPRESSED);
+                            return simpleDiag;
+                        }
+                    }
+                }
                 Symbol ws = c.sym.asMemberOf(site, types);
                 return diags.create(dkind, log.currentSource(), pos,
                           "cant.apply.symbol",
@@ -3375,35 +3403,75 @@
                 Name name,
                 List<Type> argtypes,
                 List<Type> typeargtypes) {
-            if (!resolveContext.candidates.isEmpty()) {
+            Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates();
+            Map<Symbol, JCDiagnostic> filteredCandidates = filterCandidates(candidatesMap);
+            if (filteredCandidates.isEmpty()) {
+                filteredCandidates = candidatesMap;
+            }
+            boolean truncatedDiag = candidatesMap.size() != filteredCandidates.size();
+            if (filteredCandidates.size() > 1) {
                 JCDiagnostic err = diags.create(dkind,
+                        null,
+                        truncatedDiag ?
+                            EnumSet.of(DiagnosticFlag.COMPRESSED) :
+                            EnumSet.noneOf(DiagnosticFlag.class),
                         log.currentSource(),
                         pos,
                         "cant.apply.symbols",
                         name == names.init ? KindName.CONSTRUCTOR : absentKind(kind),
                         name == names.init ? site.tsym.name : name,
                         methodArguments(argtypes));
-                return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site));
+                return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(filteredCandidates, site));
+            } else if (filteredCandidates.size() == 1) {
+                JCDiagnostic d =  new InapplicableSymbolError(resolveContext).getDiagnostic(dkind, pos,
+                    location, site, name, argtypes, typeargtypes);
+                if (truncatedDiag) {
+                    d.setFlag(DiagnosticFlag.COMPRESSED);
+                }
+                return d;
             } else {
                 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
                     location, site, name, argtypes, typeargtypes);
             }
         }
-
         //where
-        List<JCDiagnostic> candidateDetails(Type site) {
-            Map<Symbol, JCDiagnostic> details = new LinkedHashMap<Symbol, JCDiagnostic>();
-            for (Candidate c : resolveContext.candidates) {
-                if (c.isApplicable()) continue;
-                JCDiagnostic detailDiag = diags.fragment("inapplicable.method",
-                        Kinds.kindName(c.sym),
-                        c.sym.location(site, types),
-                        c.sym.asMemberOf(site, types),
-                        c.details);
-                details.put(c.sym, detailDiag);
+            private Map<Symbol, JCDiagnostic> mapCandidates() {
+                Map<Symbol, JCDiagnostic> candidates = new LinkedHashMap<Symbol, JCDiagnostic>();
+                for (Candidate c : resolveContext.candidates) {
+                    if (c.isApplicable()) continue;
+                    candidates.put(c.sym, c.details);
+                }
+                return candidates;
             }
-            return List.from(details.values());
-        }
+
+            Map<Symbol, JCDiagnostic> filterCandidates(Map<Symbol, JCDiagnostic> candidatesMap) {
+                Map<Symbol, JCDiagnostic> candidates = new LinkedHashMap<Symbol, JCDiagnostic>();
+                for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) {
+                    JCDiagnostic d = _entry.getValue();
+                    if (!compactMethodDiags ||
+                            !new Template(MethodCheckDiag.ARITY_MISMATCH.regex()).matches(d)) {
+                        candidates.put(_entry.getKey(), d);
+                    }
+                }
+                return candidates;
+            }
+
+            private List<JCDiagnostic> candidateDetails(Map<Symbol, JCDiagnostic> candidatesMap, Type site) {
+                List<JCDiagnostic> details = List.nil();
+                for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) {
+                    Symbol sym = _entry.getKey();
+                    JCDiagnostic detailDiag = diags.fragment("inapplicable.method",
+                            Kinds.kindName(sym),
+                            sym.location(site, types),
+                            sym.asMemberOf(site, types),
+                            _entry.getValue());
+                    details = details.prepend(detailDiag);
+                }
+                //typically members are visited in reverse order (see Scope)
+                //so we need to reverse the candidate list so that candidates
+                //conform to source order
+                return details;
+            }
     }
 
     /**
@@ -3624,6 +3692,105 @@
         }
     }
 
+    /**
+     * Helper class for method resolution diagnostic simplification.
+     * Certain resolution diagnostic are rewritten as simpler diagnostic
+     * where the enclosing resolution diagnostic (i.e. 'inapplicable method')
+     * is stripped away, as it doesn't carry additional info. The logic
+     * for matching a given diagnostic is given in terms of a template
+     * hierarchy: a diagnostic template can be specified programmatically,
+     * so that only certain diagnostics are matched. Each templete is then
+     * associated with a rewriter object that carries out the task of rewtiting
+     * the diagnostic to a simpler one.
+     */
+    static class MethodResolutionDiagHelper {
+
+        /**
+         * A diagnostic rewriter transforms a method resolution diagnostic
+         * into a simpler one
+         */
+        interface DiagnosticRewriter {
+            JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
+                    DiagnosticPosition preferedPos, DiagnosticSource preferredSource,
+                    DiagnosticType preferredKind, JCDiagnostic d);
+        }
+
+        /**
+         * A diagnostic template is made up of two ingredients: (i) a regular
+         * expression for matching a diagnostic key and (ii) a list of sub-templates
+         * for matching diagnostic arguments.
+         */
+        static class Template {
+
+            /** regex used to match diag key */
+            String regex;
+
+            /** templates used to match diagnostic args */
+            Template[] subTemplates;
+
+            Template(String key, Template... subTemplates) {
+                this.regex = key;
+                this.subTemplates = subTemplates;
+            }
+
+            /**
+             * Returns true if the regex matches the diagnostic key and if
+             * all diagnostic arguments are matches by corresponding sub-templates.
+             */
+            boolean matches(Object o) {
+                JCDiagnostic d = (JCDiagnostic)o;
+                Object[] args = d.getArgs();
+                if (!d.getCode().matches(regex) ||
+                        subTemplates.length != d.getArgs().length) {
+                    return false;
+                }
+                for (int i = 0; i < args.length ; i++) {
+                    if (!subTemplates[i].matches(args[i])) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+        }
+
+        /** a dummy template that match any diagnostic argument */
+        static final Template skip = new Template("") {
+            @Override
+            boolean matches(Object d) {
+                return true;
+            }
+        };
+
+        /** rewriter map used for method resolution simplification */
+        static final Map<Template, DiagnosticRewriter> rewriters =
+                new LinkedHashMap<Template, DiagnosticRewriter>();
+
+        static {
+            String argMismatchRegex = MethodCheckDiag.ARG_MISMATCH.regex();
+            rewriters.put(new Template(argMismatchRegex, new Template("(.*)(bad.arg.types.in.lambda)", skip, skip)),
+                    new DiagnosticRewriter() {
+                @Override
+                public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
+                        DiagnosticPosition preferedPos, DiagnosticSource preferredSource,
+                        DiagnosticType preferredKind, JCDiagnostic d) {
+                    return (JCDiagnostic)((JCDiagnostic)d.getArgs()[0]).getArgs()[1];
+                }
+            });
+
+            rewriters.put(new Template(argMismatchRegex, skip),
+                    new DiagnosticRewriter() {
+                @Override
+                public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
+                        DiagnosticPosition preferedPos, DiagnosticSource preferredSource,
+                        DiagnosticType preferredKind, JCDiagnostic d) {
+                    JCDiagnostic cause = (JCDiagnostic)d.getArgs()[0];
+                    return diags.create(preferredKind, preferredSource, d.getDiagnosticPosition(),
+                            "prob.found.req", cause);
+                }
+            });
+        }
+    }
+
     enum MethodResolutionPhase {
         BASIC(false, false),
         BOX(true, false),
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
index 85b1a20..ca6ebbb 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
@@ -1518,7 +1518,7 @@
             break;
         // exception parameter
         case EXCEPTION_PARAMETER:
-            position.exception_index = nextByte();
+            position.exception_index = nextChar();
             break;
         // method receiver
         case METHOD_RECEIVER:
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
index 5ce323b..8c020a4 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
@@ -632,7 +632,7 @@
             acount++;
         }
         acount += writeJavaAnnotations(sym.getRawAttributes());
-        acount += writeTypeAnnotations(sym.getRawTypeAttributes());
+        acount += writeTypeAnnotations(sym.getRawTypeAttributes(), false);
         return acount;
     }
 
@@ -759,44 +759,30 @@
         return attrCount;
     }
 
-    int writeTypeAnnotations(List<Attribute.TypeCompound> typeAnnos) {
+    int writeTypeAnnotations(List<Attribute.TypeCompound> typeAnnos, boolean inCode) {
         if (typeAnnos.isEmpty()) return 0;
 
         ListBuffer<Attribute.TypeCompound> visibles = ListBuffer.lb();
         ListBuffer<Attribute.TypeCompound> invisibles = ListBuffer.lb();
 
         for (Attribute.TypeCompound tc : typeAnnos) {
-            if (tc.position == null || tc.position.type == TargetType.UNKNOWN) {
-                boolean found = false;
-                // TODO: the position for the container annotation of a
-                // repeating type annotation has to be set.
-                // This cannot be done when the container is created, because
-                // then the position is not determined yet.
-                // How can we link these pieces better together?
-                if (tc.values.size() == 1) {
-                    Pair<MethodSymbol, Attribute> val = tc.values.get(0);
-                    if (val.fst.getSimpleName().contentEquals("value") &&
-                            val.snd instanceof Attribute.Array) {
-                        Attribute.Array arr = (Attribute.Array) val.snd;
-                        if (arr.values.length != 0 &&
-                                arr.values[0] instanceof Attribute.TypeCompound) {
-                            TypeCompound atycomp = (Attribute.TypeCompound) arr.values[0];
-                            if (atycomp.position.type != TargetType.UNKNOWN) {
-                                tc.position = atycomp.position;
-                                found = true;
-                            }
-                        }
-                    }
-                }
-                if (!found) {
+            if (tc.hasUnknownPosition()) {
+                boolean fixed = tc.tryFixPosition();
+
+                // Could we fix it?
+                if (!fixed) {
                     // This happens for nested types like @A Outer. @B Inner.
                     // For method parameters we get the annotation twice! Once with
                     // a valid position, once unknown.
                     // TODO: find a cleaner solution.
-                    // System.err.println("ClassWriter: Position UNKNOWN in type annotation: " + tc);
+                    PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
+                    pw.println("ClassWriter: Position UNKNOWN in type annotation: " + tc);
                     continue;
                 }
             }
+
+            if (tc.position.type.isLocal() != inCode)
+                continue;
             if (!tc.position.emitToClassfile())
                 continue;
             switch (types.getRetention(tc)) {
@@ -936,7 +922,7 @@
             break;
         // exception parameter
         case EXCEPTION_PARAMETER:
-            databuf.appendByte(p.exception_index);
+            databuf.appendChar(p.exception_index);
             break;
         // method receiver
         case METHOD_RECEIVER:
@@ -1241,6 +1227,9 @@
             endAttr(alenIdx);
             acount++;
         }
+
+        acount += writeTypeAnnotations(code.meth.getRawTypeAttributes(), true);
+
         endAttrs(acountIdx, acount);
     }
     //where
@@ -1627,7 +1616,7 @@
             out = null;
         } finally {
             if (out != null) {
-                // if we are propogating an exception, delete the file
+                // if we are propagating an exception, delete the file
                 out.close();
                 outFile.delete();
                 outFile = null;
@@ -1741,7 +1730,7 @@
 
         acount += writeFlagAttrs(c.flags());
         acount += writeJavaAnnotations(c.getRawAttributes());
-        acount += writeTypeAnnotations(c.getRawTypeAttributes());
+        acount += writeTypeAnnotations(c.getRawTypeAttributes(), false);
         acount += writeEnclosingMethodAttribute(c);
         acount += writeExtraClassAttributes(c);
 
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java
index d4b8eff..90fc63f 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java
@@ -1010,7 +1010,16 @@
             state.pop(((Symbol)(pool.pool[od])).erasure(types));
             break;
         case new_:
-            state.push(uninitializedObject(((Symbol)(pool.pool[od])).erasure(types), cp-3));
+            Symbol sym;
+            if (pool.pool[od] instanceof UniqueType) {
+                // Required by change in Gen.makeRef to allow
+                // annotated types.
+                // TODO: is this needed anywhere else?
+                sym = ((UniqueType)(pool.pool[od])).type.tsym;
+            } else {
+                sym = (Symbol)(pool.pool[od]);
+            }
+            state.push(uninitializedObject(sym.erasure(types), cp-3));
             break;
         case sipush:
             state.push(syms.intType);
@@ -1972,25 +1981,38 @@
             if (lv == null || lv.sym == null
                     || lv.sym.annotations.isTypesEmpty()
                     || !lv.sym.isExceptionParameter())
-                return;
-
-            int exidx = findExceptionIndex(lv);
+                continue;
 
             for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
                 TypeAnnotationPosition p = ta.position;
-                p.exception_index = exidx;
+                // At this point p.type_index contains the catch type index.
+                // Use that index to determine the exception table index.
+                // We can afterwards discard the type_index.
+                // A TA position is shared for all type annotations in the
+                // same location; updating one is enough.
+                // Use -666 as a marker that the exception_index was already updated.
+                if (p.type_index != -666) {
+                    p.exception_index = findExceptionIndex(p.type_index);
+                    p.type_index = -666;
+                }
             }
         }
     }
 
-    private int findExceptionIndex(LocalVar lv) {
+    private int findExceptionIndex(int catchType) {
+        if (catchType == Integer.MIN_VALUE) {
+            // We didn't set the catch type index correctly.
+            // This shouldn't happen.
+            // TODO: issue error?
+            return -1;
+        }
         List<char[]> iter = catchInfo.toList();
         int len = catchInfo.length();
         for (int i = 0; i < len; ++i) {
             char[] catchEntry = iter.head;
             iter = iter.tail;
-            char handlerpc = catchEntry[2];
-            if (lv.start_pc == handlerpc + 1) {
+            char ct = catchEntry[3];
+            if (catchType == ct) {
                 return i;
             }
         }
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java
index ec11a11..739f49d 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java
@@ -30,6 +30,8 @@
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Attribute.TypeCompound;
+import com.sun.tools.javac.code.Symbol.VarSymbol;
 import com.sun.tools.javac.comp.*;
 import com.sun.tools.javac.tree.*;
 
@@ -47,7 +49,6 @@
 import static com.sun.tools.javac.jvm.CRTFlags.*;
 import static com.sun.tools.javac.main.Option.*;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
-import static com.sun.tools.javac.tree.JCTree.Tag.BLOCK;
 
 /** This pass maps flat Java (i.e. without inner classes) to bytecodes.
  *
@@ -308,7 +309,15 @@
      */
     int makeRef(DiagnosticPosition pos, Type type) {
         checkDimension(pos, type);
-        return pool.put(type.hasTag(CLASS) ? (Object)type.tsym : (Object)type);
+        if (type.isAnnotated()) {
+            // Treat annotated types separately - we don't want
+            // to collapse all of them - at least for annotated
+            // exceptions.
+            // TODO: review this.
+            return pool.put((Object)type);
+        } else {
+            return pool.put(type.hasTag(CLASS) ? (Object)type.tsym : (Object)type);
+        }
     }
 
     /** Check if the given type is an array with too many dimensions.
@@ -456,7 +465,9 @@
      */
     List<JCTree> normalizeDefs(List<JCTree> defs, ClassSymbol c) {
         ListBuffer<JCStatement> initCode = new ListBuffer<JCStatement>();
+        ListBuffer<Attribute.TypeCompound> initTAs = new ListBuffer<Attribute.TypeCompound>();
         ListBuffer<JCStatement> clinitCode = new ListBuffer<JCStatement>();
+        ListBuffer<Attribute.TypeCompound> clinitTAs = new ListBuffer<Attribute.TypeCompound>();
         ListBuffer<JCTree> methodDefs = new ListBuffer<JCTree>();
         // Sort definitions into three listbuffers:
         //  - initCode for instance initializers
@@ -486,6 +497,7 @@
                             Assignment(sym, vdef.init);
                         initCode.append(init);
                         endPosTable.replaceTree(vdef, init);
+                        initTAs.addAll(getAndRemoveNonFieldTAs(sym));
                     } else if (sym.getConstValue() == null) {
                         // Initialize class (static) variables only if
                         // they are not compile-time constants.
@@ -493,6 +505,7 @@
                             Assignment(sym, vdef.init);
                         clinitCode.append(init);
                         endPosTable.replaceTree(vdef, init);
+                        clinitTAs.addAll(getAndRemoveNonFieldTAs(sym));
                     } else {
                         checkStringConstant(vdef.init.pos(), sym.getConstValue());
                     }
@@ -505,8 +518,10 @@
         // Insert any instance initializers into all constructors.
         if (initCode.length() != 0) {
             List<JCStatement> inits = initCode.toList();
+            initTAs.addAll(c.annotations.getInitTypeAttributes());
+            List<Attribute.TypeCompound> initTAlist = initTAs.toList();
             for (JCTree t : methodDefs) {
-                normalizeMethod((JCMethodDecl)t, inits);
+                normalizeMethod((JCMethodDecl)t, inits, initTAlist);
             }
         }
         // If there are class initializers, create a <clinit> method
@@ -524,11 +539,31 @@
             JCBlock block = make.at(clinitStats.head.pos()).Block(0, clinitStats);
             block.endpos = TreeInfo.endPos(clinitStats.last());
             methodDefs.append(make.MethodDef(clinit, block));
+
+            if (!clinitTAs.isEmpty())
+                clinit.annotations.appendUniqueTypes(clinitTAs.toList());
+            if (!c.annotations.getClassInitTypeAttributes().isEmpty())
+                clinit.annotations.appendUniqueTypes(c.annotations.getClassInitTypeAttributes());
         }
         // Return all method definitions.
         return methodDefs.toList();
     }
 
+    private List<Attribute.TypeCompound> getAndRemoveNonFieldTAs(VarSymbol sym) {
+        List<TypeCompound> tas = sym.getRawTypeAttributes();
+        ListBuffer<Attribute.TypeCompound> fieldTAs = new ListBuffer<Attribute.TypeCompound>();
+        ListBuffer<Attribute.TypeCompound> nonfieldTAs = new ListBuffer<Attribute.TypeCompound>();
+        for (TypeCompound ta : tas) {
+            if (ta.position.type == TargetType.FIELD) {
+                fieldTAs.add(ta);
+            } else {
+                nonfieldTAs.add(ta);
+            }
+        }
+        sym.annotations.setTypeAttributes(fieldTAs.toList());
+        return nonfieldTAs.toList();
+    }
+
     /** Check a constant value and report if it is a string that is
      *  too large.
      */
@@ -546,8 +581,9 @@
      *  @param md        The tree potentially representing a
      *                   constructor's definition.
      *  @param initCode  The list of instance initializer statements.
+     *  @param initTAs  Type annotations from the initializer expression.
      */
-    void normalizeMethod(JCMethodDecl md, List<JCStatement> initCode) {
+    void normalizeMethod(JCMethodDecl md, List<JCStatement> initCode, List<TypeCompound> initTAs) {
         if (md.name == names.init && TreeInfo.isInitialConstructor(md)) {
             // We are seeing a constructor that does not call another
             // constructor of the same class.
@@ -581,6 +617,8 @@
             md.body.stats = newstats.toList();
             if (md.body.endpos == Position.NOPOS)
                 md.body.endpos = TreeInfo.endPos(md.body.stats.last());
+
+            md.sym.annotations.appendUniqueTypes(initTAs);
         }
     }
 
@@ -1527,6 +1565,11 @@
                         registerCatch(tree.pos(),
                                       startpc,  end, code.curPc(),
                                       catchType);
+                        if (subCatch.type.isAnnotated()) {
+                            // All compounds share the same position, simply update the
+                            // first one.
+                            subCatch.type.getAnnotationMirrors().head.position.type_index = catchType;
+                        }
                     }
                     gaps = gaps.tail;
                     startpc = gaps.head.intValue();
@@ -1538,6 +1581,11 @@
                         registerCatch(tree.pos(),
                                       startpc, endpc, code.curPc(),
                                       catchType);
+                        if (subCatch.type.isAnnotated()) {
+                            // All compounds share the same position, simply update the
+                            // first one.
+                            subCatch.type.getAnnotationMirrors().head.position.type_index = catchType;
+                        }
                     }
                 }
                 VarSymbol exparam = tree.param.sym;
@@ -1783,42 +1831,44 @@
         result = items.makeStackItem(pt);
     }
 
-   private void setTypeAnnotationPositions(int treePos) {
-       MethodSymbol meth = code.meth;
+    private void setTypeAnnotationPositions(int treePos) {
+        MethodSymbol meth = code.meth;
+        boolean initOrClinit = code.meth.getKind() == javax.lang.model.element.ElementKind.CONSTRUCTOR
+                || code.meth.getKind() == javax.lang.model.element.ElementKind.STATIC_INIT;
 
-       for (Attribute.TypeCompound ta : meth.getRawTypeAttributes()) {
-           if (ta.position.pos == treePos) {
-               ta.position.offset = code.cp;
-               ta.position.lvarOffset = new int[] { code.cp };
-               ta.position.isValidOffset = true;
-           }
-       }
+        for (Attribute.TypeCompound ta : meth.getRawTypeAttributes()) {
+            if (ta.hasUnknownPosition())
+                ta.tryFixPosition();
 
-       if (code.meth.getKind() != javax.lang.model.element.ElementKind.CONSTRUCTOR
-               && code.meth.getKind() != javax.lang.model.element.ElementKind.STATIC_INIT)
-           return;
+            if (ta.position.matchesPos(treePos))
+                ta.position.updatePosOffset(code.cp);
+        }
 
-       for (Attribute.TypeCompound ta : meth.owner.getRawTypeAttributes()) {
-           if (ta.position.pos == treePos) {
-               ta.position.offset = code.cp;
-               ta.position.lvarOffset = new int[] { code.cp };
-               ta.position.isValidOffset = true;
-           }
-       }
+        if (!initOrClinit)
+            return;
 
-       ClassSymbol clazz = meth.enclClass();
-       for (Symbol s : new com.sun.tools.javac.model.FilteredMemberList(clazz.members())) {
-           if (!s.getKind().isField())
-               continue;
-           for (Attribute.TypeCompound ta : s.getRawTypeAttributes()) {
-               if (ta.position.pos == treePos) {
-                   ta.position.offset = code.cp;
-                   ta.position.lvarOffset = new int[] { code.cp };
-                   ta.position.isValidOffset = true;
-               }
-           }
-       }
-   }
+        for (Attribute.TypeCompound ta : meth.owner.getRawTypeAttributes()) {
+            if (ta.hasUnknownPosition())
+                ta.tryFixPosition();
+
+            if (ta.position.matchesPos(treePos))
+                ta.position.updatePosOffset(code.cp);
+        }
+
+        ClassSymbol clazz = meth.enclClass();
+        for (Symbol s : new com.sun.tools.javac.model.FilteredMemberList(clazz.members())) {
+            if (!s.getKind().isField())
+                continue;
+
+            for (Attribute.TypeCompound ta : s.getRawTypeAttributes()) {
+                if (ta.hasUnknownPosition())
+                    ta.tryFixPosition();
+
+                if (ta.position.matchesPos(treePos))
+                    ta.position.updatePosOffset(code.cp);
+            }
+        }
+    }
 
     public void visitNewClass(JCNewClass tree) {
         // Enclosing instances or anonymous classes should have been eliminated
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java
index 139ba51..bd8e340 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java
@@ -157,13 +157,6 @@
         if (c.isLocal() || (c.flags() & Flags.SYNTHETIC) != 0)
             return false;
 
-        /* temporary code for backwards compatibility */
-        for (Attribute.Compound a: c.annotations.getDeclarationAttributes()) {
-            if (a.type.tsym == syms.nativeHeaderType_old.tsym)
-                return true;
-        }
-        /* end of temporary code for backwards compatibility */
-
         for (Scope.Entry i = c.members_field.elems; i != null; i = i.sibling) {
             if (i.sym.kind == Kinds.MTH && (i.sym.flags() & Flags.NATIVE) != 0)
                 return true;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java
index f186a81..291a341 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java
@@ -25,7 +25,6 @@
 
 package com.sun.tools.javac.main;
 
-import com.sun.tools.javac.comp.CompileStates;
 import java.io.*;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -55,6 +54,7 @@
 import com.sun.tools.javac.code.Lint.LintCategory;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.comp.*;
+import com.sun.tools.javac.comp.CompileStates.CompileState;
 import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.parser.*;
@@ -62,7 +62,6 @@
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.comp.CompileStates.CompileState;
 import com.sun.tools.javac.util.Log.WriterKind;
 
 import static com.sun.tools.javac.code.TypeTag.CLASS;
@@ -484,7 +483,7 @@
      */
     protected boolean werror;
 
-    /** Switch: is annotation processing requested explitly via
+    /** Switch: is annotation processing requested explicitly via
      * CompilationTask.setProcessors?
      */
     protected boolean explicitAnnotationProcessingRequested = false;
@@ -1615,6 +1614,9 @@
                 log.warning("proc.use.proc.or.implicit");
         }
         chk.reportDeferredDiagnostics();
+        if (log.compressedOutput) {
+            log.mandatoryNote(null, "compressed.diags");
+        }
     }
 
     /** Close the compiler, flushing the logs
@@ -1666,6 +1668,7 @@
                     throw new FatalError(msg, e);
                 }
             }
+            closeables = List.nil();
         }
     }
 
diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java
index 9c74095..44a6cd5 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java
@@ -35,7 +35,6 @@
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
-import java.util.ServiceLoader;
 import java.util.Set;
 
 import javax.annotation.processing.Processor;
@@ -56,6 +55,7 @@
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.Log.PrefixKind;
 import com.sun.tools.javac.util.Log.WriterKind;
+import com.sun.tools.javac.util.ServiceLoader;
 import static com.sun.tools.javac.main.Option.*;
 
 /** This class provides a command line interface to the javac compiler.
@@ -469,7 +469,6 @@
                                 pluginMessage(ex);
                                 return Result.SYSERR;
                             }
-
                         }
                     }
                 }
diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/Option.java b/langtools/src/share/classes/com/sun/tools/javac/main/Option.java
index b6bfa33..dd3bbe8 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/main/Option.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/Option.java
@@ -407,6 +407,8 @@
         }
     },
 
+    XDIAGS("-Xdiags:", "opt.diags", EXTENDED, BASIC, ONEOF, "compact", "verbose"),
+
     /* This is a back door to the compiler's option table.
      * -XDx=y sets the option x to the value y.
      * -XDx sets the option x to the value x.
diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
index 17e9d94..bdd79d0 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
@@ -2013,7 +2013,7 @@
     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
      */
     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
-        List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
+        List<JCAnnotation> newAnnotations = annotationsOpt(Tag.ANNOTATION);
 
         switch (token.kind) {
         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
@@ -2030,11 +2030,6 @@
         }
         JCExpression t = qualident(true);
 
-        // handle type annotations for non primitive arrays
-        if (newAnnotations.nonEmpty()) {
-            t = insertAnnotationsToMostInner(t, newAnnotations, false);
-        }
-
         int oldmode = mode;
         mode = TYPE;
         boolean diamondFound = false;
@@ -2068,6 +2063,11 @@
         }
         mode = oldmode;
         if (token.kind == LBRACKET || token.kind == MONKEYS_AT) {
+            // handle type annotations for non primitive arrays
+            if (newAnnotations.nonEmpty()) {
+                t = insertAnnotationsToMostInner(t, newAnnotations, false);
+            }
+
             JCExpression e = arrayCreatorRest(newpos, t);
             if (diamondFound) {
                 reportSyntaxError(lastTypeargsPos, "cannot.create.array.with.diamond");
@@ -2092,8 +2092,18 @@
             if (newClass.def != null) {
                 assert newClass.def.mods.annotations.isEmpty();
                 if (newAnnotations.nonEmpty()) {
+                    // Add type and declaration annotations to the new class;
+                    // com.sun.tools.javac.code.TypeAnnotations.TypeAnnotationPositions.visitNewClass(JCNewClass)
+                    // will later remove all type annotations and only leave the
+                    // declaration annotations.
                     newClass.def.mods.pos = earlier(newClass.def.mods.pos, newAnnotations.head.pos);
-                    newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations);
+                    newClass.def.mods.annotations = newAnnotations;
+                }
+            } else {
+                // handle type annotations for instantiations
+                if (newAnnotations.nonEmpty()) {
+                    t = insertAnnotationsToMostInner(t, newAnnotations, false);
+                    newClass.clazz = t;
                 }
             }
             return newClass;
@@ -2987,7 +2997,22 @@
             syntaxError(pos, "expected", IDENTIFIER);
             name = token.name();
         } else {
-            name = ident();
+            if (allowThisIdent) {
+                JCExpression pn = qualident(false);
+                if (pn.hasTag(Tag.IDENT) && ((JCIdent)pn).name != names._this) {
+                    name = ((JCIdent)pn).name;
+                } else {
+                    if ((mods.flags & Flags.VARARGS) != 0) {
+                        log.error(token.pos, "varargs.and.receiver");
+                    }
+                    if (token.kind == LBRACKET) {
+                        log.error(token.pos, "array.and.receiver");
+                    }
+                    return toP(F.at(pos).ReceiverVarDef(mods, pn, type));
+                }
+            } else {
+                name = ident();
+            }
         }
         if ((mods.flags & Flags.VARARGS) != 0 &&
                 token.kind == LBRACKET) {
@@ -3526,18 +3551,24 @@
         ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
 
         List<JCAnnotation> typeAnnos = typeAnnotationsOpt();
-        if (!typeAnnos.isEmpty())
-            ts.append(toP(F.at(typeAnnos.head.pos).AnnotatedType(typeAnnos, qualident(true))));
-        else
-            ts.append(qualident(true));
+        JCExpression qi = qualident(true);
+        if (!typeAnnos.isEmpty()) {
+            JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
+            ts.append(at);
+        } else {
+            ts.append(qi);
+        }
         while (token.kind == COMMA) {
             nextToken();
 
             typeAnnos = typeAnnotationsOpt();
-            if (!typeAnnos.isEmpty())
-                ts.append(toP(F.at(typeAnnos.head.pos).AnnotatedType(typeAnnos, qualident(true))));
-            else
-                ts.append(qualident(true));
+            qi = qualident(true);
+            if (!typeAnnos.isEmpty()) {
+                JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
+                ts.append(at);
+            } else {
+                ts.append(qi);
+            }
         }
         return ts.toList();
     }
@@ -3601,7 +3632,7 @@
         if (token.kind != RPAREN) {
             this.allowThisIdent = true;
             lastParam = formalParameter(lambdaParameters);
-            if (lastParam.name.contentEquals(TokenKind.THIS.name)) {
+            if (lastParam.nameexpr != null) {
                 this.receiverParam = lastParam;
             } else {
                 params.append(lastParam);
diff --git a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java
index 48429de..83b1ee2 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java
@@ -76,6 +76,7 @@
 import com.sun.tools.javac.util.Name;
 import com.sun.tools.javac.util.Names;
 import com.sun.tools.javac.util.Options;
+import com.sun.tools.javac.util.ServiceLoader;
 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
 import static com.sun.tools.javac.main.Option.*;
 import static com.sun.tools.javac.comp.CompileStates.CompileState;
@@ -166,6 +167,7 @@
 
     protected JavacProcessingEnvironment(Context context) {
         this.context = context;
+        context.put(JavacProcessingEnvironment.class, this);
         log = Log.instance(context);
         source = Source.instance(context);
         diags = JCDiagnostic.Factory.instance(context);
diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
index 683e57f..192780a 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
@@ -221,17 +221,19 @@
     bad intersection type target for lambda or method reference\n\
     {0}
 
-# 0: type
+# 0: symbol or type
 compiler.misc.not.an.intf.component=\
     component type {0} is not an interface
 
 # 0: symbol kind, 1: message segment
 compiler.err.invalid.mref=\
-    invalid {0} reference; {1}
+    invalid {0} reference\n\
+    {1}
 
 # 0: symbol kind, 1: message segment
 compiler.misc.invalid.mref=\
-    invalid {0} reference; {1}
+    invalid {0} reference\n\
+    {1}
 
 compiler.misc.static.mref.with.targs=\
     parameterized qualifier on static method reference
@@ -331,29 +333,29 @@
 
 # 0: type, 1: type
 compiler.err.duplicate.annotation.missing.container=\
-    duplicate annotation, the declaration of {0} does not have a valid {1} annotation
+    duplicate annotation: the declaration of {0} does not have a valid {1} annotation
 
 # 0: type
 compiler.err.invalid.repeatable.annotation=\
-    duplicate annotation, {0} is annotated with an invalid Repeatable annotation
+    duplicate annotation: {0} is annotated with an invalid Repeatable annotation
 
-# 0: type
+# 0: symbol or type
 compiler.err.invalid.repeatable.annotation.no.value=\
-    duplicate annotation, {0} is not a valid Repeatable, no value element method declared
+    duplicate annotation: {0} is not a valid Repeatable, no value element method declared
 
 # 0: type, 1: number
 compiler.err.invalid.repeatable.annotation.multiple.values=\
-    duplicate annotation, {0} is not a valid Repeatable, {1} value element methods declared
+    duplicate annotation: {0} is not a valid Repeatable, {1} value element methods declared
 
 # 0: type
 compiler.err.invalid.repeatable.annotation.invalid.value=\
-    duplicate annotation, {0} is not a valid Repeatable, invalid value element, need a method
+    duplicate annotation: {0} is not a valid Repeatable: invalid value element
 
-# 0: type, 1: type, 2: type
+# 0: symbol type, 1: type, 2: type
 compiler.err.invalid.repeatable.annotation.value.return=\
-    duplicate annotation, value element of containing annotation {0} should have type {2}, found {1}
+    duplicate annotation: value element of containing annotation {0} should have type {2}, found {1}
 
-# 0: type, 1: symbol
+# 0: symbol or type, 1: symbol
 compiler.err.invalid.repeatable.annotation.elem.nondefault=\
     containing annotation {0} does not have a default value for element {1}
 
@@ -592,6 +594,12 @@
 compiler.err.varargs.and.old.array.syntax=\
     legacy array notation not allowed on variable-arity parameter
 
+compiler.err.varargs.and.receiver =\
+    varargs notation not allowed on receiver parameter
+
+compiler.err.array.and.receiver =\
+    legacy array notation not allowed on receiver parameter
+
 compiler.err.variable.not.allowed=\
     variable declaration not allowed here
 
@@ -659,6 +667,7 @@
 compiler.err.missing.ret.stmt=\
     missing return statement
 
+# 0: unused
 compiler.misc.missing.ret.val=\
     missing return value
 
@@ -707,7 +716,8 @@
 
 # 0: message segment
 compiler.misc.incompatible.type.in.conditional=\
-    bad type in conditional expression; {0}
+    bad type in conditional expression\n\
+    {0}
 
 compiler.misc.conditional.target.cant.be.void=\
     target-type for conditional expression cannot be void
@@ -736,7 +746,7 @@
 compiler.misc.incompatible.arg.types.in.mref=\
     incompatible parameter types in method reference
 
-# 0: list of type
+# 0: list of type, 1: message segment
 compiler.misc.bad.arg.types.in.lambda=\
     cannot type-check lambda expression with inferred parameter types\n\
     inferred types: {0}
@@ -983,7 +993,7 @@
 compiler.misc.overridden.default=\
     method {0} is overridden in {1}
 
-# 0: symbol, 1: symbol
+# 0: symbol, 1: type or symbol
 compiler.misc.redundant.supertype=\
     redundant interface {0} is extended by {1}
 
@@ -1147,6 +1157,9 @@
 ## The following string will appear before all messages keyed as:
 ## "compiler.note".
 
+compiler.note.compressed.diags=\
+    Some messages have been simplified; recompile with -Xdiags:verbose to get full output
+
 compiler.note.potential.lambda.found=\
     This anonymous inner class creation can be turned into a lambda expression.
 
@@ -1735,6 +1748,10 @@
 compiler.err.prob.found.req=\
     incompatible types: {0}
 
+# 0: message segment
+compiler.misc.prob.found.req=\
+    incompatible types: {0}
+
 # 0: message segment, 1: type, 2: type
 compiler.warn.prob.found.req=\
     {0}\n\
@@ -1896,11 +1913,10 @@
 
 #####
 
-# 0: type, 1: file name
+# 0: symbol or type, 1: file name
 compiler.warn.auxiliary.class.accessed.from.outside.of.its.source.file=\
     auxiliary class {0} in {1} should not be accessed from outside its own source file
 
-
 ## The first argument ({0}) is a "kindname".
 # 0: symbol kind, 1: symbol, 2: symbol
 compiler.err.abstract.cant.be.accessed.directly=\
@@ -2185,15 +2201,42 @@
 compiler.err.this.as.identifier=\
     as of release 8, ''this'' is allowed as the parameter name for the receiver type only, which has to be the first parameter
 
+# 0: symbol
+compiler.err.receiver.parameter.not.applicable.constructor.toplevel.class=\
+    receiver parameter not applicable for constructor of top-level class
+
 # TODO 308: make a better error message
 compiler.err.cant.annotate.static.class=\
     enclosing static nested class cannot be annotated
+
 # TODO 308: make a better error message
+# 0: unused
 compiler.err.cant.annotate.nested.type=\
     nested type cannot be annotated
 
+# 0: type, 1: type
+compiler.err.incorrect.receiver.name=\
+    the receiver name does not match the enclosing class type\n\
+    required: {0}\n\
+    found: {1}
+
+# 0: type, 1: type
 compiler.err.incorrect.receiver.type=\
-    the receiver type does not match the enclosing class type
+    the receiver type does not match the enclosing class type\n\
+    required: {0}\n\
+    found: {1}
+
+# 0: type, 1: type
+compiler.err.incorrect.constructor.receiver.type=\
+    the receiver type does not match the enclosing outer class type\n\
+    required: {0}\n\
+    found: {1}
+
+# 0: type, 1: type
+compiler.err.incorrect.constructor.receiver.name=\
+    the receiver name does not match the enclosing outer class type\n\
+    required: {0}\n\
+    found: {1}
 
 compiler.err.no.annotations.on.dot.class=\
     no annotations are allowed in the type of a class literal
diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties
index 490a927..caf6746 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties
@@ -168,6 +168,8 @@
     Specify which file to read when both a source file and class file are found for an implicitly compiled class
 javac.opt.AT=\
     Read options and filenames from file
+javac.opt.diags=\
+    Select a diagnostic mode
 
 ## errors
 
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java
index 28e3b88..1ab8051 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java
@@ -42,7 +42,6 @@
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.List;
-import static com.sun.tools.javac.code.BoundKind.*;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 
 /**
@@ -807,12 +806,15 @@
         public JCModifiers mods;
         /** variable name */
         public Name name;
+        /** variable name expression */
+        public JCExpression nameexpr;
         /** type of the variable */
         public JCExpression vartype;
         /** variable's initial value */
         public JCExpression init;
         /** symbol */
         public VarSymbol sym;
+
         protected JCVariableDecl(JCModifiers mods,
                          Name name,
                          JCExpression vartype,
@@ -824,12 +826,27 @@
             this.init = init;
             this.sym = sym;
         }
+
+        protected JCVariableDecl(JCModifiers mods,
+                         JCExpression nameexpr,
+                         JCExpression vartype) {
+            this(mods, null, vartype, null, null);
+            this.nameexpr = nameexpr;
+            if (nameexpr.hasTag(Tag.IDENT)) {
+                this.name = ((JCIdent)nameexpr).name;
+            } else {
+                // Only other option is qualified name x.y.this;
+                this.name = ((JCFieldAccess)nameexpr).name;
+            }
+        }
+
         @Override
         public void accept(Visitor v) { v.visitVarDef(this); }
 
         public Kind getKind() { return Kind.VARIABLE; }
         public JCModifiers getModifiers() { return mods; }
         public Name getName() { return name; }
+        public JCExpression getNameExpression() { return nameexpr; }
         public JCTree getType() { return vartype; }
         public JCExpression getInitializer() {
             return init;
@@ -845,7 +862,7 @@
         }
     }
 
-      /**
+    /**
      * A no-op statement ";".
      */
     public static class JCSkip extends JCStatement implements EmptyStatementTree {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java
index 3e6c149..7a2f933 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java
@@ -261,8 +261,6 @@
     }
 
     public void printTypeAnnotations(List<JCAnnotation> trees) throws IOException {
-        if (trees.nonEmpty())
-            print(" ");
         for (List<JCAnnotation> l = trees; l.nonEmpty(); l = l.tail) {
             printExpr(l.head);
             print(" ");
@@ -564,8 +562,10 @@
                         vartype = ((JCAnnotatedType)vartype).underlyingType;
                     }
                     printExpr(((JCArrayTypeTree) vartype).elemtype);
-                    if (tas != null)
+                    if (tas != null) {
+                        print(' ');
                         printTypeAnnotations(tas);
+                    }
                     print("... " + tree.name);
                 } else {
                     printExpr(tree.vartype);
@@ -918,6 +918,9 @@
                 printExprs(tree.typeargs);
                 print(">");
             }
+            if (tree.def != null && tree.def.mods.annotations.nonEmpty()) {
+                printTypeAnnotations(tree.def.mods.annotations);
+            }
             printExpr(tree.clazz);
             print("(");
             printExprs(tree.args);
@@ -948,7 +951,8 @@
                 int i = 0;
                 List<List<JCAnnotation>> da = tree.dimAnnotations;
                 for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
-                    if (da.size() > i) {
+                    if (da.size() > i && !da.get(i).isEmpty()) {
+                        print(' ');
                         printTypeAnnotations(da.get(i));
                     }
                     print("[");
@@ -958,6 +962,7 @@
                 }
                 if (tree.elems != null) {
                     if (isElemAnnoType) {
+                        print(' ');
                         printTypeAnnotations(((JCAnnotatedType)tree.elemtype).annotations);
                     }
                     print("[]");
@@ -1264,6 +1269,7 @@
                 JCAnnotatedType atype = (JCAnnotatedType) elem;
                 elem = atype.underlyingType;
                 if (!elem.hasTag(TYPEARRAY)) break;
+                print(' ');
                 printTypeAnnotations(atype.annotations);
             }
             print("[]");
@@ -1301,6 +1307,9 @@
 
     public void visitTypeParameter(JCTypeParameter tree) {
         try {
+            if (tree.annotations.nonEmpty()) {
+                this.printTypeAnnotations(tree.annotations);
+            }
             print(tree.name);
             if (tree.bounds.nonEmpty()) {
                 print(" extends ");
@@ -1379,6 +1388,7 @@
             } else if (tree.underlyingType.getKind() == JCTree.Kind.ARRAY_TYPE) {
                 JCArrayTypeTree array = (JCArrayTypeTree) tree.underlyingType;
                 printBaseElementType(tree);
+                print(' ');
                 printTypeAnnotations(tree.annotations);
                 print("[]");
                 JCExpression elem = array.elemtype;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java
index 49f988d..a06fa34 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java
@@ -422,8 +422,13 @@
         JCVariableDecl t = (JCVariableDecl) node;
         JCModifiers mods = copy(t.mods, p);
         JCExpression vartype = copy(t.vartype, p);
-        JCExpression init = copy(t.init, p);
-        return M.at(t.pos).VarDef(mods, t.name, vartype, init);
+        if (t.nameexpr == null) {
+            JCExpression init = copy(t.init, p);
+            return M.at(t.pos).VarDef(mods, t.name, vartype, init);
+        } else {
+            JCExpression nameexpr = copy(t.nameexpr, p);
+            return M.at(t.pos).ReceiverVarDef(mods, nameexpr, vartype);
+        }
     }
 
     public JCTree visitWhileLoop(WhileLoopTree node, P p) {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
index d5a5752..f6a4da4 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
@@ -763,14 +763,40 @@
     }
 
     public static Symbol symbolFor(JCTree node) {
+        Symbol sym = symbolForImpl(node);
+
+        return sym != null ? sym.baseSymbol() : null;
+    }
+
+    private static Symbol symbolForImpl(JCTree node) {
         node = skipParens(node);
         switch (node.getTag()) {
+        case TOPLEVEL:
+            return ((JCCompilationUnit) node).packge;
         case CLASSDEF:
             return ((JCClassDecl) node).sym;
         case METHODDEF:
             return ((JCMethodDecl) node).sym;
         case VARDEF:
             return ((JCVariableDecl) node).sym;
+        case IDENT:
+            return ((JCIdent) node).sym;
+        case SELECT:
+            return ((JCFieldAccess) node).sym;
+        case REFERENCE:
+            return ((JCMemberReference) node).sym;
+        case NEWCLASS:
+            return ((JCNewClass) node).constructor;
+        case APPLY:
+            return symbolFor(((JCMethodInvocation) node).meth);
+        case TYPEAPPLY:
+            return symbolFor(((JCTypeApply) node).clazz);
+        case ANNOTATION:
+        case TYPE_ANNOTATION:
+        case TYPEPARAMETER:
+            if (node.type != null)
+                return node.type.tsym;
+            return null;
         default:
             return null;
         }
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java
index cc6405e..c2757c7 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java
@@ -204,6 +204,12 @@
         return tree;
     }
 
+    public JCVariableDecl ReceiverVarDef(JCModifiers mods, JCExpression name, JCExpression vartype) {
+        JCVariableDecl tree = new JCVariableDecl(mods, name, vartype);
+        tree.pos = pos;
+        return tree;
+    }
+
     public JCSkip Skip() {
         JCSkip tree = new JCSkip();
         tree.pos = pos;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java
index 57724d3..626f70a 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java
@@ -94,6 +94,7 @@
     public void visitVarDef(JCVariableDecl tree) {
         scan(tree.mods);
         scan(tree.vartype);
+        scan(tree.nameexpr);
         scan(tree.init);
     }
 
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java
index 42e97de..b290ac8 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java
@@ -148,6 +148,7 @@
 
     public void visitVarDef(JCVariableDecl tree) {
         tree.mods = translate(tree.mods);
+        tree.nameexpr = translate(tree.nameexpr);
         tree.vartype = translate(tree.vartype);
         tree.init = translate(tree.init);
         result = tree;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java b/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java
index b1e7700..f493317 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java
@@ -349,6 +349,7 @@
         SYNTAX,
         RECOVERABLE,
         NON_DEFERRABLE,
+        COMPRESSED
     }
 
     private final DiagnosticType type;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/List.java b/langtools/src/share/classes/com/sun/tools/javac/util/List.java
index 30b00fa..611798d 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/util/List.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/List.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -37,7 +37,7 @@
 /** A class for generic linked lists. Links are supposed to be
  *  immutable, the only exception being the incremental construction of
  *  lists via ListBuffers.  List is the main container class in
- *  GJC. Most data structures and algorthms in GJC use lists rather
+ *  GJC. Most data structures and algorithms in GJC use lists rather
  *  than arrays.
  *
  *  <p>Lists are always trailed by a sentinel element, whose head and tail
@@ -154,11 +154,11 @@
     }
 
     public static <A> List<A> from(Iterable<? extends A> coll) {
-        List<A> xs = nil();
+        ListBuffer<A> xs = ListBuffer.lb();
         for (A a : coll) {
-            xs = new List<A>(a, xs);
+            xs.append(a);
         }
-        return xs;
+        return xs.toList();
     }
 
     /** Construct a list consisting of a given number of identical elements.
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java
index c2f42fe..5ed6d78 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java
@@ -214,6 +214,11 @@
     public Set<String> expectDiagKeys;
 
     /**
+     * Set to true if a compressed diagnostic is reported
+     */
+    public boolean compressedOutput;
+
+    /**
      * JavacMessages object used for localization.
      */
     private JavacMessages messages;
@@ -597,6 +602,9 @@
                 }
                 break;
             }
+            if (diagnostic.isFlagSet(JCDiagnostic.DiagnosticFlag.COMPRESSED)) {
+                compressedOutput = true;
+            }
         }
     }
 
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/ServiceLoader.java b/langtools/src/share/classes/com/sun/tools/javac/util/ServiceLoader.java
new file mode 100644
index 0000000..f24f1fb
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/ServiceLoader.java
@@ -0,0 +1,437 @@
+/*
+ * Copyright (c) 2005, 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 com.sun.tools.javac.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.ServiceConfigurationError;
+
+
+/**
+ * This is a temporary, modified copy of java.util.ServiceLoader, for use by
+ * javac, to work around bug JDK-8004082.
+ *
+ * The bug describes problems in the interaction between ServiceLoader and
+ * URLClassLoader, such that references to a jar file passed to URLClassLoader
+ * may be retained after calling URLClassLoader.close(), preventing the jar
+ * file from being deleted on Windows.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+
+public final class ServiceLoader<S>
+    implements Iterable<S>
+{
+
+    private static final String PREFIX = "META-INF/services/";
+
+    // The class or interface representing the service being loaded
+    private Class<S> service;
+
+    // The class loader used to locate, load, and instantiate providers
+    private ClassLoader loader;
+
+    // Cached providers, in instantiation order
+    private LinkedHashMap<String,S> providers = new LinkedHashMap<>();
+
+    // The current lazy-lookup iterator
+    private LazyIterator lookupIterator;
+
+    /**
+     * Clear this loader's provider cache so that all providers will be
+     * reloaded.
+     *
+     * <p> After invoking this method, subsequent invocations of the {@link
+     * #iterator() iterator} method will lazily look up and instantiate
+     * providers from scratch, just as is done by a newly-created loader.
+     *
+     * <p> This method is intended for use in situations in which new providers
+     * can be installed into a running Java virtual machine.
+     */
+    public void reload() {
+        providers.clear();
+        lookupIterator = new LazyIterator(service, loader);
+    }
+
+    private ServiceLoader(Class<S> svc, ClassLoader cl) {
+        service = Objects.requireNonNull(svc, "Service interface cannot be null");
+        loader = (cl == null) ? ClassLoader.getSystemClassLoader() : cl;
+        reload();
+    }
+
+    private static void fail(Class<?> service, String msg, Throwable cause)
+        throws ServiceConfigurationError
+    {
+        throw new ServiceConfigurationError(service.getName() + ": " + msg,
+                                            cause);
+    }
+
+    private static void fail(Class<?> service, String msg)
+        throws ServiceConfigurationError
+    {
+        throw new ServiceConfigurationError(service.getName() + ": " + msg);
+    }
+
+    private static void fail(Class<?> service, URL u, int line, String msg)
+        throws ServiceConfigurationError
+    {
+        fail(service, u + ":" + line + ": " + msg);
+    }
+
+    // Parse a single line from the given configuration file, adding the name
+    // on the line to the names list.
+    //
+    private int parseLine(Class<?> service, URL u, BufferedReader r, int lc,
+                          List<String> names)
+        throws IOException, ServiceConfigurationError
+    {
+        String ln = r.readLine();
+        if (ln == null) {
+            return -1;
+        }
+        int ci = ln.indexOf('#');
+        if (ci >= 0) ln = ln.substring(0, ci);
+        ln = ln.trim();
+        int n = ln.length();
+        if (n != 0) {
+            if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0))
+                fail(service, u, lc, "Illegal configuration-file syntax");
+            int cp = ln.codePointAt(0);
+            if (!Character.isJavaIdentifierStart(cp))
+                fail(service, u, lc, "Illegal provider-class name: " + ln);
+            for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
+                cp = ln.codePointAt(i);
+                if (!Character.isJavaIdentifierPart(cp) && (cp != '.'))
+                    fail(service, u, lc, "Illegal provider-class name: " + ln);
+            }
+            if (!providers.containsKey(ln) && !names.contains(ln))
+                names.add(ln);
+        }
+        return lc + 1;
+    }
+
+    // Parse the content of the given URL as a provider-configuration file.
+    //
+    // @param  service
+    //         The service type for which providers are being sought;
+    //         used to construct error detail strings
+    //
+    // @param  u
+    //         The URL naming the configuration file to be parsed
+    //
+    // @return A (possibly empty) iterator that will yield the provider-class
+    //         names in the given configuration file that are not yet members
+    //         of the returned set
+    //
+    // @throws ServiceConfigurationError
+    //         If an I/O error occurs while reading from the given URL, or
+    //         if a configuration-file format error is detected
+    //
+    private Iterator<String> parse(Class<?> service, URL u)
+        throws ServiceConfigurationError
+    {
+        InputStream in = null;
+        BufferedReader r = null;
+        ArrayList<String> names = new ArrayList<>();
+        try {
+            // The problem is that by default, streams opened with
+            // u.openInputStream use a cached reference to a JarFile, which
+            // is separate from the reference used by URLClassLoader, and
+            // which is not closed by URLClassLoader.close().
+            // The workaround is to disable caching for this specific jar file,
+            // so that the reference to the jar file can be closed when the
+            // file has been read.
+            // Original code:
+            // in = u.openStream();
+            // Workaround ...
+            URLConnection uc = u.openConnection();
+            uc.setUseCaches(false);
+            in = uc.getInputStream();
+            // ... end of workaround.
+            r = new BufferedReader(new InputStreamReader(in, "utf-8"));
+            int lc = 1;
+            while ((lc = parseLine(service, u, r, lc, names)) >= 0);
+        } catch (IOException x) {
+            fail(service, "Error reading configuration file", x);
+        } finally {
+            try {
+                if (r != null) r.close();
+                if (in != null) in.close();
+            } catch (IOException y) {
+                fail(service, "Error closing configuration file", y);
+            }
+        }
+        return names.iterator();
+    }
+
+    // Private inner class implementing fully-lazy provider lookup
+    //
+    private class LazyIterator
+        implements Iterator<S>
+    {
+
+        Class<S> service;
+        ClassLoader loader;
+        Enumeration<URL> configs = null;
+        Iterator<String> pending = null;
+        String nextName = null;
+
+        private LazyIterator(Class<S> service, ClassLoader loader) {
+            this.service = service;
+            this.loader = loader;
+        }
+
+        public boolean hasNext() {
+            if (nextName != null) {
+                return true;
+            }
+            if (configs == null) {
+                try {
+                    String fullName = PREFIX + service.getName();
+                    if (loader == null)
+                        configs = ClassLoader.getSystemResources(fullName);
+                    else
+                        configs = loader.getResources(fullName);
+                } catch (IOException x) {
+                    fail(service, "Error locating configuration files", x);
+                }
+            }
+            while ((pending == null) || !pending.hasNext()) {
+                if (!configs.hasMoreElements()) {
+                    return false;
+                }
+                pending = parse(service, configs.nextElement());
+            }
+            nextName = pending.next();
+            return true;
+        }
+
+        public S next() {
+            if (!hasNext()) {
+                throw new NoSuchElementException();
+            }
+            String cn = nextName;
+            nextName = null;
+            Class<?> c = null;
+            try {
+                c = Class.forName(cn, false, loader);
+            } catch (ClassNotFoundException x) {
+                fail(service,
+                     "Provider " + cn + " not found");
+            }
+            if (!service.isAssignableFrom(c)) {
+                fail(service,
+                     "Provider " + cn  + " not a subtype");
+            }
+            try {
+                S p = service.cast(c.newInstance());
+                providers.put(cn, p);
+                return p;
+            } catch (Throwable x) {
+                fail(service,
+                     "Provider " + cn + " could not be instantiated: " + x,
+                     x);
+            }
+            throw new Error();          // This cannot happen
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+    }
+
+    /**
+     * Lazily loads the available providers of this loader's service.
+     *
+     * <p> The iterator returned by this method first yields all of the
+     * elements of the provider cache, in instantiation order.  It then lazily
+     * loads and instantiates any remaining providers, adding each one to the
+     * cache in turn.
+     *
+     * <p> To achieve laziness the actual work of parsing the available
+     * provider-configuration files and instantiating providers must be done by
+     * the iterator itself.  Its {@link java.util.Iterator#hasNext hasNext} and
+     * {@link java.util.Iterator#next next} methods can therefore throw a
+     * {@link ServiceConfigurationError} if a provider-configuration file
+     * violates the specified format, or if it names a provider class that
+     * cannot be found and instantiated, or if the result of instantiating the
+     * class is not assignable to the service type, or if any other kind of
+     * exception or error is thrown as the next provider is located and
+     * instantiated.  To write robust code it is only necessary to catch {@link
+     * ServiceConfigurationError} when using a service iterator.
+     *
+     * <p> If such an error is thrown then subsequent invocations of the
+     * iterator will make a best effort to locate and instantiate the next
+     * available provider, but in general such recovery cannot be guaranteed.
+     *
+     * <blockquote style="font-size: smaller; line-height: 1.2"><span
+     * style="padding-right: 1em; font-weight: bold">Design Note</span>
+     * Throwing an error in these cases may seem extreme.  The rationale for
+     * this behavior is that a malformed provider-configuration file, like a
+     * malformed class file, indicates a serious problem with the way the Java
+     * virtual machine is configured or is being used.  As such it is
+     * preferable to throw an error rather than try to recover or, even worse,
+     * fail silently.</blockquote>
+     *
+     * <p> The iterator returned by this method does not support removal.
+     * Invoking its {@link java.util.Iterator#remove() remove} method will
+     * cause an {@link UnsupportedOperationException} to be thrown.
+     *
+     * @return  An iterator that lazily loads providers for this loader's
+     *          service
+     */
+    public Iterator<S> iterator() {
+        return new Iterator<S>() {
+
+            Iterator<Map.Entry<String,S>> knownProviders
+                = providers.entrySet().iterator();
+
+            public boolean hasNext() {
+                if (knownProviders.hasNext())
+                    return true;
+                return lookupIterator.hasNext();
+            }
+
+            public S next() {
+                if (knownProviders.hasNext())
+                    return knownProviders.next().getValue();
+                return lookupIterator.next();
+            }
+
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+
+        };
+    }
+
+    /**
+     * Creates a new service loader for the given service type and class
+     * loader.
+     *
+     * @param  service
+     *         The interface or abstract class representing the service
+     *
+     * @param  loader
+     *         The class loader to be used to load provider-configuration files
+     *         and provider classes, or <tt>null</tt> if the system class
+     *         loader (or, failing that, the bootstrap class loader) is to be
+     *         used
+     *
+     * @return A new service loader
+     */
+    public static <S> ServiceLoader<S> load(Class<S> service,
+                                            ClassLoader loader)
+    {
+        return new ServiceLoader<>(service, loader);
+    }
+
+    /**
+     * Creates a new service loader for the given service type, using the
+     * current thread's {@linkplain java.lang.Thread#getContextClassLoader
+     * context class loader}.
+     *
+     * <p> An invocation of this convenience method of the form
+     *
+     * <blockquote><pre>
+     * ServiceLoader.load(<i>service</i>)</pre></blockquote>
+     *
+     * is equivalent to
+     *
+     * <blockquote><pre>
+     * ServiceLoader.load(<i>service</i>,
+     *                    Thread.currentThread().getContextClassLoader())</pre></blockquote>
+     *
+     * @param  service
+     *         The interface or abstract class representing the service
+     *
+     * @return A new service loader
+     */
+    public static <S> ServiceLoader<S> load(Class<S> service) {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        return ServiceLoader.load(service, cl);
+    }
+
+    /**
+     * Creates a new service loader for the given service type, using the
+     * extension class loader.
+     *
+     * <p> This convenience method simply locates the extension class loader,
+     * call it <tt><i>extClassLoader</i></tt>, and then returns
+     *
+     * <blockquote><pre>
+     * ServiceLoader.load(<i>service</i>, <i>extClassLoader</i>)</pre></blockquote>
+     *
+     * <p> If the extension class loader cannot be found then the system class
+     * loader is used; if there is no system class loader then the bootstrap
+     * class loader is used.
+     *
+     * <p> This method is intended for use when only installed providers are
+     * desired.  The resulting service will only find and load providers that
+     * have been installed into the current Java virtual machine; providers on
+     * the application's class path will be ignored.
+     *
+     * @param  service
+     *         The interface or abstract class representing the service
+     *
+     * @return A new service loader
+     */
+    public static <S> ServiceLoader<S> loadInstalled(Class<S> service) {
+        ClassLoader cl = ClassLoader.getSystemClassLoader();
+        ClassLoader prev = null;
+        while (cl != null) {
+            prev = cl;
+            cl = cl.getParent();
+        }
+        return ServiceLoader.load(service, prev);
+    }
+
+    /**
+     * Returns a string describing this service.
+     *
+     * @return  A descriptive string
+     */
+    public String toString() {
+        return "java.util.ServiceLoader[" + service.getName() + "]";
+    }
+
+}
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeDocImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeDocImpl.java
index f4bfd5e..032b5f7 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeDocImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeDocImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,9 +31,7 @@
 import com.sun.tools.javac.code.Kinds;
 import com.sun.tools.javac.code.Scope;
 import com.sun.tools.javac.code.Symbol.*;
-import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.Names;
 
 /**
  * Represents an annotation type.
@@ -92,7 +90,6 @@
      * Elements are always public, so no need to filter them.
      */
     public AnnotationTypeElementDoc[] elements() {
-        Names names = tsym.name.table.names;
         List<AnnotationTypeElementDoc> elements = List.nil();
         for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
             if (e.sym != null && e.sym.kind == Kinds.MTH) {
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeElementDocImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeElementDocImpl.java
index ebd5f80..2305429 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeElementDocImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeElementDocImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,6 @@
 
 import com.sun.source.util.TreePath;
 import com.sun.tools.javac.code.Symbol.*;
-import com.sun.tools.javac.tree.JCTree.*;
 
 /**
  * Represents an element of an annotation type.
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java
index 20ed8fd..b79a19c 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,6 @@
 import com.sun.javadoc.*;
 
 import com.sun.tools.javac.code.Attribute;
-import com.sun.tools.javac.code.Symbol.*;
 
 import static com.sun.tools.javac.code.TypeTag.BOOLEAN;
 
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/Comment.java b/langtools/src/share/classes/com/sun/tools/javadoc/Comment.java
index 59236f3..036ad67 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/Comment.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/Comment.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -25,6 +25,8 @@
 
 package com.sun.tools.javadoc;
 
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import com.sun.javadoc.*;
 import com.sun.tools.javac.util.ListBuffer;
 
@@ -296,6 +298,7 @@
     static Tag[] getInlineTags(DocImpl holder, String inlinetext) {
         ListBuffer<Tag> taglist = new ListBuffer<Tag>();
         int delimend = 0, textstart = 0, len = inlinetext.length();
+        boolean inPre = false;
         DocEnv docenv = holder.env;
 
         if (len == 0) {
@@ -309,6 +312,7 @@
                                            inlinetext.substring(textstart)));
                 break;
             } else {
+                inPre = scanForPre(inlinetext, textstart, linkstart, inPre);
                 int seetextstart = linkstart;
                 for (int i = linkstart; i < inlinetext.length(); i++) {
                     char c = inlinetext.charAt(i);
@@ -319,18 +323,20 @@
                      }
                 }
                 String linkName = inlinetext.substring(linkstart+2, seetextstart);
-                //Move past the white space after the inline tag name.
-                while (Character.isWhitespace(inlinetext.
-                                                  charAt(seetextstart))) {
-                    if (inlinetext.length() <= seetextstart) {
-                        taglist.append(new TagImpl(holder, "Text",
-                                                   inlinetext.substring(textstart, seetextstart)));
-                        docenv.warning(holder,
-                                       "tag.Improper_Use_Of_Link_Tag",
-                                       inlinetext);
-                        return taglist.toArray(new Tag[taglist.length()]);
-                    } else {
-                        seetextstart++;
+                if (!(inPre && (linkName.equals("code") || linkName.equals("literal")))) {
+                    //Move past the white space after the inline tag name.
+                    while (Character.isWhitespace(inlinetext.
+                                                      charAt(seetextstart))) {
+                        if (inlinetext.length() <= seetextstart) {
+                            taglist.append(new TagImpl(holder, "Text",
+                                                       inlinetext.substring(textstart, seetextstart)));
+                            docenv.warning(holder,
+                                           "tag.Improper_Use_Of_Link_Tag",
+                                           inlinetext);
+                            return taglist.toArray(new Tag[taglist.length()]);
+                        } else {
+                            seetextstart++;
+                        }
                     }
                 }
                 taglist.append(new TagImpl(holder, "Text",
@@ -366,6 +372,17 @@
         return taglist.toArray(new Tag[taglist.length()]);
     }
 
+    /** regex for case-insensitive match for {@literal <pre> } and  {@literal </pre> }. */
+    private static final Pattern prePat = Pattern.compile("(?i)<(/?)pre>");
+
+    private static boolean scanForPre(String inlinetext, int start, int end, boolean inPre) {
+        Matcher m = prePat.matcher(inlinetext).region(start, end);
+        while (m.find()) {
+            inPre = m.group(1).isEmpty();
+        }
+        return inPre;
+    }
+
     /**
      * Recursively find the index of the closing '}' character for an inline tag
      * and return it.  If it can't be found, return -1.
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java
index f86047e..820e72d 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java
@@ -28,14 +28,10 @@
 import java.lang.reflect.Modifier;
 import java.text.CollationKey;
 
-import javax.lang.model.type.TypeKind;
-
 import com.sun.javadoc.*;
 
 import com.sun.source.util.TreePath;
-import com.sun.tools.javac.code.Attribute;
 import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.code.Attribute.Compound;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Type;
 import com.sun.tools.javac.util.List;
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/FieldDocImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/FieldDocImpl.java
index 1cec66e..8317128 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/FieldDocImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/FieldDocImpl.java
@@ -34,10 +34,6 @@
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symbol.VarSymbol;
 
-import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
-
-import com.sun.tools.javac.util.Position;
-
 import static com.sun.tools.javac.code.TypeTag.BOOLEAN;
 
 /**
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java
index 3a85a53..cc0f212 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -25,10 +25,8 @@
 
 package com.sun.tools.javadoc;
 
-
 import javax.tools.JavaFileObject;
 
-import com.sun.source.util.TreePath;
 import com.sun.tools.javac.code.Kinds;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.comp.Enter;
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/Messager.java b/langtools/src/share/classes/com/sun/tools/javadoc/Messager.java
index 77afe0a..8de85bf 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/Messager.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/Messager.java
@@ -26,9 +26,7 @@
 package com.sun.tools.javadoc;
 
 import java.io.PrintWriter;
-import java.text.MessageFormat;
 import java.util.Locale;
-import java.util.ResourceBundle;
 
 import com.sun.javadoc.*;
 import com.sun.tools.javac.util.Context;
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java b/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java
index bf76f83..721d33b 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java
@@ -25,8 +25,6 @@
 
 package com.sun.tools.javadoc;
 
-import javax.lang.model.type.TypeKind;
-
 import com.sun.javadoc.*;
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
@@ -64,12 +62,9 @@
         if (env.legacyDoclet) {
             t = env.types.erasure(t);
         }
-        if (considerAnnotations
-                && t.isAnnotated()) {
-            return new AnnotatedTypeImpl(env, (com.sun.tools.javac.code.Type.AnnotatedType) t);
-        }
 
-        if (t.isAnnotated()) {
+        if (considerAnnotations &&
+                t.isAnnotated()) {
             Type.AnnotatedType at = (Type.AnnotatedType) t;
             return new AnnotatedTypeImpl(env, at);
         }
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java
index b6f540f..3840c91 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java
@@ -25,8 +25,6 @@
 
 package com.sun.tools.javadoc;
 
-import javax.lang.model.type.TypeKind;
-
 import com.sun.javadoc.*;
 
 import com.sun.tools.javac.code.Attribute;
diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/server/CompilerThread.java b/langtools/src/share/classes/com/sun/tools/sjavac/server/CompilerThread.java
index 0a7a76f..aa9b3ba 100644
--- a/langtools/src/share/classes/com/sun/tools/sjavac/server/CompilerThread.java
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/CompilerThread.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -255,7 +255,8 @@
             }
             // Load visible sources
             Set<URI> visibleSources = new HashSet<URI>();
-            boolean fix_drive_letter_case = System.getProperty("os.name").toLowerCase().equals("windows");
+            boolean fix_drive_letter_case =
+                System.getProperty("os.name").toLowerCase().startsWith("windows");
             for (;;) {
                 String l = in.readLine();
                 if (l == null)
diff --git a/langtools/src/share/classes/javax/annotation/processing/SupportedAnnotationTypes.java b/langtools/src/share/classes/javax/annotation/processing/SupportedAnnotationTypes.java
index 8afc71f..fe3ee8d 100644
--- a/langtools/src/share/classes/javax/annotation/processing/SupportedAnnotationTypes.java
+++ b/langtools/src/share/classes/javax/annotation/processing/SupportedAnnotationTypes.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -47,5 +47,9 @@
 @Target(TYPE)
 @Retention(RUNTIME)
 public @interface SupportedAnnotationTypes {
-  String [] value();
+    /**
+     * Returns the names of the supported annotation types.
+     * @return the names of the supported annotation types
+     */
+    String [] value();
 }
diff --git a/langtools/src/share/classes/javax/annotation/processing/SupportedOptions.java b/langtools/src/share/classes/javax/annotation/processing/SupportedOptions.java
index 5d6017d..3a9dd29 100644
--- a/langtools/src/share/classes/javax/annotation/processing/SupportedOptions.java
+++ b/langtools/src/share/classes/javax/annotation/processing/SupportedOptions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -46,5 +46,9 @@
 @Target(TYPE)
 @Retention(RUNTIME)
 public @interface SupportedOptions {
-  String [] value();
+    /**
+     * Returns the supported options.
+     * @return the supported options
+     */
+    String [] value();
 }
diff --git a/langtools/src/share/classes/javax/annotation/processing/SupportedSourceVersion.java b/langtools/src/share/classes/javax/annotation/processing/SupportedSourceVersion.java
index c28a1da..59c861c 100644
--- a/langtools/src/share/classes/javax/annotation/processing/SupportedSourceVersion.java
+++ b/langtools/src/share/classes/javax/annotation/processing/SupportedSourceVersion.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -47,5 +47,9 @@
 @Target(TYPE)
 @Retention(RUNTIME)
 public @interface SupportedSourceVersion {
+    /**
+     * Returns the latest supported source version.
+     * @return the latest supported source version
+     */
     SourceVersion value();
 }
diff --git a/langtools/src/share/classes/javax/lang/model/AnnotatedConstruct.java b/langtools/src/share/classes/javax/lang/model/AnnotatedConstruct.java
index 99bbe35..c96bff4 100644
--- a/langtools/src/share/classes/javax/lang/model/AnnotatedConstruct.java
+++ b/langtools/src/share/classes/javax/lang/model/AnnotatedConstruct.java
@@ -51,7 +51,7 @@
  * <li> for an invocation of {@code getAnnotation(Class<T>)} or
  * {@code getAnnotationMirrors()}, <i>E</i>'s annotations contain <i>A</i>.
  *
- * <li> for an invocation of getAnnotationsByType(Class<T>),
+ * <li> for an invocation of {@code getAnnotationsByType(Class<T>)},
  * <i>E</i>'s annotations either contain <i>A</i> or, if the type of
  * <i>A</i> is repeatable, contain exactly one annotation whose value
  * element contains <i>A</i> and whose type is the containing
diff --git a/langtools/src/share/classes/javax/lang/model/element/NestingKind.java b/langtools/src/share/classes/javax/lang/model/element/NestingKind.java
index 5e89aaf..b618c48 100644
--- a/langtools/src/share/classes/javax/lang/model/element/NestingKind.java
+++ b/langtools/src/share/classes/javax/lang/model/element/NestingKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -82,9 +82,24 @@
  * @since 1.6
  */
 public enum NestingKind {
+    /**
+     * A top-level type, not contained within another type.
+     */
     TOP_LEVEL,
+
+    /**
+     * A type that is a named member of another type.
+     */
     MEMBER,
+
+    /**
+     * A named type declared within a construct other than a type.
+     */
     LOCAL,
+
+    /**
+     * A type without a name.
+     */
     ANONYMOUS;
 
     /**
@@ -92,6 +107,7 @@
      * A <i>nested</i> type element is any that is not top-level.
      * An <i>inner</i> type element is any nested type element that
      * is not {@linkplain Modifier#STATIC static}.
+     * @return whether or not the constant is nested
      */
     public boolean isNested() {
         return this != TOP_LEVEL;
diff --git a/langtools/src/share/classes/javax/lang/model/util/ElementScanner6.java b/langtools/src/share/classes/javax/lang/model/util/ElementScanner6.java
index 809b4dd..e67728d 100644
--- a/langtools/src/share/classes/javax/lang/model/util/ElementScanner6.java
+++ b/langtools/src/share/classes/javax/lang/model/util/ElementScanner6.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -135,6 +135,9 @@
     /**
      * Processes an element by calling {@code e.accept(this, p)};
      * this method may be overridden by subclasses.
+     *
+     * @param e the element to scan
+     * @param p a scanner-specified parameter
      * @return the result of visiting {@code e}.
      */
     public R scan(Element e, P p) {
@@ -143,6 +146,8 @@
 
     /**
      * Convenience method equivalent to {@code v.scan(e, null)}.
+     *
+     * @param e the element to scan
      * @return the result of scanning {@code e}.
      */
     public final R scan(Element e) {
diff --git a/langtools/src/share/classes/javax/lang/model/util/Elements.java b/langtools/src/share/classes/javax/lang/model/util/Elements.java
index 5778bd0..f782294 100644
--- a/langtools/src/share/classes/javax/lang/model/util/Elements.java
+++ b/langtools/src/share/classes/javax/lang/model/util/Elements.java
@@ -247,6 +247,7 @@
      * argument.
      *
      * @param cs the character sequence to return as a name
+     * @return a name with the same sequence of characters as the argument
      */
     Name getName(CharSequence cs);
 
diff --git a/langtools/src/share/classes/javax/lang/model/util/Types.java b/langtools/src/share/classes/javax/lang/model/util/Types.java
index 560e8e5..2e50b50 100644
--- a/langtools/src/share/classes/javax/lang/model/util/Types.java
+++ b/langtools/src/share/classes/javax/lang/model/util/Types.java
@@ -52,6 +52,7 @@
      * Returns {@code null} if the type is not one with a
      * corresponding element.
      *
+     * @param t the type to map to an element
      * @return the element corresponding to the given type
      */
     Element asElement(TypeMirror t);
diff --git a/langtools/src/share/sample/language/model/CoreReflectionFactory.java b/langtools/src/share/sample/language/model/CoreReflectionFactory.java
new file mode 100644
index 0000000..e51cff7
--- /dev/null
+++ b/langtools/src/share/sample/language/model/CoreReflectionFactory.java
@@ -0,0 +1,3771 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.lang.annotation.Annotation;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.element.*;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+import java.lang.reflect.*;
+import java.io.Writer;
+import java.util.*;
+
+import static javax.lang.model.SourceVersion.RELEASE_8;
+import static java.util.Objects.*;
+
+/**
+ * This class provides a proof-of-concept implementation of the {@code
+ * javax.lang.model.*} API backed by core reflection. That is, rather
+ * than having a source file or compile-time class file as the
+ * originator of the information about an element or type, as done
+ * during standard annotation processing, runtime core reflection
+ * objects serve that purpose instead.
+ *
+ * With this kind of implementation, the same logic can be used for
+ * both compile-time and runtime processing of annotations.
+ *
+ * The nested types in this class define a specialization of {@code
+ * javax.lang.model.*} to provide some additional functionality and
+ * type information. The original {@code javax.lang.model.*} API was
+ * designed to accommodate such a specialization by using wildcards in
+ * the return types of methods.
+ *
+ * It would be technically possible for further specializations of the
+ * API implemented in this class to define alternative semantics of
+ * annotation look-up. For example to allow one annotation to have the
+ * effect of macro-expanding into a set of other annotations.
+ *
+ * Some aspects of the implementation are left as "exercises for the
+ * reader" to complete if interested.
+ *
+ * When passed null pointers, the methods defined in this type will
+ * generally throw null pointer exceptions.
+ *
+ * To get started, first compile this file with a command line like:
+ *
+ * <pre>
+ * $JDK/bin/javac -parameters -Xdoclint:all/public -Xlint:all -d $OUTPUT_DIR CoreReflectionFactory.java
+ * </pre>
+ *
+ * and then run the main method of {@code CoreReflectionFactory},
+ * which will print out a representation of {@code
+ * CoreReflectionFactory}. To use the printing logic defined in {@code
+ * javac}, put {@code tools.jar} on the classpath as in:
+ *
+ * <pre>
+ * $JDK/bin/java -cp $OUTPUT_DIR:$JDK_ROOT/lib/tools.jar CoreReflectionFactory
+ * </pre>
+ *
+ * @author Joseph D. Darcy (darcy)
+ * @author Joel Borggren-Franck (jfranck)
+ */
+public class CoreReflectionFactory {
+    private CoreReflectionFactory() {
+        throw new AssertionError("No instances of CoreReflectionFactory for you!");
+    }
+
+    /**
+     * Returns a reflection type element mirroring a {@code Class} object.
+     * @return a reflection type element mirroring a {@code Class} object
+     * @param clazz the {@code Class} to mirror
+     */
+    public static ReflectionTypeElement createMirror(Class<?> clazz) {
+        return new CoreReflTypeElement(Objects.requireNonNull(clazz));
+    }
+
+    /**
+     * Returns a reflection package element mirroring a {@code Package} object.
+     * @return a reflection package element mirroring a {@code Package} object
+     * @param pkg the {@code Package} to mirror
+     */
+    public static ReflectionPackageElement createMirror(Package pkg) {
+        // Treat a null pkg to mean an unnamed package.
+        return new CoreReflPackageElement(pkg);
+    }
+
+    /**
+     * Returns a reflection variable element mirroring a {@code Field} object.
+     * @return a reflection variable element mirroring a {@code Field} object
+     * @param field the {@code Field} to mirror
+     */
+    public static ReflectionVariableElement createMirror(Field field) {
+        return new CoreReflFieldVariableElement(Objects.requireNonNull(field));
+    }
+
+    /**
+     * Returns a reflection executable element mirroring a {@code Method} object.
+     * @return a reflection executable element mirroring a {@code Method} object
+     * @param method the {@code Method} to mirror
+     */
+    public static ReflectionExecutableElement createMirror(Method method)  {
+        return new CoreReflMethodExecutableElement(Objects.requireNonNull(method));
+    }
+
+    /**
+     * Returns a reflection executable element mirroring a {@code Constructor} object.
+     * @return a reflection executable element mirroring a {@code Constructor} object
+     * @param constructor the {@code Constructor} to mirror
+     */
+    public static ReflectionExecutableElement createMirror(Constructor<?> constructor)  {
+        return new CoreReflConstructorExecutableElement(Objects.requireNonNull(constructor));
+    }
+
+    /**
+     * Returns a type parameter element mirroring a {@code TypeVariable} object.
+     * @return a type parameter element mirroring a {@code TypeVariable} object
+     * @param tv the {@code TypeVariable} to mirror
+     */
+    public static TypeParameterElement createMirror(java.lang.reflect.TypeVariable<?> tv) {
+        return new CoreReflTypeParameterElement(Objects.requireNonNull(tv));
+    }
+
+    /**
+     * Returns a variable element mirroring a {@code Parameter} object.
+     * @return a variable element mirroring a {@code Parameter} object
+     * @param p the {Parameter} to mirror
+     */
+    public static VariableElement createMirror(java.lang.reflect.Parameter p) {
+        return new CoreReflParameterVariableElement(Objects.requireNonNull(p));
+    }
+
+    /**
+     * Returns an annotation mirror mirroring an annotation object.
+     * @return an annotation mirror mirroring an annotation object
+     * @param annotation the annotation to mirror
+     */
+    public static AnnotationMirror createMirror(Annotation annotation)  {
+        return new CoreReflAnnotationMirror(Objects.requireNonNull(annotation));
+    }
+
+    /**
+     * Returns a {@code Types} utility object for type objects backed by core reflection.
+     * @return a {@code Types} utility object for type objects backed by core reflection
+     */
+    public static Types getTypes() {
+        return CoreReflTypes.instance();
+    }
+
+    /**
+     * Returns an {@code Elements} utility object for type objects backed by core reflection.
+     * @return an {@code Elements} utility object for type objects backed by core reflection
+     */
+    public static Elements getElements() {
+        return CoreReflElements.instance();
+    }
+
+    // Helper
+    private static TypeMirror createTypeMirror(Class<?> c) {
+        return TypeFactory.instance(Objects.requireNonNull(c));
+    }
+
+    /**
+     * Main method; prints out a representation of this class.
+     * @param args command-line arguments, currently ignored
+     */
+    public static void main(String... args) {
+        getElements().printElements(new java.io.PrintWriter(System.out),
+                                    createMirror(CoreReflectionFactory.class));
+    }
+
+    /**
+     * A specialization of {@code javax.lang.model.element.Element} that is
+     * backed by core reflection.
+     */
+    public static interface ReflectionElement
+        extends Element, AnnotatedElement {
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        ReflectionElement getEnclosingElement();
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        List<ReflectionElement> getEnclosedElements();
+
+        /**
+         * Applies a visitor to this element.
+         *
+         * @param v the visitor operating on this element
+         * @param p additional parameter to the visitor
+         * @param <R> the return type of the visitor's methods
+         * @param <P> the type of the additional parameter to the visitor's methods
+         * @return a visitor-specified result
+         */
+        <R,P> R accept(ReflectionElementVisitor<R,P> v, P p);
+
+        // Functionality specific to the specialization
+        /**
+         * Returns the underlying core reflection source object, if applicable.
+         * @return the underlying core reflection source object, if applicable
+         */
+        AnnotatedElement getSource();
+
+        // Functionality from javax.lang.model.util.Elements
+        /**
+         * Returns the package of an element. The package of a package
+         * is itself.
+         * @return the package of an element
+         */
+        ReflectionPackageElement getPackage();
+
+    }
+
+    /**
+     * A logical specialization of {@code
+     * javax.lang.model.element.ElementVisitor} being backed by core
+     * reflection.
+     *
+     * @param <R> the return type of this visitor's methods.
+     * @param <P> the type of the additional parameter to this visitor's
+     *            methods.
+     */
+    public static interface ReflectionElementVisitor<R, P> {
+        /**
+         * Visits an element.
+         * @param e  the element to visit
+         * @param p  a visitor-specified parameter
+         * @return a visitor-specified result
+         */
+        R visit(ReflectionElement e, P p);
+
+        /**
+         * A convenience method equivalent to {@code v.visit(e, null)}.
+         * @param e  the element to visit
+         * @return a visitor-specified result
+         */
+        R visit(ReflectionElement e);
+
+        /**
+         * Visits a package element.
+         * @param e  the element to visit
+         * @param p  a visitor-specified parameter
+         * @return a visitor-specified result
+         */
+        R visitPackage(ReflectionPackageElement e, P p);
+
+        /**
+         * Visits a type element.
+         * @param e  the element to visit
+         * @param p  a visitor-specified parameter
+         * @return a visitor-specified result
+         */
+        R visitType(ReflectionTypeElement e, P p);
+
+        /**
+         * Visits a variable element.
+         * @param e  the element to visit
+         * @param p  a visitor-specified parameter
+         * @return a visitor-specified result
+         */
+        R visitVariable(ReflectionVariableElement e, P p);
+
+        /**
+         * Visits an executable element.
+         * @param e  the element to visit
+         * @param p  a visitor-specified parameter
+         * @return a visitor-specified result
+         */
+        R visitExecutable(ReflectionExecutableElement e, P p);
+
+        /**
+         * Visits a type parameter element.
+         * @param e  the element to visit
+         * @param p  a visitor-specified parameter
+         * @return a visitor-specified result
+         */
+        R visitTypeParameter(ReflectionTypeParameterElement e, P p);
+
+        /**
+         * Visits an unknown kind of element.
+         * This can occur if the language evolves and new kinds
+         * of elements are added to the {@code Element} hierarchy.
+         *
+         * @param e  the element to visit
+         * @param p  a visitor-specified parameter
+         * @return a visitor-specified result
+         * @throws UnknownElementException
+         * a visitor implementation may optionally throw this exception
+         */
+        R visitUnknown(ReflectionElement e, P p);
+    }
+
+    /**
+     * A specialization of {@code javax.lang.model.element.ExecutableElement} that is
+     * backed by core reflection.
+     */
+    public static interface ReflectionExecutableElement
+        extends ReflectionElement, ExecutableElement, ReflectionParameterizable {
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        List<ReflectionTypeParameterElement> getTypeParameters();
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        List<ReflectionVariableElement> getParameters();
+
+        // Functionality specific to the specialization
+        /**
+         * Returns all parameters, including synthetic ones.
+         * @return all parameters, including synthetic ones
+         */
+        List<ReflectionVariableElement> getAllParameters();
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        Executable getSource();
+
+        /**
+         * Returns true if this executable is a synthetic construct; returns false otherwise.
+         * @return true if this executable is a synthetic construct; returns false otherwise
+         */
+        boolean isSynthetic();
+
+        /**
+         * Returns true if this executable is a bridge method; returns false otherwise.
+         * @return true if this executable is a bridge method; returns false otherwise
+         */
+        boolean isBridge();
+    }
+
+    /**
+     * A specialization of {@code javax.lang.model.element.PackageElement} being
+     * backed by core reflection.
+     */
+    public static interface ReflectionPackageElement
+        extends ReflectionElement, PackageElement {
+
+        // Functionality specific to the specialization
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        Package getSource();
+    }
+
+    /**
+     * A specialization of {@code javax.lang.model.element.TypeElement} that is
+     * backed by core reflection.
+     */
+    public static interface ReflectionTypeElement
+        extends ReflectionElement, TypeElement, ReflectionParameterizable {
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        List<ReflectionTypeParameterElement> getTypeParameters();
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        List<ReflectionElement> getEnclosedElements();
+
+        // Methods specific to the specialization, but functionality
+        // also present in javax.lang.model.util.Elements.
+        /**
+         * Returns all members of a type element, whether inherited or
+         * declared directly. For a class the result also includes its
+         * constructors, but not local or anonymous classes.
+         * @return all members of the type
+         */
+        List<ReflectionElement> getAllMembers();
+
+        /**
+         * Returns the binary name of a type element.
+         * @return the binary name of a type element
+         */
+        Name getBinaryName();
+
+        // Functionality specific to the specialization
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        Class<?> getSource();
+    }
+
+    /**
+     * A specialization of {@code javax.lang.model.element.TypeParameterElement} being
+     * backed by core reflection.
+     */
+    public static interface ReflectionTypeParameterElement
+        extends ReflectionElement, TypeParameterElement {
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        ReflectionElement getGenericElement();
+
+        // Functionality specific to the specialization
+
+        // Conceptually should have an override for getSource
+        // returning GenericDeclaration, but GenericDeclaration
+        // doesn't currently implement AnnotatedElement.
+//         /**
+//          * {@inheritDoc}
+//          */
+//         @Override
+//         java.lang.reflect.GenericDeclaration getSource();
+    }
+
+    /**
+     * A specialization of {@code javax.lang.model.element.VariableElement} that is
+     * backed by core reflection.
+     */
+    public static interface ReflectionVariableElement
+        extends ReflectionElement, VariableElement {
+
+        // Functionality specific to the specialization
+        /**
+         * Returns true if this variable is a synthetic construct; returns false otherwise.
+         * @return true if this variable is a synthetic construct; returns false otherwise
+         */
+        boolean isSynthetic();
+
+        /**
+         * Returns true if this variable is implicitly declared in source code; returns false otherwise.
+         * @return true if this variable is implicitly declared in source code; returns false otherwise
+         */
+        boolean isImplicit();
+
+        // The VariableElement concept covers fields, variables, and
+        // method and constructor parameters. Therefore, this
+        // interface cannot define a more precise override of
+        // getSource since those three concept have different core
+        // reflection types with no supertype more precise than
+        // AnnotatedElement.
+    }
+
+    /**
+     * A specialization of {@code javax.lang.model.element.Parameterizable} being
+     * backed by core reflection.
+     */
+    public static interface ReflectionParameterizable
+        extends ReflectionElement, Parameterizable {
+        @Override
+        List<ReflectionTypeParameterElement> getTypeParameters();
+    }
+
+    /**
+     * Base class for concrete visitors of elements backed by core reflection.
+     */
+    public static abstract class AbstractReflectionElementVisitor8<R, P>
+        extends AbstractElementVisitor8<R, P>
+        implements ReflectionElementVisitor<R, P> {
+        protected AbstractReflectionElementVisitor8() {
+            super();
+        }
+    }
+
+    /**
+     * Base class for simple visitors of elements that are backed by core reflection.
+     */
+    @SupportedSourceVersion(value=RELEASE_8)
+    public static abstract class SimpleReflectionElementVisitor8<R, P>
+        extends SimpleElementVisitor8<R, P>
+        implements ReflectionElementVisitor<R, P> {
+
+        protected SimpleReflectionElementVisitor8(){
+            super();
+        }
+
+        protected SimpleReflectionElementVisitor8(R defaultValue) {
+            super(defaultValue);
+        }
+
+        // Create manual "bridge methods" for now.
+
+        @Override
+        public final R visitPackage(PackageElement e, P p) {
+            return visitPackage((ReflectionPackageElement) e , p);
+        }
+
+        @Override
+        public final R visitType(TypeElement e, P p) {
+            return visitType((ReflectionTypeElement) e , p);
+        }
+
+        @Override
+        public final R visitVariable(VariableElement e, P p) {
+            return visitVariable((ReflectionVariableElement) e , p);
+        }
+
+        @Override
+        public final R visitExecutable(ExecutableElement e, P p) {
+            return visitExecutable((ReflectionExecutableElement) e , p);
+        }
+
+        @Override
+        public final R visitTypeParameter(TypeParameterElement e, P p) {
+            return visitTypeParameter((ReflectionTypeParameterElement) e , p);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public static interface ReflectionElements  extends Elements {
+        /**
+         * Returns the innermost enclosing {@link ReflectionTypeElement}
+         * of the {@link ReflectionElement} or {@code null} if the
+         * supplied ReflectionElement is toplevel or represents a
+         * Package.
+         *
+         * @param e the {@link ReflectionElement} whose innermost
+         * enclosing {@link ReflectionTypeElement} is sought
+         * @return the innermost enclosing {@link
+         * ReflectionTypeElement} or @{code null} if the parameter
+         * {@code e} is a toplevel element or a package
+         */
+        ReflectionTypeElement getEnclosingTypeElement(ReflectionElement e);
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        List<? extends ReflectionElement> getAllMembers(TypeElement type);
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        ReflectionPackageElement getPackageElement(CharSequence name);
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        ReflectionPackageElement getPackageOf(Element type);
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        ReflectionTypeElement getTypeElement(CharSequence name);
+    }
+
+    // ------------------------- Implementation classes ------------------------
+
+    // Exercise for the reader: review the CoreReflElement class
+    // hierarchy below with an eye toward exposing it as an extensible
+    // API that could be subclassed to provide customized behavior,
+    // such as alternate annotation lookup semantics.
+
+    private static abstract class CoreReflElement
+        implements ReflectionElement, AnnotatedElement {
+        public abstract AnnotatedElement getSource();
+
+        protected CoreReflElement() {
+            super();
+        }
+
+        // ReflectionElement methods
+        @Override
+        public ReflectionPackageElement getPackage() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public TypeMirror asType() {
+            throw new UnsupportedOperationException(getClass().toString());
+        }
+
+        @Override
+        public List<? extends AnnotationMirror> getAnnotationMirrors() {
+            Annotation[] annotations = getSource().getDeclaredAnnotations();
+            int len = annotations.length;
+
+            if (len > 0) {
+                List<AnnotationMirror> res = new ArrayList<>(len);
+                for (Annotation a : annotations) {
+                    res.add(createMirror(a));
+                }
+                return Collections.unmodifiableList(res);
+            } else {
+                return Collections.emptyList();
+            }
+        }
+
+        @Override
+        public Set<Modifier> getModifiers() {
+            return ModifierUtil.instance(0, false);
+        }
+
+        @Override
+        public abstract Name getSimpleName();
+
+        @Override
+        public abstract ReflectionElement getEnclosingElement();
+
+        @Override
+        public abstract List<ReflectionElement> getEnclosedElements();
+
+        //AnnotatedElement methods
+        @Override
+        public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+            return getSource().getAnnotation(annotationClass);
+        }
+
+        @Override
+        public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
+            return getSource().getAnnotationsByType(annotationClass);
+        }
+
+        @Override
+        public Annotation[] getAnnotations() {
+            return getSource().getAnnotations();
+        }
+
+        @Override
+        public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
+            return getSource().getDeclaredAnnotation(annotationClass);
+        }
+
+        @Override
+        public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
+            return getSource().getDeclaredAnnotationsByType(annotationClass);
+        }
+
+        @Override
+        public Annotation[] getDeclaredAnnotations() {
+            return getSource().getDeclaredAnnotations();
+        }
+
+        // java.lang.Object methods
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof CoreReflElement) {
+                CoreReflElement other = (CoreReflElement)obj;
+                return Objects.equals(other.getSource(), this.getSource());
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hashCode(getSource());
+        }
+
+        @Override
+        public String toString() {
+            return getKind().toString() + " " + getSimpleName().toString();
+        }
+    }
+
+    // Type
+    private static class CoreReflTypeElement extends CoreReflElement
+        implements ReflectionTypeElement {
+        private final Class<?> source;
+
+        protected CoreReflTypeElement(Class<?> source) {
+            Objects.requireNonNull(source);
+            if (source.isPrimitive() ||
+                source.isArray()) {
+                throw new IllegalArgumentException("Cannot create a ReflectionTypeElement based on class: " + source);
+            }
+
+            this.source = source;
+        }
+
+        @Override
+        public TypeMirror asType() {
+            return createTypeMirror(source);
+        }
+
+        @Override
+        public Class<?> getSource() {
+            return source;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof CoreReflTypeElement) {
+                return source.equals(((CoreReflTypeElement)o).getSource());
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public <R,P> R accept(ElementVisitor<R,P> v, P p) {
+            return v.visitType(this, p);
+        }
+
+        @Override
+        public <R,P> R accept(ReflectionElementVisitor<R,P> v, P p) {
+            return v.visitType(this, p);
+        }
+
+        @Override
+        public Set<Modifier> getModifiers() {
+            return ModifierUtil.instance(source.getModifiers() &
+                                         (source.isInterface() ?
+                                          java.lang.reflect.Modifier.interfaceModifiers() :
+                                          java.lang.reflect.Modifier.classModifiers()),
+                                         false);
+        }
+
+        @Override
+        public List<ReflectionElement> getEnclosedElements() {
+            List<ReflectionElement> enclosedElements = new ArrayList<>();
+
+            for (Class<?> declaredClass : source.getDeclaredClasses()) {
+                enclosedElements.add(createMirror(declaredClass));
+            }
+
+            // Add elements in the conventional ordering: fields, then
+            // constructors, then methods.
+            for (Field f : source.getDeclaredFields()) {
+                enclosedElements.add(createMirror(f));
+            }
+
+            for (Constructor<?> c : source.getDeclaredConstructors()) {
+                enclosedElements.add(createMirror(c));
+            }
+
+            for (Method m : source.getDeclaredMethods()) {
+                enclosedElements.add(createMirror(m));
+            }
+
+            return (enclosedElements.isEmpty() ?
+                    Collections.emptyList():
+                    Collections.unmodifiableList(enclosedElements));
+        }
+
+        // Review for default method handling.
+        @Override
+        public List<ReflectionElement> getAllMembers() {
+            List<ReflectionElement> allMembers = new ArrayList<>();
+
+            // If I only had a MultiMap ...
+            List<ReflectionElement> fields = new ArrayList<>();
+            List<ReflectionExecutableElement> methods = new ArrayList<>();
+            List<ReflectionElement> classes = new ArrayList<>();
+
+            // Add all fields for this class
+            for (Field f : source.getDeclaredFields()) {
+                fields.add(createMirror(f));
+            }
+
+            // Add all methods for this class
+            for (Method m : source.getDeclaredMethods()) {
+                methods.add(createMirror(m));
+            }
+
+            // Add all classes for this class, except anonymous/local as per Elements.getAllMembers doc
+            for (Class<?> c : source.getDeclaredClasses()) {
+                if (c.isLocalClass() || c.isAnonymousClass())
+                    continue;
+                classes.add(createMirror(c));
+            }
+
+            Class<?> cls = source;
+            if (cls.isInterface()) {
+                cls = null;
+            }
+            do {
+                // Walk up superclasses adding non-private elements.
+                // If source is an interface, just add Object's
+                // elements.
+
+                if (cls == null) {
+                    cls = java.lang.Object.class;
+                } else {
+                    cls = cls.getSuperclass();
+                }
+
+                addMembers(cls, fields, methods, classes);
+
+            } while (cls != java.lang.Object.class);
+
+            // add members on (super)interface(s)
+            Set<Class<?>> seenInterfaces = new HashSet<>();
+            Queue<Class<?>> interfaces = new LinkedList<>();
+            if (source.isInterface()) {
+                seenInterfaces.add(source);
+                interfaces.add(source);
+            } else {
+                Class<?>[] ifaces = source.getInterfaces();
+                for (Class<?> iface : ifaces) {
+                    seenInterfaces.add(iface);
+                    interfaces.add(iface);
+                }
+            }
+
+            while (interfaces.peek() != null) {
+                Class<?> head = interfaces.remove();
+                addMembers(head, fields, methods, classes);
+
+                Class<?>[] ifaces = head.getInterfaces();
+                for (Class<?> iface : ifaces) {
+                    if (!seenInterfaces.contains(iface)) {
+                        seenInterfaces.add(iface);
+                        interfaces.add(iface);
+                    }
+                }
+            }
+
+            // Add constructors
+            for (Constructor<?> c : source.getDeclaredConstructors()) {
+                allMembers.add(createMirror(c));
+            }
+
+            // Add all unique methods
+            allMembers.addAll(methods);
+
+            // Add all unique fields
+            allMembers.addAll(fields);
+
+            // Add all unique classes
+            allMembers.addAll(classes);
+
+            return Collections.unmodifiableList(allMembers);
+        }
+
+        private void addMembers(Class<?> cls,
+                                List<ReflectionElement> fields,
+                                List<ReflectionExecutableElement> methods,
+                                List<ReflectionElement> classes) {
+            Elements elements = getElements();
+
+            for (Field f : cls.getDeclaredFields()) {
+                if (java.lang.reflect.Modifier.isPrivate(f.getModifiers())) { continue; }
+                ReflectionElement tmp = createMirror(f);
+                boolean add = true;
+                for (ReflectionElement e : fields) {
+                    if (elements.hides(e, tmp)) {
+                        add = false;
+                        break;
+                    }
+                }
+                if (add) {
+                    fields.add(tmp);
+                }
+            }
+
+            for (Method m : cls.getDeclaredMethods()) {
+                if (java.lang.reflect.Modifier.isPrivate(m.getModifiers()))
+                    continue;
+
+                ReflectionExecutableElement tmp = createMirror(m);
+                boolean add = true;
+                for (ReflectionExecutableElement e : methods) {
+                    if (elements.hides(e, tmp)) {
+                        add = false;
+                        break;
+                    } else if (elements.overrides(e, tmp, this)) {
+                        add = false;
+                        break;
+                    }
+                }
+                if (add) {
+                    methods.add(tmp);
+                }
+            }
+
+            for (Class<?> c : cls.getDeclaredClasses()) {
+                if (java.lang.reflect.Modifier.isPrivate(c.getModifiers()) ||
+                    c.isLocalClass() ||
+                    c.isAnonymousClass())
+                    continue;
+
+                ReflectionElement tmp = createMirror(c);
+                boolean add = true;
+                for (ReflectionElement e : classes) {
+                    if (elements.hides(e, tmp)) {
+                        add = false;
+                        break;
+                    }
+                }
+                if (add) {
+                    classes.add(tmp);
+                }
+            }
+        }
+
+        @Override
+        public ElementKind getKind() {
+            if (source.isInterface()) {
+                if (source.isAnnotation())
+                    return ElementKind.ANNOTATION_TYPE;
+                else
+                    return ElementKind.INTERFACE;
+            } else if (source.isEnum()) {
+                return ElementKind.ENUM;
+            } else
+                return ElementKind.CLASS;
+        }
+
+        @Override
+        public NestingKind getNestingKind() {
+            if (source.isAnonymousClass())
+                return NestingKind.ANONYMOUS;
+            else if (source.isLocalClass())
+                return NestingKind.LOCAL;
+            else if (source.isMemberClass())
+                return NestingKind.MEMBER;
+            else return
+                NestingKind.TOP_LEVEL;
+        }
+
+        @Override
+        public Name getQualifiedName() {
+            String name = source.getCanonicalName(); // TODO, this should be a FQN for
+                                                     // the current element
+            if (name == null)
+                name = "";
+            return StringName.instance(name);
+        }
+
+        @Override
+        public Name getSimpleName() {
+            return StringName.instance(source.getSimpleName());
+        }
+
+        @Override
+        public TypeMirror getSuperclass() {
+            if (source.equals(java.lang.Object.class)) {
+                return NoType.getNoneInstance();
+            } else {
+                return createTypeMirror(source.getSuperclass());
+            }
+        }
+
+        @Override
+        public List<? extends TypeMirror> getInterfaces() {
+            Class[] interfaces = source.getInterfaces();
+            int len = interfaces.length;
+            List<TypeMirror> res = new ArrayList<>(len);
+
+            if (len > 0) {
+                for (Class<?> c : interfaces) {
+                    res.add(createTypeMirror(c));
+                }
+            } else {
+                return Collections.emptyList();
+            }
+            return Collections.unmodifiableList(res);
+        }
+
+        @Override
+        public List<ReflectionTypeParameterElement> getTypeParameters() {
+            return createTypeParameterList(source);
+        }
+
+        @Override
+        public ReflectionElement getEnclosingElement() {
+            // Returns the package of a top-level type and returns the
+            // immediately lexically enclosing element for a nested type.
+
+            switch(getNestingKind()) {
+            case TOP_LEVEL:
+                return createMirror(source.getPackage());
+            case MEMBER:
+                return createMirror(source.getEnclosingClass());
+            default:
+                if (source.getEnclosingConstructor() != null) {
+                    return createMirror(source.getEnclosingConstructor());
+                } else if (source.getEnclosingMethod() != null) {
+                    return createMirror(source.getEnclosingMethod());
+                } else {
+                    return createMirror(source.getEnclosingClass());
+                }
+            }
+        }
+
+        @Override
+        public Name getBinaryName() {
+            return StringName.instance(getSource().getName());
+        }
+    }
+
+    private static abstract class CoreReflExecutableElement extends CoreReflElement
+        implements ReflectionExecutableElement {
+
+        protected Executable source = null;
+        protected final List<CoreReflParameterVariableElement> parameters;
+
+        protected CoreReflExecutableElement(Executable source,
+                                            List<CoreReflParameterVariableElement> parameters) {
+            this.source = Objects.requireNonNull(source);
+            this.parameters = Objects.requireNonNull(parameters);
+        }
+
+        @Override
+        public <R,P> R accept(ElementVisitor<R,P> v, P p) {
+            return v.visitExecutable(this, p);
+        }
+
+        @Override
+        public <R,P> R accept(ReflectionElementVisitor<R,P> v, P p) {
+            return v.visitExecutable(this, p);
+        }
+
+        @Override
+        public abstract ExecutableType asType();
+
+        // Only Types and Packages enclose elements; see Element.getEnclosedElements()
+        @Override
+        public List<ReflectionElement> getEnclosedElements() {
+            return Collections.emptyList();
+        }
+
+        @Override
+        public List<ReflectionVariableElement> getParameters() {
+            List<ReflectionVariableElement> tmp = new ArrayList<>();
+            for (ReflectionVariableElement parameter : parameters) {
+                if (!parameter.isSynthetic())
+                    tmp.add(parameter);
+            }
+            return tmp;
+        }
+
+        @Override
+        public List<ReflectionVariableElement> getAllParameters() {
+            // Could "fix" this if the return type included wildcards
+            @SuppressWarnings("unchecked")
+            List<ReflectionVariableElement> tmp = (List<ReflectionVariableElement>)(List)parameters;
+            return tmp;
+        }
+
+        @Override
+        public List<? extends TypeMirror> getThrownTypes() {
+            Class<?>[] thrown = source.getExceptionTypes();
+            int len = thrown.length;
+            List<TypeMirror> res = new ArrayList<>(len);
+
+            if (len > 0) {
+                for (Class<?> c : thrown) {
+                    res.add(createTypeMirror(c));
+                }
+            } else {
+                return Collections.emptyList();
+            }
+            return Collections.unmodifiableList(res);
+        }
+
+        @Override
+        public boolean isVarArgs() {
+            return source.isVarArgs();
+        }
+
+        @Override
+        public boolean isSynthetic() {
+            return source.isSynthetic();
+        }
+
+        @Override
+        public boolean isBridge() {
+            return false;
+        }
+
+        @Override
+        public List<ReflectionTypeParameterElement> getTypeParameters() {
+            return createTypeParameterList(source);
+        }
+
+        public abstract AnnotationValue getDefaultValue();
+
+        @Override
+        public TypeMirror getReceiverType() {
+            // New in JDK 8
+            throw new UnsupportedOperationException(this.toString());
+        }
+    }
+
+    private static class CoreReflConstructorExecutableElement
+        extends CoreReflExecutableElement {
+
+        protected CoreReflConstructorExecutableElement(Constructor<?> source) {
+            super(Objects.requireNonNull(source),
+                  createParameterList(source));
+        }
+
+        @Override
+        public  Constructor<?> getSource() {
+            return (Constructor<?>)source;
+        }
+
+        @Override
+        public TypeMirror getReturnType() {
+            return NoType.getVoidInstance();
+        }
+
+        @Override
+        public ExecutableType asType() {
+            throw new UnsupportedOperationException(getClass().toString());
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof CoreReflConstructorExecutableElement) {
+                return source.equals(((CoreReflConstructorExecutableElement)o).getSource());
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public ElementKind getKind() {
+            return ElementKind.CONSTRUCTOR;
+        }
+
+        @Override
+        public Set<Modifier> getModifiers() {
+            return ModifierUtil.instance(source.getModifiers() &
+                                         java.lang.reflect.Modifier.constructorModifiers(), false);
+        }
+
+        @Override
+        public ReflectionElement getEnclosingElement() {
+            return createMirror(source.getDeclaringClass());
+        }
+
+        @Override
+        public Name getSimpleName() {
+            return StringName.instance("<init>");
+        }
+
+        @Override
+        public AnnotationValue getDefaultValue() {
+            // a constructor is never an annotation element
+            return null;
+        }
+
+        @Override
+        public boolean isDefault() {
+            return false; // A constructor cannot be a default method
+        }
+    }
+
+    private static class CoreReflMethodExecutableElement
+        extends CoreReflExecutableElement {
+
+        protected CoreReflMethodExecutableElement(Method source) {
+            super(Objects.requireNonNull(source),
+                  createParameterList(source));
+            this.source = source;
+        }
+
+        @Override
+        public Method getSource() {
+            return (Method)source;
+        }
+
+        @Override
+        public TypeMirror getReturnType() {
+            return TypeFactory.instance(getSource().getReturnType());
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof CoreReflMethodExecutableElement) {
+                return source.equals( ((CoreReflMethodExecutableElement)o).getSource());
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public ElementKind getKind() {
+            return ElementKind.METHOD;
+        }
+
+        @Override
+        public Set<Modifier> getModifiers() {
+            return ModifierUtil.instance(source.getModifiers() &
+                                         java.lang.reflect.Modifier.methodModifiers(),
+                                         isDefault());
+        }
+
+        @Override
+        public ReflectionElement getEnclosingElement() {
+            return createMirror(source.getDeclaringClass());
+        }
+
+        @Override
+        public Name getSimpleName() {
+            return StringName.instance(source.getName());
+        }
+
+        @Override
+        public AnnotationValue getDefaultValue() {
+            Object value = getSource().getDefaultValue();
+            if (null == value) {
+                return null;
+            } else {
+                return new CoreReflAnnotationValue(value);
+            }
+        }
+
+        @Override
+        public boolean isDefault() {
+            return getSource().isDefault();
+        }
+
+        @Override
+        public boolean isBridge() {
+            return getSource().isBridge();
+        }
+
+        @Override
+        public ExecutableType asType() {
+            return TypeFactory.instance(getSource());
+        }
+    }
+
+    private static List<CoreReflParameterVariableElement> createParameterList(Executable source) {
+        Parameter[] parameters = source.getParameters();
+        int length = parameters.length;
+        if (length == 0)
+            return Collections.emptyList();
+        else {
+            List<CoreReflParameterVariableElement> tmp = new ArrayList<>(length);
+            for (Parameter parameter : parameters) {
+                tmp.add(new CoreReflParameterVariableElement(parameter));
+            }
+            return Collections.unmodifiableList(tmp);
+        }
+    }
+
+    private static List<ReflectionTypeParameterElement> createTypeParameterList(GenericDeclaration source) {
+        java.lang.reflect.TypeVariable<?>[] typeParams = source.getTypeParameters();
+        int length = typeParams.length;
+        if (length == 0)
+            return Collections.emptyList();
+        else {
+            List<ReflectionTypeParameterElement> tmp = new ArrayList<>(length);
+            for (java.lang.reflect.TypeVariable<?> typeVar : typeParams)
+                tmp.add(new CoreReflTypeParameterElement(typeVar));
+            return Collections.unmodifiableList(tmp);
+        }
+    }
+
+    private static class CoreReflTypeParameterElement
+        extends CoreReflElement
+        implements ReflectionTypeParameterElement {
+
+        private final GenericDeclaration source;
+        private final java.lang.reflect.TypeVariable<?> sourceTypeVar;
+
+        protected CoreReflTypeParameterElement(java.lang.reflect.TypeVariable<?> sourceTypeVar) {
+            this.sourceTypeVar = Objects.requireNonNull(sourceTypeVar);
+            this.source = Objects.requireNonNull(sourceTypeVar.getGenericDeclaration());
+        }
+
+        @Override
+        public AnnotatedElement getSource() {
+            return (AnnotatedElement)source;
+        }
+
+        protected java.lang.reflect.TypeVariable<?> getSourceTypeVar() {
+            return sourceTypeVar;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof CoreReflTypeParameterElement) {
+                return sourceTypeVar.equals(((CoreReflTypeParameterElement)o).sourceTypeVar);
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public <R,P> R accept(ElementVisitor<R,P> v, P p) {
+            return v.visitTypeParameter(this, p);
+        }
+
+        @Override
+        public <R,P> R accept(ReflectionElementVisitor<R,P> v, P p) {
+            return v.visitTypeParameter(this, p);
+        }
+
+        @Override
+        public List<ReflectionElement> getEnclosedElements() {
+            return Collections.emptyList();
+        }
+
+        @Override
+        public ReflectionElement getEnclosingElement() {
+            if (source instanceof Class)
+                return createMirror((Class<?>)source);
+            else if (source instanceof Method)
+                return createMirror((Method)source);
+            else if (source instanceof Constructor)
+                return createMirror((Constructor<?>)source);
+            else
+                throw new AssertionError("Unexpected enclosing element: " + source);
+        }
+
+        @Override
+        public ElementKind getKind() {
+            return ElementKind.TYPE_PARAMETER;
+        }
+
+        @Override
+        public Name getSimpleName() {
+            return StringName.instance(sourceTypeVar.getName());
+        }
+
+        // TypeParameterElement methods
+        @Override
+        public ReflectionElement getGenericElement() {
+            return getEnclosingElement(); // As per the doc,
+                                          // getEnclosingElement and
+                                          // getGenericElement return
+                                          // the same information.
+        }
+
+        @Override
+        public List<? extends TypeMirror> getBounds() {
+            Type[] types = getSourceTypeVar().getBounds();
+            int len = types.length;
+
+            if (len > 0) {
+                List<TypeMirror> res = new ArrayList<>(len);
+                for (Type t : types) {
+                    res.add(TypeFactory.instance(t));
+                }
+                return Collections.unmodifiableList(res);
+            } else {
+                return Collections.emptyList();
+            }
+        }
+    }
+
+    private abstract static class CoreReflVariableElement extends CoreReflElement
+        implements ReflectionVariableElement {
+
+        protected CoreReflVariableElement() {}
+
+        // Element visitor
+        @Override
+        public <R,P> R accept(ElementVisitor<R,P>v, P p) {
+            return v.visitVariable(this, p);
+        }
+
+        // ReflectElement visitor
+        @Override
+        public <R,P> R accept(ReflectionElementVisitor<R,P> v, P p) {
+            return v.visitVariable(this, p);
+        }
+
+        @Override
+        public List<ReflectionElement> getEnclosedElements() {
+            return Collections.emptyList();
+        }
+
+        @Override
+        public ReflectionElement getEnclosingElement() {
+            return null;
+        }
+
+        @Override
+        public boolean isSynthetic() {
+            return false;
+        }
+
+        @Override
+        public boolean isImplicit() {
+            return false;
+        }
+    }
+
+    private static class CoreReflFieldVariableElement extends CoreReflVariableElement {
+        private final Field source;
+
+        protected CoreReflFieldVariableElement(Field source) {
+            this.source = Objects.requireNonNull(source);
+        }
+
+        @Override
+        public Field getSource() {
+            return source;
+        }
+
+        @Override
+        public TypeMirror asType() {
+            return createTypeMirror(getSource().getType());
+        }
+
+        @Override
+        public ElementKind getKind() {
+            if (source.isEnumConstant())
+                return ElementKind.ENUM_CONSTANT;
+            else
+                return ElementKind.FIELD;
+        }
+
+        @Override
+        public Set<Modifier> getModifiers() {
+            return ModifierUtil.instance(source.getModifiers() &
+                                         java.lang.reflect.Modifier.fieldModifiers(), false);
+        }
+
+        @Override
+        public Name getSimpleName() {
+            return StringName.instance(source.getName());
+        }
+
+        @Override
+        public ReflectionElement getEnclosingElement() {
+            return createMirror(source.getDeclaringClass());
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof CoreReflFieldVariableElement) {
+                return Objects.equals(source,
+                                      ((CoreReflFieldVariableElement)o).getSource());
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public Object getConstantValue() {
+            Field target = source;
+
+            // The api says only Strings and primitives may be compile time constants.
+            // Ensure field is that, and final.
+            //
+            // Also, we don't have an instance so restrict to static Fields
+            //
+            if (!(source.getType().equals(java.lang.String.class)
+                  || source.getType().isPrimitive())) {
+                return null;
+            }
+            final int modifiers = target.getModifiers();
+            if (!( java.lang.reflect.Modifier.isFinal(modifiers) &&
+                   java.lang.reflect.Modifier.isStatic(modifiers))) {
+                return null;
+            }
+
+            try {
+                return target.get(null);
+            } catch (IllegalAccessException e) {
+                try {
+                    target.setAccessible(true);
+                    return target.get(null);
+                } catch (IllegalAccessException i) {
+                    throw new SecurityException(i);
+                }
+            }
+        }
+    }
+
+    private static class CoreReflParameterVariableElement
+        extends CoreReflVariableElement {
+        private final Parameter source;
+
+        protected CoreReflParameterVariableElement(Parameter source) {
+            this.source = Objects.requireNonNull(source);
+        }
+
+        @Override
+        public Parameter getSource() {
+            return source;
+        }
+
+        @Override
+        public Set<Modifier> getModifiers() {
+            return ModifierUtil.instance(source.getModifiers() &
+                                         java.lang.reflect.Modifier.parameterModifiers(), false);
+        }
+
+        @Override
+        public TypeMirror asType() {
+            // TODO : switch to parameterized type
+            return createTypeMirror(source.getType());
+        }
+
+        @Override
+        public ElementKind getKind() {
+            return ElementKind.PARAMETER;
+        }
+
+        @Override
+        public Name getSimpleName() {
+            return StringName.instance(source.getName());
+        }
+
+        @Override
+        public ReflectionElement getEnclosingElement() {
+            Executable enclosing = source.getDeclaringExecutable();
+            if (enclosing instanceof Method)
+                return createMirror((Method)enclosing);
+            else if (enclosing instanceof Constructor)
+                return createMirror((Constructor<?>)enclosing);
+            else
+                throw new AssertionError("Bad enclosing value.");
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof CoreReflParameterVariableElement) {
+                return source.equals(((CoreReflParameterVariableElement) o).getSource());
+            } else
+                return false;
+        }
+
+        // VariableElement methods
+        @Override
+        public Object getConstantValue() {
+            return null;
+        }
+
+        @Override
+        public boolean isSynthetic() {
+            return source.isSynthetic();
+        }
+
+        @Override
+        public boolean isImplicit() {
+            return source.isImplicit();
+        }
+    }
+
+    private static class CoreReflPackageElement extends CoreReflElement
+        implements ReflectionPackageElement {
+
+        private final Package source;
+
+        protected CoreReflPackageElement(Package source) {
+            this.source = source;
+        }
+
+        @Override
+        public Package getSource() {
+            return source;
+        }
+
+        @Override
+        public <R,P> R accept(ElementVisitor<R,P> v, P p) {
+            return v.visitPackage(this, p);
+        }
+
+        @Override
+        public <R,P> R accept(ReflectionElementVisitor<R,P> v, P p) {
+            return v.visitPackage(this, p);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof CoreReflPackageElement) {
+                return Objects.equals(source,
+                                      ((CoreReflPackageElement)o).getSource());
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public ElementKind getKind() {
+            return ElementKind.PACKAGE;
+        }
+
+        @Override
+        public ReflectionElement getEnclosingElement() {
+            return null;
+        }
+
+        @Override
+        public List<ReflectionElement> getEnclosedElements() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Name getQualifiedName() {
+            return StringName.instance((source != null) ?
+                                       source.getName() :
+                                       "" );
+        }
+
+        @Override
+        public Name getSimpleName() {
+            String n = ((source != null) ?
+                        source.getName() :
+                        "");
+            int index = n.lastIndexOf('.');
+            if (index > 0) {
+                return StringName.instance(n.substring(index + 1, n.length()));
+            } else {
+                return StringName.instance(n);
+            }
+        }
+
+        @Override
+        public boolean isUnnamed() {
+            if (source != null) {
+                String name = source.getName();
+                return(name == null || name.isEmpty());
+            } else
+                return true;
+        }
+    }
+
+    private static class CoreReflAnnotationMirror
+        implements javax.lang.model.element.AnnotationMirror {
+        private final Annotation annotation;
+
+        protected CoreReflAnnotationMirror(Annotation annotation) {
+            this.annotation = Objects.requireNonNull(annotation);
+        }
+
+        @Override
+        public DeclaredType getAnnotationType() {
+            return (DeclaredType)TypeFactory.instance(annotation.annotationType());
+        }
+
+        @Override
+        public Map<? extends ReflectionExecutableElement, ? extends AnnotationValue> getElementValues() {
+            // This differs from the javac implementation in that it returns default values
+
+            Method[] elems = annotation.annotationType().getDeclaredMethods();
+            int len = elems.length;
+
+            if (len > 0) {
+                Map<ReflectionExecutableElement, AnnotationValue> res = new HashMap<>();
+                for (Method m : elems) {
+                    AnnotationValue v;
+                    try {
+                        v = new CoreReflAnnotationValue(m.invoke(annotation));
+                    } catch (IllegalAccessException e) {
+                        try {
+                            m.setAccessible(true);
+                            v = new CoreReflAnnotationValue(m.invoke(annotation));
+                        } catch (IllegalAccessException i) {
+                            throw new SecurityException(i);
+                        } catch (InvocationTargetException ee) {
+                            throw new RuntimeException(ee);
+                        }
+                    } catch (InvocationTargetException ee) {
+                        throw new RuntimeException(ee);
+                    }
+                    ReflectionExecutableElement e = createMirror(m);
+                    res.put(e, v);
+                }
+
+                return Collections.unmodifiableMap(res);
+            } else {
+                return Collections.emptyMap();
+            }
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (other instanceof CoreReflAnnotationMirror) {
+                return annotation.equals(((CoreReflAnnotationMirror)other).annotation);
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hashCode(annotation);
+        }
+
+        @Override
+        public String toString() {
+            return annotation.toString();
+        }
+    }
+
+    private static class CoreReflAnnotationValue
+        implements javax.lang.model.element.AnnotationValue {
+        private Object value = null;
+
+        protected CoreReflAnnotationValue(Object value) {
+            // Is this constraint really necessary?
+            Objects.requireNonNull(value);
+            this.value = value;
+        }
+
+        @Override
+        public Object getValue() {
+            return value;
+        }
+
+        @Override
+        public String toString() {
+            return value.toString();
+        }
+
+        @Override
+        public <R,P> R accept(AnnotationValueVisitor<R,P> v, P p) {
+            return v.visit(this, p);
+        }
+    }
+
+    // Helper utility classes
+
+    private static class StringName implements Name {
+        private String name;
+
+        private StringName(String name) {
+            this.name = Objects.requireNonNull(name);
+        }
+
+        public static StringName instance(String name) {
+            return new StringName(name);
+        }
+
+        @Override
+        public int length() {
+            return name.length();
+        }
+
+        @Override
+        public char charAt(int index) {
+            return name.charAt(index);
+        }
+
+        @Override
+        public CharSequence subSequence(int start, int end) {
+            return name.subSequence(start, end);
+        }
+
+        @Override
+        public String toString() {
+            return name;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (other instanceof StringName) {
+                return name.equals(((StringName) other).name);
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public int hashCode() {
+            return name.hashCode();
+        }
+
+        @Override
+        public boolean contentEquals(CharSequence cs) {
+            return name.contentEquals(cs);
+        }
+    }
+
+    /*
+     * Given an {@code int} value of modifiers, return a proper immutable set
+     * of {@code Modifier}s as a result.
+     */
+    private static class ModifierUtil {
+        private ModifierUtil() {
+            throw new AssertionError("No instances for you.");
+        }
+
+        // Exercise for the reader: explore if caching of sets of
+        // Modifiers would be helpful.
+
+        public static Set<Modifier> instance(int modifiers, boolean isDefault) {
+            Set<Modifier> modSet = EnumSet.noneOf(Modifier.class);
+
+            if (java.lang.reflect.Modifier.isAbstract(modifiers))
+                modSet.add(Modifier.ABSTRACT);
+
+            if (java.lang.reflect.Modifier.isFinal(modifiers))
+                modSet.add(Modifier.FINAL);
+
+            if (java.lang.reflect.Modifier.isNative(modifiers))
+                modSet.add(Modifier.NATIVE);
+
+            if (java.lang.reflect.Modifier.isPrivate(modifiers))
+                modSet.add(Modifier.PRIVATE);
+
+            if (java.lang.reflect.Modifier.isProtected(modifiers))
+                modSet.add(Modifier.PROTECTED);
+
+            if (java.lang.reflect.Modifier.isPublic(modifiers))
+                modSet.add(Modifier.PUBLIC);
+
+            if (java.lang.reflect.Modifier.isStatic(modifiers))
+                modSet.add(Modifier.STATIC);
+
+            if (java.lang.reflect.Modifier.isStrict(modifiers))
+                modSet.add(Modifier.STRICTFP);
+
+            if (java.lang.reflect.Modifier.isSynchronized(modifiers))
+                modSet.add(Modifier.SYNCHRONIZED);
+
+            if (java.lang.reflect.Modifier.isTransient(modifiers))
+                modSet.add(Modifier.TRANSIENT);
+
+            if (java.lang.reflect.Modifier.isVolatile(modifiers))
+                modSet.add(Modifier.VOLATILE);
+
+            if (isDefault)
+                modSet.add(Modifier.DEFAULT);
+
+            return Collections.unmodifiableSet(modSet);
+        }
+    }
+
+    private abstract static class AbstractTypeMirror implements TypeMirror {
+        private final TypeKind kind;
+
+        protected AbstractTypeMirror(TypeKind kind) {
+            this.kind = Objects.requireNonNull(kind);
+        }
+
+        @Override
+        public TypeKind getKind() {
+            return kind;
+        }
+
+        @Override
+        public <R,P> R accept(TypeVisitor<R,P> v, P p) {
+            return v.visit(this, p);
+        }
+
+        //Types methods
+        abstract List<? extends TypeMirror> directSuperTypes();
+
+        TypeMirror capture() {
+            // Exercise for the reader: make this abstract and implement in subtypes
+            throw new UnsupportedOperationException();
+        }
+
+        TypeMirror erasure() {
+            // Exercise for the reader: make this abstract and implement in subtypes
+            throw new UnsupportedOperationException();
+        }
+
+        // Exercise for the reader: implement the AnnotatedConstruct methods
+        @Override
+        public List<? extends AnnotationMirror> getAnnotationMirrors() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    private static class CoreReflArrayType extends AbstractTypeMirror
+        implements javax.lang.model.type.ArrayType,
+                   Reifiable {
+        private Class<?> source = null;
+        private Class<?> component = null;
+        private TypeMirror eagerComponent = null;
+
+        protected CoreReflArrayType(Class<?> source) {
+            super(TypeKind.ARRAY);
+            this.source = source;
+            this.component = source.getComponentType();
+            this.eagerComponent = TypeFactory.instance(component);
+        }
+
+        public TypeMirror getComponentType() {
+            return eagerComponent;
+        }
+
+        @Override
+        public Class<?> getSource() {
+            return source;
+        }
+
+        @Override
+        List<? extends TypeMirror> directSuperTypes() {
+            final TypeMirror componentType = getComponentType();
+            final TypeMirror[] directSupers;
+
+            // JLS v4 4.10.3
+            if (componentType.getKind().isPrimitive() ||
+                component.equals(java.lang.Object.class)) {
+                directSupers = new TypeMirror[3];
+                directSupers[0] = TypeFactory.instance(java.lang.Object.class);
+                directSupers[1] = TypeFactory.instance(java.lang.Cloneable.class);
+                directSupers[2] = TypeFactory.instance(java.io.Serializable.class);
+            } else if (componentType.getKind() == TypeKind.ARRAY) {
+                List<? extends TypeMirror> componentDirectSupertypes = CoreReflTypes.instance().directSupertypes(componentType);
+                directSupers = new TypeMirror[componentDirectSupertypes.size()];
+                for (int i = 0; i < directSupers.length; i++) {
+                    directSupers[i] = new CoreReflArrayType(Array.newInstance(((Reifiable)componentDirectSupertypes.get(i)).getSource(), 0).getClass());
+                }
+            } else {
+                Class<?> superClass = component.getSuperclass();
+                Class<?>[] interfaces = component.getInterfaces();
+                directSupers = new TypeMirror[1 + interfaces.length];
+
+                directSupers[0] = TypeFactory.instance(Array.newInstance(superClass, 0).getClass());
+
+                for (int i = 0; i < interfaces.length; i++) {
+                    directSupers[i + 1] = TypeFactory.instance(Array.newInstance(interfaces[i],0).getClass());
+                }
+            }
+
+            return Collections.unmodifiableList(Arrays.asList(directSupers));
+        }
+
+        @Override
+        public String toString() {
+            return getKind() + " of " + getComponentType().toString();
+        }
+    }
+
+    private static class CaptureTypeVariable extends AbstractTypeMirror implements javax.lang.model.type.TypeVariable {
+        private TypeMirror source = null;
+        private TypeMirror upperBound = null;
+        private TypeMirror lowerBound = null;
+
+        CaptureTypeVariable(TypeMirror source,
+                            TypeMirror upperBound,
+                            TypeMirror lowerBound) {
+            super(TypeKind.TYPEVAR);
+
+            this.source = Objects.requireNonNull(source);
+            this.upperBound = (upperBound == null ? CoreReflTypes.instance().getNullType() : upperBound);
+            this.lowerBound = (lowerBound == null ? CoreReflTypes.instance().getNullType() : lowerBound);
+        }
+
+        protected Class<?> getSource() {
+            if (source instanceof CoreReflDeclaredType) {
+                return ((CoreReflDeclaredType)source).getSource();
+            } else {
+                return null;
+            }
+        }
+
+        @Override
+        public TypeMirror getUpperBound() {
+            return upperBound;
+        }
+
+        @Override
+        public TypeMirror getLowerBound() {
+            return lowerBound;
+        }
+
+        @Override
+        public Element asElement() {
+            if (null == getSource()) {
+                return null;
+            }
+            return CoreReflectionFactory.createMirror(getSource());
+        }
+
+        @Override
+        List<? extends TypeMirror> directSuperTypes() {
+            throw new UnsupportedOperationException();
+
+        }
+
+        @Override
+        public String toString() {
+            return getKind() + " CAPTURE of: " + source.toString();
+        }
+    }
+
+    private static class CoreReflElements implements ReflectionElements {
+        private CoreReflElements() {} // mostly one instance for you
+
+        private static CoreReflElements instance = new CoreReflElements();
+
+        static CoreReflElements instance() {
+            return instance;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public ReflectionPackageElement getPackageElement(CharSequence name) {
+            return createMirror(Package.getPackage(name.toString()));
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public ReflectionTypeElement getTypeElement(CharSequence name) {
+            // where name is a Canonical Name jls 6.7
+            // but this method will probably accept an equivalent FQN
+            // depending on Class.forName(String)
+
+            ReflectionTypeElement tmp = null;
+
+            // Filter out arrays
+            String n = name.toString();
+            if (n.contains("[")) return null;
+            if (n.equals("")) return null;
+
+            // The intention of this loop is to handle nested
+            // elements.  If finding the element using Class.forName
+            // fails, an attempt is made to find the element as an
+            // enclosed element by trying fo find a prefix of the name
+            // (dropping a trailing ".xyz") and looking for "xyz" as
+            // an enclosed element.
+
+            Deque<String> parts = new ArrayDeque<>();
+            boolean again;
+            do {
+                again = false;
+                try {
+                    tmp = createMirror(Class.forName(n));
+                } catch (ClassNotFoundException e) {
+                    tmp = null;
+                }
+
+                if (tmp != null) {
+                    if (parts.isEmpty()) {
+                        return tmp;
+                    }
+
+                    tmp = findInner(tmp, parts);
+                    if (tmp != null) {
+                        return tmp;
+                    }
+                }
+
+                int indx = n.lastIndexOf('.');
+                if (indx > -1) {
+                    parts.addFirst(n.substring(indx + 1));
+                    n = n.substring(0, indx);
+                    again = true;
+                }
+            } while (again);
+
+            return null;
+        }
+
+        // Recursively finds enclosed type elements named as part.top() popping part and repeating
+        private ReflectionTypeElement findInner(ReflectionTypeElement e, Deque<String> parts) {
+            if (parts.isEmpty()) {
+                return e;
+            }
+
+            String part = parts.removeFirst();
+            List<ReflectionElement> enclosed = e.getEnclosedElements();
+            for (ReflectionElement elm : enclosed) {
+                if ((elm.getKind() == ElementKind.CLASS ||
+                     elm.getKind() == ElementKind.INTERFACE ||
+                     elm.getKind() == ElementKind.ENUM ||
+                     elm.getKind() == ElementKind.ANNOTATION_TYPE)
+                    && elm.getSimpleName().toString().equals(part)) {
+                    ReflectionTypeElement t = findInner((ReflectionTypeElement)elm, parts);
+                    if (t != null) {
+                        return t;
+                    }
+                }
+            }
+            return null;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public Map<? extends ReflectionExecutableElement, ? extends AnnotationValue>
+            getElementValuesWithDefaults(AnnotationMirror a) {
+            if (a instanceof CoreReflAnnotationMirror) {
+                return ((CoreReflAnnotationMirror)a).getElementValues();
+            } else {
+                throw new IllegalArgumentException();
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public String getDocComment(Element e) {
+            checkElement(e);
+            return null; // As per the doc
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean isDeprecated(Element e) {
+            checkElement(e);
+            return ((CoreReflElement)e).getSource().isAnnotationPresent(java.lang.Deprecated.class);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public Name getBinaryName(TypeElement type) {
+            checkElement(type);
+            return StringName.instance(((CoreReflTypeElement)type)
+                                       .getSource()
+                                       .getName());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public ReflectionPackageElement getPackageOf(Element type) {
+            checkElement(type);
+            if (type instanceof ReflectionPackageElement) {
+                return (ReflectionPackageElement)type;
+            }
+
+            Package p;
+            if (type instanceof CoreReflTypeElement) {
+                p = ((CoreReflTypeElement)type).getSource().getPackage();
+            } else {
+                CoreReflTypeElement enclosingTypeElement = (CoreReflTypeElement)getEnclosingTypeElement((ReflectionElement)type);
+                p = enclosingTypeElement.getSource().getPackage();
+            }
+
+            return createMirror(p);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public List<? extends ReflectionElement> getAllMembers(TypeElement type) {
+            checkElement(type);
+            return getAllMembers((ReflectionTypeElement)type);
+        }
+
+        // Exercise for the reader: should this method, and similar
+        // ones that specialize on the more specific argument types,
+        // be addd to the public ReflectionElements API?
+        public List<? extends ReflectionElement> getAllMembers(ReflectionTypeElement type) {
+            return type.getAllMembers();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public List<? extends AnnotationMirror> getAllAnnotationMirrors(Element e) {
+            checkElement(e);
+            AnnotatedElement ae = CoreReflElement.class.cast(e).getSource();
+            Annotation[] annotations = ae.getAnnotations();
+            int len = annotations.length;
+
+            if (len > 0) {
+                List<AnnotationMirror> res = new ArrayList<>(len);
+                for (Annotation a : annotations) {
+                    res.add(createMirror(a));
+                }
+                return Collections.unmodifiableList(res);
+            } else {
+                List<AnnotationMirror> ret = Collections.emptyList();
+                return ret;
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean hides(Element hider, Element hidden) {
+            checkElement(hider);
+            checkElement(hidden);
+
+            // Names must be equal
+            if (!hider.getSimpleName().equals(hidden.getSimpleName())) {
+                return false;
+            }
+
+            // Hides isn't reflexive
+            if (hider.equals(hidden)) {
+                return false;
+            }
+
+            // Hider and hidden needs to be field, method or type
+            // and fields hide fields, types hide types, methods hide methods
+            // IE a Field doesn't hide a Methods etc
+            ElementKind hiderKind = hider.getKind();
+            ElementKind hiddenKind = hidden.getKind();
+            if (hiderKind.isField() && !hiddenKind.isField()) {
+                return false;
+            } else if (hiderKind.isClass() &&
+                       !(hiddenKind.isClass() || hiddenKind.isInterface())) {
+                return false;
+            } else if (hiderKind.isInterface() &&
+                       !(hiddenKind.isClass() || hiddenKind.isInterface())) {
+                return false;
+            } else if (hiderKind == ElementKind.METHOD && hiddenKind != ElementKind.METHOD) {
+                return false;
+            } else if (!(hiderKind.isClass() ||
+                         hiderKind.isInterface() ||
+                         hiderKind.isField() ||
+                         hiderKind == ElementKind.METHOD)) {
+                return false;
+            }
+
+            Set<Modifier> hm = hidden.getModifiers();
+            // jls 8.4.8.2 only static methods can hide methods
+            if (hider.getKind() == ElementKind.METHOD) {
+                if (!hider.getModifiers().contains(Modifier.STATIC)) {
+                    return false; // hider not static
+                } else if (!hm.contains(Modifier.STATIC)) { // we know it's a method
+                    return false; // hidden not static
+                }
+
+                // For methods we also need to check parameter types
+                Class<?>[] h1 = ((CoreReflMethodExecutableElement)hider).getSource().getParameterTypes();
+                Class<?>[] h2 = ((CoreReflMethodExecutableElement)hidden).getSource().getParameterTypes();
+                if (h1.length != h2.length) {
+                    return false;
+                }
+                for (int i = 0; i < h1.length; i++) {
+                    if (h1[i] != h2[i]) {
+                        return false;
+                    }
+                }
+            }
+
+            // You can only hide visible elements
+            if (hm.contains(Modifier.PRIVATE)) {
+                return false; // hidden private, can't be hidden
+            } else if ((!(hm.contains(Modifier.PUBLIC) || hm.contains(Modifier.PROTECTED))) && // not private, not (public or protected) IE package private
+                       (!getPackageOf(hider).equals(getPackageOf(hidden)))) {
+                return false; // hidden package private, and different packages, IE not visible
+            }
+
+            // Ok so now hider actually hides hidden if hider is
+            // declared on a subtype of hidden.
+            //
+            // TODO: should this be a proper subtype or is that taken
+            // care of by the reflexive check in the beginning?
+            //
+            TypeMirror hiderType = getEnclosingTypeElement((ReflectionElement)hider).asType();
+            TypeMirror hiddenType = getEnclosingTypeElement((ReflectionElement)hidden).asType();
+
+            return getTypes().isSubtype(hiderType, hiddenType);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public ReflectionTypeElement getEnclosingTypeElement(ReflectionElement e) {
+            if (e.getKind() == ElementKind.PACKAGE) {
+                return null;
+            }
+
+            if(e instanceof CoreReflTypeParameterElement) {
+                ReflectionElement encElem = ((CoreReflTypeParameterElement)e).getEnclosingElement();
+                if (encElem instanceof ReflectionTypeElement) {
+                    return (ReflectionTypeElement)encElem;
+                } else  {
+                    return getEnclosingTypeElement(encElem);
+                }
+            }
+
+            Class<?> encl = null;
+            if (e instanceof CoreReflTypeElement) {
+                encl = ((CoreReflTypeElement)e).getSource().getDeclaringClass();
+            } else if (e instanceof CoreReflExecutableElement) {
+                encl = (((CoreReflExecutableElement)e).getSource()).getDeclaringClass();
+            } else if (e instanceof CoreReflFieldVariableElement) {
+                encl = ((CoreReflFieldVariableElement)e).getSource().getDeclaringClass();
+            } else if (e instanceof CoreReflParameterVariableElement) {
+                encl = ((CoreReflParameterVariableElement)e).getSource().getDeclaringExecutable().getDeclaringClass();
+            }
+
+            return encl == null ? null : createMirror(encl);
+        }
+
+        /**
+         *{@inheritDoc}
+         *
+         * Note that this implementation does not handle the situation
+         * where A overrides B and B overrides C but A does not
+         * directly override C. In this case, this implementation will
+         * erroneously return false.
+         */
+        @Override
+        public boolean overrides(ExecutableElement overrider, ExecutableElement overridden,
+                                 TypeElement type) {
+            checkElement(overrider);
+            checkElement(overridden);
+            checkElement(type);
+
+            // TODO handle transitive overrides
+            return overridesDirect(overrider, overridden, type);
+        }
+
+        private boolean overridesDirect(ExecutableElement overrider, ExecutableElement overridden,
+                                         TypeElement type) {
+            // Should we check that at least one of the types
+            // overrider has is in fact a supertype of the TypeElement
+            // 'type' supplied?
+
+            CoreReflExecutableElement rider = (CoreReflExecutableElement)overrider;
+            CoreReflExecutableElement ridden = (CoreReflExecutableElement)overridden;
+            CoreReflTypeElement riderType = (CoreReflTypeElement)type;
+
+            // Names must match, redundant - see subsignature below
+            if (!rider.getSimpleName().equals(ridden.getSimpleName())) {
+                return false;
+            }
+
+            // Constructors don't override
+            // TODO: verify this fact
+            if (rider.getKind() == ElementKind.CONSTRUCTOR ||
+                ridden.getKind() == ElementKind.CONSTRUCTOR) {
+                return false;
+            }
+
+            // Overridden must be visible to be overridden
+            // TODO Fix transitive visibility/override
+            Set<Modifier> rm = ridden.getModifiers();
+            if (rm.contains(Modifier.PRIVATE)) {
+                return false; // overridden private, can't be overridden
+            } else if ((!(rm.contains(Modifier.PUBLIC) || rm.contains(Modifier.PROTECTED))) && // not private, not (public or protected) IE package private
+                       (!getPackageOf(rider).equals(getPackageOf(ridden)))) {
+                return false; // ridden package private, and different packages, IE not visible
+            }
+
+            // Static methods doesn't override
+            if (rm.contains(Modifier.STATIC) ||
+                rider.getModifiers().contains(Modifier.STATIC)) {
+                return false;
+            }
+
+            // Declaring class of overrider must be a subclass of declaring class of overridden
+            // except we use the parameter type as declaring class of overrider
+            if (!getTypes().isSubtype(riderType.asType(), getEnclosingTypeElement(ridden).asType())) {
+                return false;
+            }
+
+            // Now overrider overrides overridden if the signature of rider is a subsignature of ridden
+            return getTypes().isSubsignature(rider.asType(), ridden.asType());
+        }
+
+        /**
+         *{@inheritDoc}
+         */
+        @Override
+        public String getConstantExpression(Object value) {
+            return Constants.format(value);
+        }
+
+        // If CoreReflectionFactory were a proper part of the JDK, the
+        // analogous functionality in javac could be reused.
+        private static class Constants {
+            /**
+             * Returns a string representation of a constant value (given in
+             * standard wrapped representation), quoted and formatted as in
+             * Java source.
+             */
+            public static String format(Object value) {
+                if (value instanceof Byte)      return formatByte((Byte) value);
+                if (value instanceof Short)     return formatShort((Short) value);
+                if (value instanceof Long)      return formatLong((Long) value);
+                if (value instanceof Float)     return formatFloat((Float) value);
+                if (value instanceof Double)    return formatDouble((Double) value);
+                if (value instanceof Character) return formatChar((Character) value);
+                if (value instanceof String)    return formatString((String) value);
+                if (value instanceof Integer ||
+                    value instanceof Boolean)   return value.toString();
+                else
+                    throw new IllegalArgumentException("Argument is not a primitive type or a string; it " +
+                                                       ((value == null) ?
+                                                        "is a null value." :
+                                                        "has class " +
+                                                        value.getClass().getName()) + "." );
+            }
+
+            private static String formatByte(byte b) {
+                return String.format("(byte)0x%02x", b);
+            }
+
+            private static String formatShort(short s) {
+                return String.format("(short)%d", s);
+            }
+
+            private static String formatLong(long lng) {
+                return lng + "L";
+            }
+
+            private static String formatFloat(float f) {
+                if (Float.isNaN(f))
+                    return "0.0f/0.0f";
+                else if (Float.isInfinite(f))
+                    return (f < 0) ? "-1.0f/0.0f" : "1.0f/0.0f";
+                else
+                    return f + "f";
+            }
+
+            private static String formatDouble(double d) {
+                if (Double.isNaN(d))
+                    return "0.0/0.0";
+                else if (Double.isInfinite(d))
+                    return (d < 0) ? "-1.0/0.0" : "1.0/0.0";
+                else
+                    return d + "";
+            }
+
+            private static String formatChar(char c) {
+                return '\'' + quote(c) + '\'';
+            }
+
+            private static String formatString(String s) {
+                return '"' + quote(s) + '"';
+            }
+
+            /**
+             * Escapes each character in a string that has an escape sequence or
+             * is non-printable ASCII.  Leaves non-ASCII characters alone.
+             */
+            private static String quote(String s) {
+                StringBuilder buf = new StringBuilder();
+                for (int i = 0; i < s.length(); i++) {
+                    buf.append(quote(s.charAt(i)));
+                }
+                return buf.toString();
+            }
+
+            /**
+             * Escapes a character if it has an escape sequence or is
+             * non-printable ASCII.  Leaves ASCII characters alone.
+             */
+            private static String quote(char ch) {
+                switch (ch) {
+                case '\b':  return "\\b";
+                case '\f':  return "\\f";
+                case '\n':  return "\\n";
+                case '\r':  return "\\r";
+                case '\t':  return "\\t";
+                case '\'':  return "\\'";
+                case '\"':  return "\\\"";
+                case '\\':  return "\\\\";
+                default:
+                    return (isPrintableAscii(ch))
+                        ? String.valueOf(ch)
+                        : String.format("\\u%04x", (int) ch);
+                }
+            }
+
+            /**
+             * Is a character printable ASCII?
+             */
+            private static boolean isPrintableAscii(char ch) {
+                return ch >= ' ' && ch <= '~';
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void printElements(Writer w, Element... elements) {
+            ElementVisitor<?, ?> printer = getPrinter(w);
+            try {
+                for (Element e : elements) {
+                    checkElement(e);
+                    printer.visit(e);
+                }
+            } finally {
+                try {
+                    w.flush();
+                } catch (java.io.IOException e) { /* Ignore */;}
+            }
+        }
+
+        private ElementVisitor<?, ?> getPrinter(Writer w) {
+            // First try a reflective call into javac and if that
+            // fails, fallback to a very simple toString-based
+            // scanner.
+            try {
+                //reflective form of
+                // return new com.sun.tools.javac.processing.PrintingProcessor.PrintingElementVisitor(w, getElements());
+                Class<?> printProcClass =
+                    ClassLoader.getSystemClassLoader().loadClass("com.sun.tools.javac.processing.PrintingProcessor$PrintingElementVisitor");
+                Constructor<?> printProcCtor = printProcClass.getConstructor(Writer.class, Elements.class);
+                return (ElementVisitor) printProcCtor.newInstance(w, getElements());
+            } catch (ReflectiveOperationException | SecurityException e) {
+                return new ElementScanner8<Writer, Void>(w){
+                    @Override
+                    public Writer scan(Element e, Void v) {
+                        try {
+                            DEFAULT_VALUE.append(e.toString());
+                            DEFAULT_VALUE.append("\n");
+                        } catch (java.io.IOException ioe) {
+                            throw new RuntimeException(ioe);
+                        }
+                        return DEFAULT_VALUE;
+                    }
+                };
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public Name getName(CharSequence cs) {
+            return StringName.instance(cs.toString());
+        }
+
+        private void checkElement(Element e) {
+            if(!(e instanceof CoreReflElement)) {
+                throw new IllegalArgumentException();
+            }
+        }
+
+        @Override
+        public boolean isFunctionalInterface(TypeElement e) {
+            throw new UnsupportedOperationException();
+            // Update once this functionality is in core reflection
+        }
+    }
+
+    private static class CoreReflTypes implements javax.lang.model.util.Types {
+        private static Types instance = new CoreReflTypes();
+
+        public static Types instance() {
+            return instance;
+        }
+
+        // Private to suppress instantiation
+        private CoreReflTypes() {}
+
+        // Types methods
+        @Override
+        public Element asElement(TypeMirror t) {
+            checkType(t);
+            if (t instanceof javax.lang.model.type.TypeVariable) {
+                ((javax.lang.model.type.TypeVariable)t).asElement();
+            } else if (t instanceof DeclaredType) {
+                return ((DeclaredType)t).asElement();
+            }
+            return null;
+        }
+
+        @Override
+        public boolean isSameType(TypeMirror t1, TypeMirror t2) {
+            if (t1.getKind() != t2.getKind()) {
+                return false;
+            }
+
+            if (t1.getKind() == TypeKind.WILDCARD ||
+                t2.getKind() == TypeKind.WILDCARD) {
+                // Wildcards are not equal to any type
+                return false;
+            }
+
+            if (t1 instanceof CoreReflDeclaredType &&
+                t2 instanceof CoreReflDeclaredType) {
+                return ((CoreReflDeclaredType)t1).isSameType((CoreReflDeclaredType)t2);
+            } else if (t1 instanceof PrimitiveType &&
+                       t2 instanceof PrimitiveType) {
+                return t1.getKind() == t2.getKind();
+            } else if (t1 instanceof NoType &&
+                       t2 instanceof NoType) {
+                return true;
+            } else if (t1 instanceof NullType &&
+                       t2 instanceof NullType) {
+                return true;
+            } else if (t1 instanceof ArrayType &&
+                       t2 instanceof ArrayType) {
+                return isSameType(((ArrayType)t1).getComponentType(), ((ArrayType)t2).getComponentType());
+            }
+
+            return false;
+        }
+
+        @Override
+        public boolean isSubtype(TypeMirror t1, TypeMirror t2) {
+            checkType(t1);
+            checkType(t2);
+
+            if (isSameType(t1, t2)) {
+                return true;
+            } else if(t1.getKind() == TypeKind.NULL) {
+                return true;
+            }
+
+            // This depth first traversal should terminate due to the ban on circular inheritance
+            List<? extends TypeMirror> directSupertypes = directSupertypes(t1);
+            if (directSupertypes.isEmpty()) {
+                return false;
+            }
+            for (TypeMirror ti : directSupertypes) {
+                if (isSameType(ti, t2) || isSubtype(ti, t2)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public boolean isAssignable(TypeMirror t1, TypeMirror t2) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean contains(TypeMirror t1, TypeMirror t2) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean isSubsignature(ExecutableType m1, ExecutableType m2) {
+            checkType(m1);
+            checkType(m2);
+
+            ExecutableMethodType m0 = (ExecutableMethodType)m1;
+
+            return m0.sameSignature((ExecutableMethodType)m2) || m0.sameSignature((ExecutableMethodType)erasure(m2));
+        }
+
+        @Override
+        public List<? extends TypeMirror> directSupertypes(TypeMirror t) {
+            checkType(t);
+            if (t instanceof ExecutableType ||
+                t.getKind() == TypeKind.PACKAGE) {
+                throw new IllegalArgumentException("You can't ask for direct supertypes for type: " + t);
+            }
+            return ((AbstractTypeMirror)t).directSuperTypes();
+        }
+
+        @Override
+        public TypeMirror erasure(TypeMirror t) {
+            checkType(t);
+            return ((AbstractTypeMirror)t).erasure();
+        }
+
+        @Override
+        public TypeElement boxedClass(javax.lang.model.type.PrimitiveType p) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public PrimitiveType unboxedType(TypeMirror t) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public TypeMirror capture(TypeMirror t) {
+            checkType(t);
+            return ((AbstractTypeMirror)t).capture();
+        }
+
+        @Override
+        public PrimitiveType getPrimitiveType(TypeKind kind) {
+            return PrimitiveType.instance(kind);
+        }
+
+        @Override
+        public NullType getNullType() {
+            return CoreReflNullType.getInstance();
+        }
+
+        @Override
+        public javax.lang.model.type.NoType getNoType(TypeKind kind) {
+            if (kind == TypeKind.NONE) {
+                return NoType.getNoneInstance();
+            } else if (kind == TypeKind.VOID) {
+                return NoType.getVoidInstance();
+            } else {
+                throw new IllegalArgumentException("No NoType of kind: " + kind);
+            }
+        }
+
+        @Override
+        public ArrayType getArrayType(TypeMirror componentType) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public javax.lang.model.type.WildcardType getWildcardType(TypeMirror extendsBound,
+                                                                  TypeMirror superBound) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public DeclaredType getDeclaredType(TypeElement typeElem, TypeMirror... typeArgs) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public javax.lang.model.type.DeclaredType getDeclaredType(javax.lang.model.type.DeclaredType containing,
+                                                                  TypeElement typeElem,
+                                                                  TypeMirror... typeArgs) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public TypeMirror asMemberOf(javax.lang.model.type.DeclaredType containing, Element element) {
+            throw new UnsupportedOperationException();
+        }
+
+        private void checkType(TypeMirror t) {
+            if (!(t instanceof AbstractTypeMirror)) {
+                throw new IllegalArgumentException("This Types implementation can only operate on CoreReflectionFactory type classes");
+            }
+        }
+    }
+
+    private abstract static class CoreReflDeclaredType extends AbstractTypeMirror
+        implements javax.lang.model.type.DeclaredType {
+        private Class<?> source = null;
+
+        private CoreReflDeclaredType(Class<?> source) {
+            super(TypeKind.DECLARED);
+            this.source = source;
+        }
+
+        static DeclaredType instance(Class<?> source, Type genericSource) {
+            if (genericSource instanceof ParameterizedType) {
+                return new ParameterizedDeclaredType(source, (ParameterizedType)genericSource);
+            } else if (genericSource instanceof Class) { // This happens when a field has a raw type
+                if (!source.equals(genericSource)) {
+                    throw new IllegalArgumentException("Don't know how to handle this");
+                }
+                return instance(source);
+            }
+            throw new IllegalArgumentException("Don't know how to create a declared type from: " +
+                                               source +
+                                               " and genericSource " +
+                                               genericSource);
+        }
+
+        static DeclaredType instance(Class<?> source) {
+            return new RawDeclaredType(source);
+        }
+
+        protected Class<?> getSource() {
+            return source;
+        }
+
+        @Override
+        public Element asElement() {
+            return CoreReflectionFactory.createMirror(getSource());
+        }
+
+        abstract boolean isSameType(DeclaredType other);
+
+        @Override
+        TypeMirror capture() {
+            return new CaptureDeclaredType(this);
+        }
+
+        private static class CaptureDeclaredType extends CoreReflDeclaredType {
+            CoreReflDeclaredType cap;
+            CaptureDeclaredType(CoreReflDeclaredType t) {
+                super(t.source);
+                this.cap = t;
+            }
+
+            @Override
+            public List<? extends TypeMirror> getTypeArguments() {
+                List<? extends TypeMirror> wrapped = cap.getTypeArguments();
+                ArrayList<TypeMirror> res = new ArrayList<>(wrapped.size());
+                res.ensureCapacity(wrapped.size());
+
+                for (int i = 0; i < wrapped.size(); i++) {
+                    TypeMirror t = wrapped.get(i);
+
+                    if (t instanceof javax.lang.model.type.WildcardType) {
+                        res.add(i, convert(t));
+                    } else {
+                        res.add(i, t);
+                    }
+                }
+                return Collections.unmodifiableList(res);
+            }
+
+            private TypeMirror convert(TypeMirror t) {
+                if (!(t instanceof javax.lang.model.type.WildcardType)) {
+                    throw new IllegalArgumentException();
+                } else {
+                    javax.lang.model.type.WildcardType w = (javax.lang.model.type.WildcardType)t;
+                    return TypeFactory.typeVariableInstance(w, w.getExtendsBound(), w.getSuperBound());
+                }
+            }
+
+            @Override
+            public TypeMirror getEnclosingType() {
+                return cap.getEnclosingType();
+            }
+
+            @Override
+            List<? extends TypeMirror> directSuperTypes() {
+                return cap.directSuperTypes();
+            }
+
+            @Override
+            boolean isSameType(DeclaredType other) {
+                return other == this;
+            }
+
+            @Override
+            public String toString() {
+                return " CAPTURE of: " + cap.toString();
+            }
+        }
+
+        private static class RawDeclaredType extends CoreReflDeclaredType
+            implements Reifiable {
+            private RawDeclaredType(Class<?> source) {
+                super(source);
+            }
+
+            @Override
+            public Class<?> getSource() {
+                return super.getSource();
+            }
+
+            @Override
+            public TypeMirror getEnclosingType() {
+                Class<?> enclosing = getSource().getEnclosingClass();
+                if (null == enclosing) {
+                    return NoType.getNoneInstance();
+                } else {
+                    return TypeFactory.instance(enclosing);
+                }
+            }
+
+            @Override
+            public List<? extends TypeMirror> getTypeArguments() {
+                return Collections.emptyList();
+            }
+
+            @Override
+            List<? extends TypeMirror> directSuperTypes() {
+                if (getSource().isEnum()) {
+                    return enumSuper();
+                }
+
+                if (getSource() == java.lang.Object.class) {
+                    return Collections.emptyList();
+                }
+                List<TypeMirror> res = new ArrayList<>();
+                Type[] superInterfaces = getSource().getInterfaces();
+                if (!getSource().isInterface()) {
+                    res.add(TypeFactory.instance(getSource().getSuperclass()));
+                } else if (superInterfaces.length == 0) {
+                    // Interfaces that don't extend another interface
+                    // have java.lang.Object as a direct supertype.
+                    return Collections.unmodifiableList(Arrays.asList(TypeFactory.instance(java.lang.Object.class)));
+                }
+
+                for (Type t : superInterfaces) {
+                    res.add(TypeFactory.instance(t));
+                }
+                return Collections.unmodifiableList(res);
+            }
+
+            private List<? extends TypeMirror> enumSuper() {
+                Class<?> rawSuper = getSource().getSuperclass();
+                Type[] actualArgs = ((ParameterizedTypeImpl)getSource().getGenericSuperclass()).getActualTypeArguments();
+
+                // Reconsider this : assume the problem is making
+                // Enum<MyEnum> rather than just a raw enum.
+                return Collections.unmodifiableList(Arrays.asList(TypeFactory.instance(ParameterizedTypeImpl.make(rawSuper,
+                                                                                                                  Arrays.copyOf(actualArgs,
+                                                                                                                                actualArgs.length),
+                                                                                                                  null))));
+            }
+
+            @Override
+            boolean isSameType(DeclaredType other) {
+                if (other instanceof RawDeclaredType) {
+                    return Objects.equals(getSource(), ((RawDeclaredType)other).getSource());
+                } else {
+                    return false;
+                }
+            }
+
+            @Override
+            public String toString() {
+                return getSource().toString();
+            }
+        }
+
+        private static class ParameterizedDeclaredType extends CoreReflDeclaredType {
+            private ParameterizedType genericSource = null;
+            private ParameterizedDeclaredType(Class<?> source, ParameterizedType genericSource) {
+                super(source);
+                this.genericSource = genericSource;
+            }
+
+            @Override
+            public TypeMirror getEnclosingType() {
+                Type me = genericSource;
+                Type owner = GenericTypes.getEnclosingType(me);
+                if (owner == null) {
+                    return NoType.getNoneInstance();
+                }
+                return TypeFactory.instance(owner);
+            }
+
+            @Override
+            public List<? extends TypeMirror> getTypeArguments() {
+                Type[] typeArgs = genericSource.getActualTypeArguments();
+
+                int length = typeArgs.length;
+                if (length == 0)
+                    return Collections.emptyList();
+                else {
+                    List<TypeMirror> tmp = new ArrayList<>(length);
+                    for (Type t : typeArgs) {
+                        tmp.add(TypeFactory.instance(t));
+                    }
+                    return Collections.unmodifiableList(tmp);
+                }
+            }
+
+            @Override
+            List<? extends TypeMirror> directSuperTypes() {
+                if (getSource() == java.lang.Object.class) {
+                    return Collections.emptyList();
+                }
+
+                List<TypeMirror> res = new ArrayList<>();
+                Type[] superInterfaces = getSource().getGenericInterfaces();
+                if (!getSource().isInterface()) {
+                    // Replace actual type arguments with our type arguments
+                    res.add(TypeFactory.instance(substituteTypeArgs(getSource().getGenericSuperclass())));
+                } else if (superInterfaces.length == 0) {
+                    // Interfaces that don't extend another interface
+                    // have java.lang.Object as a direct supertype, plus
+                    // possibly the interface's raw type
+                    res.add(TypeFactory.instance(java.lang.Object.class));
+                }
+
+                for (Type t : superInterfaces) {
+                    res.add(TypeFactory.instance(substituteTypeArgs(t)));
+                }
+
+                res.add(TypeFactory.instance(getSource())); // Add raw type
+                return Collections.unmodifiableList(res);
+            }
+
+            private Type substituteTypeArgs(Type type) {
+                if (!(type instanceof ParameterizedType)) {
+                    return type;
+                }
+
+                ParameterizedType target = (ParameterizedType)type;
+                // Cast to get a Class instead of a plain type.
+                Class<?> raw = ((ParameterizedTypeImpl)target).getRawType();
+                Type[] actualArgs = genericSource.getActualTypeArguments();
+
+                return  ParameterizedTypeImpl.make(raw, Arrays.copyOf(actualArgs, actualArgs.length), null);
+            }
+
+            @Override
+            boolean isSameType(DeclaredType other) {
+                if (other instanceof ParameterizedDeclaredType) {
+                    return GenericTypes.isSameGenericType(genericSource,
+                                                          ((ParameterizedDeclaredType)other).genericSource);
+                } else {
+                    return false;
+                }
+            }
+
+            @Override
+            public String toString() {
+                return getKind().toString() + " " + genericSource.toString();
+            }
+        }
+
+        /**
+         * Implementing class for ParameterizedType interface.
+         * Derived from sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
+         */
+
+        private static class ParameterizedTypeImpl implements ParameterizedType {
+            private Type[] actualTypeArguments;
+            private Class<?>  rawType;
+            private Type   ownerType;
+
+            private ParameterizedTypeImpl(Class<?> rawType,
+                                          Type[] actualTypeArguments,
+                                          Type ownerType) {
+                this.actualTypeArguments = actualTypeArguments;
+                this.rawType             = rawType;
+                if (ownerType != null) {
+                    this.ownerType = ownerType;
+                } else {
+                    this.ownerType = rawType.getDeclaringClass();
+                }
+                validateConstructorArguments();
+            }
+
+            private void validateConstructorArguments() {
+                java.lang.reflect.TypeVariable/*<?>*/[] formals = rawType.getTypeParameters();
+                // check correct arity of actual type args
+                if (formals.length != actualTypeArguments.length){
+                    throw new MalformedParameterizedTypeException();
+                }
+            }
+
+            /**
+             * Static factory. Given a (generic) class, actual type arguments
+             * and an owner type, creates a parameterized type.
+             * This class can be instantiated with a a raw type that does not
+             * represent a generic type, provided the list of actual type
+             * arguments is empty.
+             * If the ownerType argument is null, the declaring class of the
+             * raw type is used as the owner type.
+             * <p> This method throws a MalformedParameterizedTypeException
+             * under the following circumstances:
+             * If the number of actual type arguments (i.e., the size of the
+             * array {@code typeArgs}) does not correspond to the number of
+             * formal type arguments.
+             * If any of the actual type arguments is not an instance of the
+             * bounds on the corresponding formal.
+             * @param rawType the Class representing the generic type declaration being
+             * instantiated
+             * @param actualTypeArguments - a (possibly empty) array of types
+             * representing the actual type arguments to the parameterized type
+             * @param ownerType - the enclosing type, if known.
+             * @return An instance of {@code ParameterizedType}
+             * @throws MalformedParameterizedTypeException - if the instantiation
+             * is invalid
+             */
+            public static ParameterizedTypeImpl make(Class<?> rawType,
+                                                     Type[] actualTypeArguments,
+                                                     Type ownerType) {
+                return new ParameterizedTypeImpl(rawType, actualTypeArguments,
+                                                 ownerType);
+            }
+
+
+            /**
+             * Returns an array of {@code Type} objects representing the actual type
+             * arguments to this type.
+             *
+             * <p>Note that in some cases, the returned array be empty. This can occur
+             * if this type represents a non-parameterized type nested within
+             * a parameterized type.
+             *
+             * @return an array of {@code Type} objects representing the actual type
+             *     arguments to this type
+             * @throws {@code TypeNotPresentException} if any of the
+             *     actual type arguments refers to a non-existent type declaration
+             * @throws {@code MalformedParameterizedTypeException} if any of the
+             *     actual type parameters refer to a parameterized type that cannot
+             *     be instantiated for any reason
+             * @since 1.5
+             */
+            public Type[] getActualTypeArguments() {
+                return actualTypeArguments.clone();
+            }
+
+            /**
+             * Returns the {@code Type} object representing the class or interface
+             * that declared this type.
+             *
+             * @return the {@code Type} object representing the class or interface
+             *     that declared this type
+             */
+            public Class<?> getRawType() {
+                return rawType;
+            }
+
+
+            /**
+             * Returns a {@code Type} object representing the type that this type
+             * is a member of.  For example, if this type is {@code O<T>.I<S>},
+             * return a representation of {@code O<T>}.
+             *
+             * <p>If this type is a top-level type, {@code null} is returned.
+             *
+             * @return a {@code Type} object representing the type that
+             *     this type is a member of. If this type is a top-level type,
+             *     {@code null} is returned
+             */
+            public Type getOwnerType() {
+                return ownerType;
+            }
+
+            /*
+             * From the JavaDoc for java.lang.reflect.ParameterizedType
+             * "Instances of classes that implement this interface must
+             * implement an equals() method that equates any two instances
+             * that share the same generic type declaration and have equal
+             * type parameters."
+             */
+            @Override
+            public boolean equals(Object o) {
+                if (o instanceof ParameterizedType) {
+                    // Check that information is equivalent
+                    ParameterizedType that = (ParameterizedType) o;
+
+                    if (this == that)
+                        return true;
+
+                    Type thatOwner   = that.getOwnerType();
+                    Type thatRawType = that.getRawType();
+
+                    return Objects.equals(ownerType, thatOwner) &&
+                        Objects.equals(rawType, thatRawType) &&
+                        Arrays.equals(actualTypeArguments, // avoid clone
+                                      that.getActualTypeArguments());
+                } else
+                    return false;
+            }
+
+            @Override
+            public int hashCode() {
+                return
+                    Arrays.hashCode(actualTypeArguments) ^
+                    Objects.hashCode(ownerType) ^
+                    Objects.hashCode(rawType);
+            }
+
+            public String toString() {
+                StringBuilder sb = new StringBuilder();
+
+                if (ownerType != null) {
+                    if (ownerType instanceof Class)
+                        sb.append(((Class)ownerType).getName());
+                    else
+                        sb.append(ownerType.toString());
+
+                    sb.append(".");
+
+                    if (ownerType instanceof ParameterizedTypeImpl) {
+                        // Find simple name of nested type by removing the
+                        // shared prefix with owner.
+                        sb.append(rawType.getName().replace( ((ParameterizedTypeImpl)ownerType).rawType.getName() + "$",
+                                                             ""));
+                    } else
+                        sb.append(rawType.getName());
+                } else
+                    sb.append(rawType.getName());
+
+                if (actualTypeArguments != null &&
+                    actualTypeArguments.length > 0) {
+                    sb.append("<");
+                    boolean first = true;
+                    for (Type t: actualTypeArguments) {
+                        if (!first)
+                            sb.append(", ");
+                        if (t instanceof Class)
+                            sb.append(((Class)t).getName());
+                        else
+                            sb.append(t.toString());
+                        first = false;
+                    }
+                    sb.append(">");
+                }
+
+                return sb.toString();
+            }
+        }
+
+    }
+
+    private static class ErasedMethodType extends ExecutableMethodType implements javax.lang.model.type.ExecutableType {
+        private final Method m;
+
+        ErasedMethodType(Method m) {
+            super(m);
+            this.m = Objects.requireNonNull(m);
+        }
+
+        @Override
+        public List<javax.lang.model.type.TypeVariable> getTypeVariables() {
+            return Collections.emptyList();
+        }
+
+        @Override
+        public List<? extends TypeMirror> getThrownTypes() {
+            Class<?>[] exceptions = m.getExceptionTypes();
+            int len = exceptions.length;
+
+            if (len > 0) {
+                List<TypeMirror> res = new ArrayList<TypeMirror>(len);
+                for (Class<?> t : exceptions) {
+                    res.add(TypeFactory.instance(t));
+                }
+                return Collections.unmodifiableList(res);
+            } else {
+                List<TypeMirror> ret = Collections.emptyList();
+                return ret;
+            }
+        }
+
+        @Override
+        public List<? extends TypeMirror> getParameterTypes() {
+            Class<?>[] params = m.getParameterTypes();
+            int len = params.length;
+
+            if (len > 0) {
+                List<TypeMirror> res = new ArrayList<TypeMirror>(len);
+                for (Class<?> t : params) {
+                    res.add(TypeFactory.instance(t));
+                }
+                return Collections.unmodifiableList(res);
+            } else {
+                List<TypeMirror> ret = Collections.emptyList();
+                return ret;
+            }
+        }
+
+        @Override
+        public TypeMirror getReturnType() {
+            return TypeFactory.instance(m.getReturnType());
+        }
+
+        @Override
+        TypeMirror erasure() {
+            return this;
+        }
+    }
+
+    private static class ErrorType extends AbstractTypeMirror implements javax.lang.model.type.ErrorType {
+        private static ErrorType errorType = new ErrorType();
+
+        public static ErrorType getErrorInstance() {
+            return errorType;
+        }
+
+        private ErrorType() {
+            super(TypeKind.ERROR);
+        }
+
+        @Override
+        public List<? extends TypeMirror> getTypeArguments() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public TypeMirror getEnclosingType() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Element asElement() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        List<? extends TypeMirror> directSuperTypes() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    private static class ExecutableMethodType extends AbstractTypeMirror
+        implements javax.lang.model.type.ExecutableType {
+        private final Method m;
+
+        ExecutableMethodType(Method m) {
+            super(TypeKind.EXECUTABLE);
+            this.m = Objects.requireNonNull(m);
+        }
+
+        @Override
+        public List<? extends TypeMirror> getThrownTypes() {
+            Type[] exceptions = m.getGenericExceptionTypes();
+            int len = exceptions.length;
+
+            if (len > 0) {
+                List<TypeMirror> res = new ArrayList<TypeMirror>(len);
+                for (Type t : exceptions) {
+                    res.add(TypeFactory.instance(t));
+                }
+                return Collections.unmodifiableList(res);
+            } else {
+                List<TypeMirror> ret = Collections.emptyList();
+                return ret;
+            }
+        }
+
+        @Override
+        public List<javax.lang.model.type.TypeVariable> getTypeVariables() {
+            java.lang.reflect.TypeVariable[] variables = m.getTypeParameters();
+            int len = variables.length;
+
+            if (len > 0) {
+                List<javax.lang.model.type.TypeVariable> res = new ArrayList<>(len);
+                for (java.lang.reflect.TypeVariable<?> t : variables) {
+                    res.add(TypeFactory.typeVariableInstance(t));
+                }
+                return Collections.unmodifiableList(res);
+            } else {
+                return Collections.emptyList();
+            }
+        }
+
+        @Override
+        public TypeMirror getReturnType() {
+            return TypeFactory.instance(m.getGenericReturnType());
+        }
+
+        @Override
+        public List<? extends TypeMirror> getParameterTypes() {
+            Type[] params = m.getGenericParameterTypes();
+            int len = params.length;
+
+            if (len > 0) {
+                List<TypeMirror> res = new ArrayList<TypeMirror>(len);
+                for (Type t : params) {
+                    res.add(TypeFactory.instance(t));
+                }
+                return Collections.unmodifiableList(res);
+            } else {
+                return Collections.emptyList();
+            }
+        }
+
+        @Override
+        List<? extends TypeMirror> directSuperTypes() {
+            // Spec says we don't need this
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        TypeMirror erasure() {
+            return new ErasedMethodType(m);
+        }
+
+        @Override
+        public TypeMirror getReceiverType() {
+            throw new UnsupportedOperationException();
+        }
+
+        boolean sameSignature(ExecutableMethodType other){
+            if (!m.getName().equals(other.m.getName())) {
+                return false;
+            }
+
+            List<? extends TypeMirror> thisParams = getParameterTypes();
+            List<? extends TypeMirror> otherParams = other.getParameterTypes();
+            if (thisParams.size() != otherParams.size()) {
+                return false;
+            }
+            for (int i = 0; i < thisParams.size(); i++) {
+                if (!CoreReflTypes.instance().isSameType(thisParams.get(i), otherParams.get(i))) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    private static class GenericTypes {
+        public static boolean isSameGenericType(Type t1, Type t2) {
+            if (t1 instanceof Class) {
+                return ((Class)t1).equals(t2);
+            } else if (t1 instanceof ParameterizedType) {
+                return ((ParameterizedType)t1).equals(t2);
+            }
+            throw new UnsupportedOperationException();
+        }
+
+        public static Type getEnclosingType(Type t1) {
+            if (t1 instanceof Class) {
+                return ((Class)t1).getEnclosingClass();
+            } else if (t1 instanceof ParameterizedType) {
+                return ((ParameterizedType)t1).getOwnerType();
+            }
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    private static class IntersectionDeclaredType extends AbstractTypeMirror
+        implements javax.lang.model.type.DeclaredType {
+        private Type[] sources = null;
+
+        IntersectionDeclaredType(Type[] sources) {
+            super(TypeKind.DECLARED);
+            this.sources = Arrays.copyOf(Objects.requireNonNull(sources),
+                                         sources.length);
+        }
+
+        @Override
+        public TypeMirror getEnclosingType() {
+            return NoType.getNoneInstance();
+        }
+
+        @Override
+        public  Element asElement() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public List<? extends TypeMirror> getTypeArguments() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        List<? extends TypeMirror> directSuperTypes() {
+            int len = sources.length;
+
+            if (len > 0) {
+                List<TypeMirror> res = new ArrayList<TypeMirror>(len);
+                for (Type c : sources) {
+                    res.add(TypeFactory.instance(c));
+                }
+                return Collections.unmodifiableList(res);
+            } else {
+                return Collections.emptyList();
+            }
+        }
+    }
+
+    private static class ModelWildcardType extends AbstractTypeMirror
+        implements javax.lang.model.type.WildcardType {
+        private java.lang.reflect.WildcardType genericSource;
+
+        ModelWildcardType(java.lang.reflect.WildcardType genericSource) {
+            super(TypeKind.WILDCARD);
+            this.genericSource = Objects.requireNonNull(genericSource);
+        }
+
+        @Override
+        List<? extends TypeMirror> directSuperTypes() {
+            // TODO Add support for this operation
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public TypeMirror getExtendsBound() {
+            Type[] t = genericSource.getUpperBounds();
+
+            if (t.length == 1) {
+                if (t[0].equals(Object.class) && getSuperBound() != null) { // can't have both lower and upper explicit
+                    return null;
+                }
+                return TypeFactory.instance(t[0]);
+            }
+            throw new UnsupportedOperationException(); // TODO: intersection type?
+        }
+
+        @Override
+        public TypeMirror getSuperBound() {
+            Type[] t = genericSource.getLowerBounds();
+
+            if (t.length == 0) { // bound is null
+                return null;
+            } else if (t.length == 1) {
+                return TypeFactory.instance(t[0]);
+            }
+            throw new UnsupportedOperationException(); // TODO: intersection type?
+        }
+
+        @Override
+        public String toString() {
+            return getKind() + " " + genericSource.toString();
+        }
+    }
+
+    private static class NoType extends AbstractTypeMirror
+        implements javax.lang.model.type.NoType {
+        private static NoType noneType = new NoType(TypeKind.NONE, "none");
+        private static NoType packageType = new NoType(TypeKind.PACKAGE, "package");
+        private static NoType voidType = new NoType(TypeKind.VOID, "void");
+
+        private String str;
+
+        public static NoType getNoneInstance() {
+            return noneType;
+        }
+
+        public static NoType getPackageInstance() {
+            return packageType;
+        }
+
+        public static NoType getVoidInstance() {
+            return voidType;
+        }
+
+        private NoType(TypeKind k, String str) {
+            super(k);
+            this.str = str;
+        }
+
+        @Override
+        List<? extends TypeMirror> directSuperTypes() {
+            // TODO We don't need this for the Package instance, how about the others?
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String toString() {
+            return str;
+        }
+    }
+
+    private static class CoreReflNullType extends AbstractTypeMirror
+        implements javax.lang.model.type.NullType {
+        private static CoreReflNullType nullType = new CoreReflNullType();
+
+        public static NullType getInstance() {
+            return nullType;
+        }
+
+        private CoreReflNullType() {
+            super(TypeKind.NULL);
+        }
+
+        @Override
+        List<? extends TypeMirror> directSuperTypes() {
+            // JLS 4.10.2 says:
+            // "The direct supertypes of the null type are all reference types other than the null type itself."
+            // TODO return null? an empty list? the error type? anyhow fix this
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    private static interface Reifiable {
+        Class<?> getSource();
+    }
+
+    private static class PrimitiveType extends AbstractTypeMirror
+        implements javax.lang.model.type.PrimitiveType,
+                   Reifiable {
+        private Class<?> source;
+
+        private static PrimitiveType booleanInstance = new PrimitiveType(TypeKind.BOOLEAN, boolean.class);
+        private static PrimitiveType byteInstance =    new PrimitiveType(TypeKind.BYTE, byte.class);
+        private static PrimitiveType charInstance =    new PrimitiveType(TypeKind.CHAR, char.class);
+        private static PrimitiveType shortInstance =   new PrimitiveType(TypeKind.SHORT, short.class);
+        private static PrimitiveType intInstance =     new PrimitiveType(TypeKind.INT, int.class);
+        private static PrimitiveType longInstance =    new PrimitiveType(TypeKind.LONG, long.class);
+        private static PrimitiveType floatInstance =   new PrimitiveType(TypeKind.FLOAT, float.class);
+        private static PrimitiveType doubleInstance =  new PrimitiveType(TypeKind.DOUBLE, double.class);
+
+        private PrimitiveType(TypeKind kind, Class<?> source) {
+            super(kind);
+            this.source = source;
+        }
+
+        @Override
+        public Class<?> getSource() {
+            return source;
+        }
+
+        static PrimitiveType instance(Class<?> c) {
+            switch(c.getName()) {
+            case "boolean":
+                return booleanInstance;
+            case "byte":
+                return byteInstance;
+            case "char":
+                return charInstance;
+            case "short":
+                return shortInstance;
+            case "int":
+                return intInstance;
+            case "long":
+                return longInstance;
+            case "float":
+                return floatInstance;
+            case "double":
+                return doubleInstance;
+            default:
+                throw new IllegalArgumentException();
+            }
+        }
+
+        static PrimitiveType instance(TypeKind k) {
+            switch(k) {
+            case BOOLEAN:
+                return booleanInstance;
+            case BYTE:
+                return byteInstance;
+            case CHAR:
+                return charInstance;
+            case SHORT:
+                return shortInstance;
+            case INT:
+                return intInstance;
+            case LONG:
+                return longInstance;
+            case FLOAT:
+                return floatInstance;
+            case DOUBLE:
+                return doubleInstance;
+            default:
+                throw new IllegalArgumentException();
+            }
+        }
+
+        @Override
+        public String toString() {
+            return source.getName();
+        }
+
+        //Types methods
+        @Override
+        List<? extends TypeMirror> directSuperTypes() {
+            switch (getKind()) {
+            case DOUBLE:
+                return Collections.emptyList();
+            case FLOAT:
+                return Arrays.asList(doubleInstance);
+            case LONG:
+                return Arrays.asList(floatInstance);
+            case INT:
+                return Arrays.asList(longInstance);
+            case CHAR:
+                return Arrays.asList(intInstance);
+            case SHORT:
+                return Arrays.asList(intInstance);
+            case BYTE:
+                return Arrays.asList(shortInstance);
+            default:
+                return Collections.emptyList();
+            }
+        }
+    }
+
+    private static class TypeFactory {
+        private TypeFactory() { }// no instances for you
+
+        public static TypeMirror instance(Class<?> c) {
+            if (c.isPrimitive()) {
+                if (c.getName().equals("void")) {
+                    return NoType.getVoidInstance();
+                } else {
+                    return PrimitiveType.instance(c);
+                }
+            } else if (c.isArray()) {
+                return new CoreReflArrayType(c);
+            } else if (c.isAnonymousClass() ||
+                       c.isLocalClass() ||
+                       c.isMemberClass() ||
+                       c.isInterface() || // covers annotations
+                       c.isEnum()) {
+                return CoreReflDeclaredType.instance(c);
+            } else { // plain old class ??
+                return CoreReflDeclaredType.instance(c);
+            }
+        }
+
+        public static TypeMirror instance(Type t) {
+            if (t instanceof Class) {
+                return instance((Class)t);
+            } else if (t instanceof ParameterizedType) {
+                ParameterizedType tmp = (ParameterizedType)t;
+                Type raw = tmp.getRawType();
+                if (!(raw instanceof Class)) {
+                    throw new IllegalArgumentException(t + " " + raw );
+                }
+                return CoreReflDeclaredType.instance((Class)raw, tmp);
+            } else if (t instanceof java.lang.reflect.WildcardType) {
+                return new ModelWildcardType((java.lang.reflect.WildcardType)t);
+            } else if (t instanceof java.lang.reflect.TypeVariable) {
+            return new CoreReflTypeVariable((java.lang.reflect.TypeVariable)t);
+            }
+            throw new IllegalArgumentException("Don't know how to make instance from: " + t.getClass());
+        }
+
+        public static TypeMirror instance(Field f) {
+            return CoreReflDeclaredType.instance(f.getType(), f.getGenericType());
+        }
+
+        public static ExecutableType instance(Method m) {
+            return new ExecutableMethodType(m);
+        }
+
+        public static javax.lang.model.type.TypeVariable typeVariableInstance(java.lang.reflect.TypeVariable<?> v) {
+            return new CoreReflTypeVariable(v);
+        }
+
+        public static javax.lang.model.type.TypeVariable typeVariableInstance(TypeMirror source,
+                                                        TypeMirror upperBound,
+                                                        TypeMirror lowerBound) {
+            return new CaptureTypeVariable(source, upperBound, lowerBound);
+        }
+    }
+
+    private static class CoreReflTypeVariable extends AbstractTypeMirror
+        implements javax.lang.model.type.TypeVariable {
+        private final java.lang.reflect.TypeVariable<?> source;
+        private boolean isCapture = false;
+
+        protected CoreReflTypeVariable(java.lang.reflect.TypeVariable<?> source) {
+            super(TypeKind.TYPEVAR);
+            Objects.requireNonNull(source);
+            this.source = source;
+        }
+
+        @Override
+        public TypeMirror getUpperBound() {
+            return new IntersectionDeclaredType(source.getBounds());
+        }
+
+        @Override
+        public TypeMirror getLowerBound() {
+            return CoreReflTypes.instance().getNullType();
+        }
+
+        @Override
+        public Element asElement() {
+            return CoreReflectionFactory.createMirror(source);
+        }
+
+        @Override
+        List<? extends TypeMirror> directSuperTypes() {
+            return ((AbstractTypeMirror)getUpperBound()).directSuperTypes();
+        }
+
+        @Override
+        public int hashCode() {
+            return source.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (other instanceof CoreReflTypeVariable) {
+                return this.source.equals(((CoreReflTypeVariable)other).source);
+            } else {
+                return false;
+            }
+        }
+    }
+}
diff --git a/langtools/test/com/sun/javadoc/AuthorDD/AuthorDD.java b/langtools/test/com/sun/javadoc/AuthorDD/AuthorDD.java
index c238abf..e65f81a 100644
--- a/langtools/test/com/sun/javadoc/AuthorDD/AuthorDD.java
+++ b/langtools/test/com/sun/javadoc/AuthorDD/AuthorDD.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -86,12 +86,12 @@
 
              // Test single @since tag:
 
-            { "<dt><span class=\"strong\">Since:</span></dt>"+NL+"  <dd>JDK 1.0</dd>",
+            { "<dt><span class=\"strong\">Since:</span></dt>"+NL+"<dd>JDK 1.0</dd>",
                                   BUGID + FS + "p1" + FS + "C1.html" },
 
             // Test multiple @author tags:
 
-            { "<dt><span class=\"strong\">Author:</span></dt>"+NL+"  <dd>Doug Kramer, Jamie, Neal</dd>",
+            { "<dt><span class=\"strong\">Author:</span></dt>"+NL+"<dd>Doug Kramer, Jamie, Neal</dd>",
                                   BUGID + FS + "p1" + FS + "C1.html" },
 
         };
diff --git a/langtools/test/com/sun/javadoc/InheritDocForUserTags/DocTest.java b/langtools/test/com/sun/javadoc/InheritDocForUserTags/DocTest.java
new file mode 100644
index 0000000..04d77e3
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/InheritDocForUserTags/DocTest.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8008768
+ * @summary Using {@inheritDoc} in simple tag defined via -tag fails
+ * @author Mike Duigou
+ * @run main DocTest
+ */
+
+import java.io.*;
+
+/**
+ * DocTest documentation.
+ *
+ * @apiNote DocTest API note.
+ * @implSpec DocTest implementation spec.
+ * @implNote DocTest implementation note.
+ */
+public class DocTest {
+    public static void main(String... args) throws Exception {
+        String[] javadoc_args = {
+            "-verbose",
+            "-d", "DocTest",
+            "-tag", "apiNote:optcm:<em>API Note</em>",
+            "-tag", "implSpec:optcm:<em>Implementation Requirements</em>:",
+            "-tag", "implNote:optcm:<em>Implementation Note</em>:",
+            "-package",
+            new File(System.getProperty("test.src"), "DocTest.java").getPath()
+        };
+
+        // javadoc does not report an exit code for an internal exception (!)
+        // so monitor stderr for stack dumps.
+        PrintStream prevErr = System.err;
+        ByteArrayOutputStream err_baos = new ByteArrayOutputStream();
+        PrintStream err_ps = new PrintStream(err_baos);
+        System.setErr(err_ps);
+
+        int rc;
+        try {
+            rc = com.sun.tools.javadoc.Main.execute(javadoc_args);
+        } finally {
+            err_ps.close();
+            System.setErr(prevErr);
+        }
+
+        String err = err_baos.toString();
+        System.err.println(err);
+
+        if (rc != 0)
+            throw new Exception("javadoc exited with rc=" + rc);
+
+        if (err.contains("at com.sun."))
+            throw new Exception("javadoc output contains stack trace");
+    }
+
+    /**
+     * DocTest() documentation.
+     *
+     * @apiNote DocTest() API note.
+     * @implSpec DocTest() implementation spec.
+     * @implNote DocTest() implementation note.
+     */
+    public DocTest() {
+    }
+
+    /**
+     * DocTest.testMethod() documentation.
+     *
+     * @apiNote DocTest.testMethod() API note.
+     * @implSpec DocTest.testMethod() implementation spec.
+     * @implNote DocTest.testMethod() implementation note.
+     */
+    public void testMethod() {
+    }
+}
+
+/**
+ * DocTestWithTags documentation.
+ *
+ * @apiNote DocTestWithTags API note.
+ * <pre>
+ *    DocTestWithTags API note code sample.
+ * </pre>
+ * @implSpec DocTestWithTags implementation spec.
+ * <pre>
+ *    DocTestWithTags implementation spec code sample.
+ * </pre>
+ * @implNote DocTestWithTags implementation note.
+ * <pre>
+ *    DocTestWithTags implementation note code sample.
+ * </pre>
+ */
+class DocTestWithTags {
+
+    /**
+     * DocTestWithTags() documentation.
+     *
+     * @apiNote DocTestWithTags() API note.
+     * <pre>
+     *    DocTestWithTags() API note code sample.
+     * </pre>
+     * @implSpec DocTestWithTags() implementation spec.
+     * <pre>
+     *    DocTestWithTags() implementation spec code sample.
+     * </pre>
+     * @implNote DocTest() implementation note.
+     * <pre>
+     *    DocTest() implementation note code sample.
+     * </pre>
+     */
+    public DocTestWithTags() {
+    }
+
+    /**
+     * DocTest.testMethod() documentation.
+     *
+     * @apiNote DocTestWithTags.testMethod() API note.
+     * <pre>
+     *    DocTestWithTags.testMethod() API note code sample.
+     * </pre>
+     * @implSpec DocTestWithTags.testMethod() implementation spec.
+     * <pre>
+     *    DocTestWithTags.testMethod() API implementation spec code sample.
+     * </pre>
+     * @implNote DocTest.testMethod() implementation note.
+     * <pre>
+     *    DocTest.testMethod() API implementation code sample.
+     * </pre>
+     */
+    public void testMethod() {
+    }
+}
+
+class MinimallyExtendsDocTest extends DocTest {
+}
+
+/**
+ * SimpleExtendsDocTest documentation.
+ */
+class SimpleExtendsDocTest extends DocTest {
+
+    /**
+     * SimpleExtendsDocTest() documentation.
+     */
+    public SimpleExtendsDocTest() {
+
+    }
+
+    /**
+     * SimpleExtendsDocTest.testMethod() documenation.
+     */
+    @java.lang.Override
+    public void testMethod() {
+    }
+}
+
+/**
+ * {@inheritDoc}
+ */
+class SimpleInheritDocDocTest extends DocTest {
+
+    /**
+     * {@inheritDoc}
+     */
+    public SimpleInheritDocDocTest() {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @java.lang.Override
+    public void testMethod() {
+    }
+}
+
+/**
+ * {@inheritDoc}
+ *
+ * @apiNote {@inheritDoc}
+ * @implSpec {@inheritDoc}
+ * @implNote {@inheritDoc}
+ */
+class FullInheritDocDocTest extends DocTest {
+
+    /**
+     * {@inheritDoc}
+     *
+     * @apiNote {@inheritDoc}
+     * @implSpec {@inheritDoc}
+     * @implNote {@inheritDoc}
+     */
+    public FullInheritDocDocTest() {
+
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @apiNote {@inheritDoc}
+     * @implSpec {@inheritDoc}
+     * @implNote {@inheritDoc}
+     */
+    @java.lang.Override
+    public void testMethod() {
+    }
+}
+
+/**
+ * {@inheritDoc} and FullInheritDocPlusDocTest documentation.
+ *
+ * @implSpec {@inheritDoc} and FullInheritDocPlusDocTest API note.
+ * @implNote {@inheritDoc} and FullInheritDocPlusDocTest implementation specification.
+ * @apiNote {@inheritDoc} and FullInheritDocPlusDocTest implementation note.
+ */
+class FullInheritDocPlusDocTest extends DocTest {
+
+    /**
+     * {@inheritDoc} and FullInheritDocPlusDocTest() documentation.
+     *
+     * @implSpec {@inheritDoc} and FullInheritDocPlusDocTest() API note.
+     * @implNote {@inheritDoc} and FullInheritDocPlusDocTest() implementation specification.
+     * @apiNote {@inheritDoc} and FullInheritDocPlusDocTest() implementation note.
+     */
+    public FullInheritDocPlusDocTest() {
+
+    }
+
+    /**
+     * {@inheritDoc} and FullInheritDocPlusDocTest.testMethod() documentation.
+     *
+     * @implSpec {@inheritDoc} and FullInheritDocPlusDocTest.testMethod() API note.
+     * @implNote {@inheritDoc} and FullInheritDocPlusDocTest.testMethod() implementation specification.
+     * @apiNote {@inheritDoc} and FullInheritDocPlusDocTest.testMethod() implementation note.
+     */
+    @java.lang.Override
+    public void testMethod() {
+    }
+}
+
diff --git a/langtools/test/com/sun/javadoc/_template/Template.java b/langtools/test/com/sun/javadoc/_template/Template.java
index 4598ce7..484a1ad 100644
--- a/langtools/test/com/sun/javadoc/_template/Template.java
+++ b/langtools/test/com/sun/javadoc/_template/Template.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -22,15 +22,13 @@
  */
 
 /*
- * test
- * @bug      0000000
- * @summary  <DESC>
- * @author   jamieh
- * @library  ../lib/
- * @ignore   This is a template for regression tests.
- * @build    JavadocTester
- * @build    <CLASS NAME>
- * @run main <CLASS NAME>
+ * @ test
+ * @ bug      <BUG-ID>
+ * @ summary  <BUG-SYNOPSIS>
+ * @ author   <AUTHOR> or delete
+ * @ library  ../lib/
+ * @ build    JavadocTester <CLASS NAME>
+ * @ run main <CLASS NAME>
  */
 
 public class Template extends JavadocTester {
diff --git a/langtools/test/com/sun/javadoc/_template/TemplateComplete.java b/langtools/test/com/sun/javadoc/_template/TemplateComplete.java
index 0aeb472..5c63487 100644
--- a/langtools/test/com/sun/javadoc/_template/TemplateComplete.java
+++ b/langtools/test/com/sun/javadoc/_template/TemplateComplete.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -22,15 +22,13 @@
  */
 
 /*
- * test
- * @bug      0000000
- * @summary  <DESC>
- * @author   jamieh
- * @library  ../lib/
- * @ignore   This is a template for regression tests.
- * @build    JavadocTester
- * @build    <CLASS NAME>
- * @run main <CLASS NAME>
+ * @ test
+ * @ bug      <BUG-ID>
+ * @ summary  <BUG-SYNOPSIS>
+ * @ author   <AUTHOR> or delete
+ * @ library  ../lib/
+ * @ build    JavadocTester <CLASS NAME>
+ * @ run main <CLASS NAME>
  */
 
 public class TemplateComplete extends JavadocTester {
diff --git a/langtools/test/com/sun/javadoc/testConstructorIndent/TestConstructorIndent.java b/langtools/test/com/sun/javadoc/testConstructorIndent/TestConstructorIndent.java
index 17b3462..2742285 100644
--- a/langtools/test/com/sun/javadoc/testConstructorIndent/TestConstructorIndent.java
+++ b/langtools/test/com/sun/javadoc/testConstructorIndent/TestConstructorIndent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,8 +47,8 @@
     private static final String[][] TEST = {
         {BUG_ID + FS + "C.html", "<div class=\"block\">" +
                  "This is just a simple constructor.</div>" + NL +
-                 "<dl><dt><span class=\"strong\">Parameters:</span></dt><dd>" +
-                 "<code>i</code> - a param.</dd></dl>"
+                 "<dl>" + NL + "<dt><span class=\"strong\">Parameters:</span></dt>" + NL +
+                 "<dd><code>i</code> - a param.</dd>" + NL +"</dl>"
         }
     };
     private static final String[][] NEGATED_TEST = NO_TEST;
diff --git a/langtools/test/com/sun/javadoc/testHref/TestHref.java b/langtools/test/com/sun/javadoc/testHref/TestHref.java
index d7952f6..297ddc6 100644
--- a/langtools/test/com/sun/javadoc/testHref/TestHref.java
+++ b/langtools/test/com/sun/javadoc/testHref/TestHref.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -70,7 +70,7 @@
         },
         //@see test.
         {BUG_ID + FS + "pkg" + FS + "C2.html",
-            "See Also:</span></dt><dd><a href=\"../pkg/C1.html#method(int, int, java.util.ArrayList)\">"
+            "See Also:</span></dt>" + NL + "<dd><a href=\"../pkg/C1.html#method(int, int, java.util.ArrayList)\">"
         },
 
         //Header does not link to the page itself.
diff --git a/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java b/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java
index 7c403e5..80d3797 100644
--- a/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java
+++ b/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java
@@ -53,64 +53,64 @@
     // serialized form should have properly nested definition list tags
     // enclosing comments, tags and deprecated information.
     private static final String[][] TEST_CMNT_DEPR = {
-        {BUG_ID + FS + "pkg1" + FS + "package-summary.html", "<dl>" +
+        {BUG_ID + FS + "pkg1" + FS + "package-summary.html", "<dl>" + NL +
                  "<dt><span class=\"strong\">Since:</span></dt>" + NL +
-                 "  <dd>JDK1.0</dd></dl>"},
-        {BUG_ID + FS + "pkg1" + FS + "C1.html", "<dl><dt><span class=\"strong\">Since:</span></dt>" + NL +
-                 "  <dd>JDK1.0</dd>" + NL + "<dt><span class=\"strong\">See Also:</span></dt>" +
+                 "<dd>JDK1.0</dd>" + NL + "</dl>"},
+        {BUG_ID + FS + "pkg1" + FS + "C1.html", "<dl>" + NL + "<dt><span class=\"strong\">Since:</span></dt>" + NL +
+                 "<dd>JDK1.0</dd>" + NL + "<dt><span class=\"strong\">See Also:</span></dt>" + NL +
                  "<dd><a href=\"../pkg1/C2.html\" title=\"class in pkg1\"><code>" +
                  "C2</code></a>, " + NL + "<a href=\"../serialized-form.html#pkg1.C1\">" +
-                 "Serialized Form</a></dd></dl>"},
-        {BUG_ID + FS + "pkg1" + FS + "C1.html", "<dl><dt><span class=\"strong\">Since:</span></dt>" + NL +
-                 "  <dd>1.4</dd>" + NL +
-                 "<dt><span class=\"strong\">See Also:</span></dt><dd>" +
+                 "Serialized Form</a></dd>" + NL + "</dl>"},
+        {BUG_ID + FS + "pkg1" + FS + "C1.html", "<dl>" + NL + "<dt><span class=\"strong\">Since:</span></dt>" + NL +
+                 "<dd>1.4</dd>" + NL +
+                 "<dt><span class=\"strong\">See Also:</span></dt>" + NL + "<dd>" +
                  "<a href=\"../pkg1/C1.html#setUndecorated(boolean)\">" +
-                 "<code>setUndecorated(boolean)</code></a></dd></dl>"},
-        {BUG_ID + FS + "pkg1" + FS + "C1.html", "<dl><dt><span class=\"strong\">Parameters:</span></dt><dd><code>title" +
-                 "</code> - the title</dd><dd><code>test</code> - boolean value" +
+                 "<code>setUndecorated(boolean)</code></a></dd>" + NL + "</dl>"},
+        {BUG_ID + FS + "pkg1" + FS + "C1.html", "<dl>"+ NL + "<dt><span class=\"strong\">Parameters:</span></dt>" + NL + "<dd><code>title" +
+                 "</code> - the title</dd>" + NL + "<dd><code>test</code> - boolean value" +
                  "</dd>" + NL + "<dt><span class=\"strong\">Throws:</span></dt>" + NL +
                  "<dd><code>java.lang.IllegalArgumentException</code> - if the " +
                  "<code>owner</code>'s" + NL +
                  "     <code>GraphicsConfiguration</code> is not from a screen " +
-                 "device</dd>" + NL + "<dd><code>HeadlessException</code></dd></dl>"},
-        {BUG_ID + FS + "pkg1" + FS + "C1.html", "<dl><dt><span class=\"strong\">Parameters:</span></dt><dd><code>undecorated" +
+                 "device</dd>" + NL + "<dd><code>HeadlessException</code></dd>" + NL + "</dl>"},
+        {BUG_ID + FS + "pkg1" + FS + "C1.html", "<dl>" + NL + "<dt><span class=\"strong\">Parameters:</span></dt>" + NL + "<dd><code>undecorated" +
                  "</code> - <code>true</code> if no decorations are" + NL +
                  "         to be enabled;" + NL + "         <code>false</code> " +
-                 "if decorations are to be enabled.</dd><dt><span class=\"strong\">Since:" +
-                 "</span></dt>" + NL + "  <dd>1.4</dd>" + NL +
-                 "<dt><span class=\"strong\">See Also:</span></dt><dd>" +
+                 "if decorations are to be enabled.</dd>" + NL + "<dt><span class=\"strong\">Since:" +
+                 "</span></dt>" + NL + "<dd>1.4</dd>" + NL +
+                 "<dt><span class=\"strong\">See Also:</span></dt>" + NL + "<dd>" +
                  "<a href=\"../pkg1/C1.html#readObject()\"><code>readObject()" +
-                 "</code></a></dd></dl>"},
-        {BUG_ID + FS + "pkg1" + FS + "C1.html", "<dl><dt><span class=\"strong\">Throws:</span></dt>" + NL +
-                 "<dd><code>java.io.IOException</code></dd><dt><span class=\"strong\">See Also:" +
-                 "</span></dt><dd><a href=\"../pkg1/C1.html#setUndecorated(boolean)\">" +
-                 "<code>setUndecorated(boolean)</code></a></dd></dl>"},
-        {BUG_ID + FS + "pkg1" + FS + "C2.html", "<dl><dt><span class=\"strong\">Parameters:" +
-                 "</span></dt><dd><code>set</code> - boolean</dd><dt><span class=\"strong\">" +
-                 "Since:</span></dt>" + NL + "  <dd>1.4</dd></dl>"},
-        {BUG_ID + FS + "serialized-form.html", "<dl><dt><span class=\"strong\">Throws:</span>" +
+                 "</code></a></dd>" + NL + "</dl>"},
+        {BUG_ID + FS + "pkg1" + FS + "C1.html", "<dl>" + NL + "<dt><span class=\"strong\">Throws:</span></dt>" + NL +
+                 "<dd><code>java.io.IOException</code></dd>" + NL + "<dt><span class=\"strong\">See Also:" +
+                 "</span></dt>" + NL + "<dd><a href=\"../pkg1/C1.html#setUndecorated(boolean)\">" +
+                 "<code>setUndecorated(boolean)</code></a></dd>" + NL + "</dl>"},
+        {BUG_ID + FS + "pkg1" + FS + "C2.html", "<dl>" + NL + "<dt><span class=\"strong\">Parameters:" +
+                 "</span></dt>" + NL + "<dd><code>set</code> - boolean</dd>" + NL + "<dt><span class=\"strong\">" +
+                 "Since:</span></dt>" + NL + "<dd>1.4</dd>" + NL + "</dl>"},
+        {BUG_ID + FS + "serialized-form.html", "<dl>" + NL + "<dt><span class=\"strong\">Throws:</span>" +
                  "</dt>" + NL + "<dd><code>" +
-                 "java.io.IOException</code></dd><dt><span class=\"strong\">See Also:</span>" +
-                 "</dt><dd><a href=\"pkg1/C1.html#setUndecorated(boolean)\">" +
-                 "<code>C1.setUndecorated(boolean)</code></a></dd></dl>"},
+                 "java.io.IOException</code></dd>" + NL + "<dt><span class=\"strong\">See Also:</span>" +
+                 "</dt>" + NL + "<dd><a href=\"pkg1/C1.html#setUndecorated(boolean)\">" +
+                 "<code>C1.setUndecorated(boolean)</code></a></dd>" + NL + "</dl>"},
         {BUG_ID + FS + "serialized-form.html", "<span class=\"strong\">Deprecated.</span>" +
                  "&nbsp;<i>As of JDK version 1.5, replaced by" + NL +
                  " <a href=\"pkg1/C1.html#setUndecorated(boolean)\">" +
                  "<code>setUndecorated(boolean)</code></a>.</i></div>" + NL +
                  "<div class=\"block\">This field indicates whether the C1 is " +
-                 "undecorated.</div>" + NL + "&nbsp;" + NL + "<dl><dt><span class=\"strong\">Since:</span></dt>" + NL +
-                 "  <dd>1.4</dd>" + NL + "<dt><span class=\"strong\">See Also:</span>" +
-                 "</dt><dd><a href=\"pkg1/C1.html#setUndecorated(boolean)\">" +
-                 "<code>C1.setUndecorated(boolean)</code></a></dd></dl>"},
+                 "undecorated.</div>" + NL + "&nbsp;" + NL + "<dl>" + NL + "<dt><span class=\"strong\">Since:</span></dt>" + NL +
+                 "<dd>1.4</dd>" + NL + "<dt><span class=\"strong\">See Also:</span>" +
+                 "</dt>" + NL + "<dd><a href=\"pkg1/C1.html#setUndecorated(boolean)\">" +
+                 "<code>C1.setUndecorated(boolean)</code></a></dd>" + NL + "</dl>"},
         {BUG_ID + FS + "serialized-form.html", "<span class=\"strong\">Deprecated.</span>" +
                  "&nbsp;<i>As of JDK version 1.5, replaced by" + NL +
                  " <a href=\"pkg1/C1.html#setUndecorated(boolean)\">" +
                  "<code>setUndecorated(boolean)</code></a>.</i></div>" + NL +
                  "<div class=\"block\">Reads the object stream.</div>" + NL +
-                 "<dl><dt><span class=\"strong\">Throws:" +
+                 "<dl>" + NL + "<dt><span class=\"strong\">Throws:" +
                  "</span></dt>" + NL + "<dd><code><code>" +
                  "IOException</code></code></dd>" + NL +
-                 "<dd><code>java.io.IOException</code></dd></dl>"},
+                 "<dd><code>java.io.IOException</code></dd>" + NL + "</dl>"},
         {BUG_ID + FS + "serialized-form.html", "<span class=\"strong\">Deprecated.</span>" +
                  "&nbsp;</div>" + NL +
                  "<div class=\"block\">The name for this class.</div>"}};
@@ -121,55 +121,55 @@
     // should display properly nested definition list tags for comments, tags
     // and deprecated information.
     private static final String[][] TEST_NODEPR = {
-        {BUG_ID + FS + "pkg1" + FS + "package-summary.html", "<dl>" +
+        {BUG_ID + FS + "pkg1" + FS + "package-summary.html", "<dl>" + NL +
                  "<dt><span class=\"strong\">Since:</span></dt>" + NL +
-                 "  <dd>JDK1.0</dd></dl>"},
-        {BUG_ID + FS + "pkg1" + FS + "C1.html", "<dl><dt><span class=\"strong\">Since:</span>" +
-                 "</dt>" + NL + "  <dd>JDK1.0</dd>" + NL + "<dt><span class=\"strong\">See Also:" +
-                 "</span></dt><dd><a href=\"../pkg1/C2.html\" title=\"class in pkg1\">" +
+                 "<dd>JDK1.0</dd>" + NL + "</dl>"},
+        {BUG_ID + FS + "pkg1" + FS + "C1.html", "<dl>" + NL + "<dt><span class=\"strong\">Since:</span>" +
+                 "</dt>" + NL + "<dd>JDK1.0</dd>" + NL + "<dt><span class=\"strong\">See Also:" +
+                 "</span></dt>" + NL + "<dd><a href=\"../pkg1/C2.html\" title=\"class in pkg1\">" +
                  "<code>C2</code></a>, " + NL + "<a href=\"../serialized-form.html#pkg1.C1\">" +
-                 "Serialized Form</a></dd></dl>"},
-        {BUG_ID + FS + "pkg1" + FS + "C1.html", "<dl><dt><span class=\"strong\">Parameters:" +
-                 "</span></dt><dd><code>title</code> - the title</dd><dd><code>" +
+                 "Serialized Form</a></dd>" + NL + "</dl>"},
+        {BUG_ID + FS + "pkg1" + FS + "C1.html", "<dl>" + NL + "<dt><span class=\"strong\">Parameters:" +
+                 "</span></dt>" + NL + "<dd><code>title</code> - the title</dd>" + NL + "<dd><code>" +
                  "test</code> - boolean value</dd>" + NL + "<dt><span class=\"strong\">Throws:" +
                  "</span></dt>" + NL + "<dd><code>java.lang.IllegalArgumentException" +
                  "</code> - if the <code>owner</code>'s" + NL + "     <code>GraphicsConfiguration" +
                  "</code> is not from a screen device</dd>" + NL + "<dd><code>" +
-                 "HeadlessException</code></dd></dl>"},
-        {BUG_ID + FS + "pkg1" + FS + "C1.html", "<dl><dt><span class=\"strong\">Parameters:" +
-                 "</span></dt><dd><code>undecorated</code> - <code>true</code>" +
+                 "HeadlessException</code></dd>" + NL + "</dl>"},
+        {BUG_ID + FS + "pkg1" + FS + "C1.html", "<dl>" + NL + "<dt><span class=\"strong\">Parameters:" +
+                 "</span></dt>" + NL + "<dd><code>undecorated</code> - <code>true</code>" +
                  " if no decorations are" + NL + "         to be enabled;" + NL +
                  "         <code>false</code> if decorations are to be enabled." +
-                 "</dd><dt><span class=\"strong\">Since:</span></dt>" + NL + "  <dd>1.4</dd>" + NL +
-                 "<dt><span class=\"strong\">See Also:</span></dt><dd><a href=\"../pkg1/C1.html#readObject()\">" +
-                 "<code>readObject()</code></a></dd></dl>"},
-        {BUG_ID + FS + "pkg1" + FS + "C1.html", "<dl><dt><span class=\"strong\">Throws:</span>" +
-                 "</dt>" + NL + "<dd><code>java.io.IOException</code></dd><dt>" +
-                 "<span class=\"strong\">See Also:</span></dt><dd><a href=\"../pkg1/C1.html#setUndecorated(boolean)\">" +
-                 "<code>setUndecorated(boolean)</code></a></dd></dl>"},
-        {BUG_ID + FS + "serialized-form.html", "<dl><dt><span class=\"strong\">Throws:</span>" +
+                 "</dd>" + NL + "<dt><span class=\"strong\">Since:</span></dt>" + NL + "<dd>1.4</dd>" + NL +
+                 "<dt><span class=\"strong\">See Also:</span></dt>" + NL + "<dd><a href=\"../pkg1/C1.html#readObject()\">" +
+                 "<code>readObject()</code></a></dd>" + NL + "</dl>"},
+        {BUG_ID + FS + "pkg1" + FS + "C1.html", "<dl>" + NL + "<dt><span class=\"strong\">Throws:</span>" +
+                 "</dt>" + NL + "<dd><code>java.io.IOException</code></dd>" + NL + "<dt>" +
+                 "<span class=\"strong\">See Also:</span></dt>" + NL + "<dd><a href=\"../pkg1/C1.html#setUndecorated(boolean)\">" +
+                 "<code>setUndecorated(boolean)</code></a></dd>" + NL + "</dl>"},
+        {BUG_ID + FS + "serialized-form.html", "<dl>" + NL + "<dt><span class=\"strong\">Throws:</span>" +
                  "</dt>" + NL + "<dd><code>" +
-                 "java.io.IOException</code></dd><dt><span class=\"strong\">See Also:</span>" +
-                 "</dt><dd><a href=\"pkg1/C1.html#setUndecorated(boolean)\">" +
-                 "<code>C1.setUndecorated(boolean)</code></a></dd></dl>"},
+                 "java.io.IOException</code></dd>" + NL + "<dt><span class=\"strong\">See Also:</span>" +
+                 "</dt>" + NL + "<dd><a href=\"pkg1/C1.html#setUndecorated(boolean)\">" +
+                 "<code>C1.setUndecorated(boolean)</code></a></dd>" + NL + "</dl>"},
         {BUG_ID + FS + "serialized-form.html", "<span class=\"strong\">Deprecated.</span>" +
                  "&nbsp;<i>As of JDK version 1.5, replaced by" + NL +
                  " <a href=\"pkg1/C1.html#setUndecorated(boolean)\">" +
                  "<code>setUndecorated(boolean)</code></a>.</i></div>" + NL +
                  "<div class=\"block\">This field indicates whether the C1 is " +
-                 "undecorated.</div>" + NL + "&nbsp;" + NL + "<dl><dt><span class=\"strong\">Since:</span></dt>" + NL +
-                 "  <dd>1.4</dd>" + NL + "<dt><span class=\"strong\">See Also:</span>" +
-                 "</dt><dd><a href=\"pkg1/C1.html#setUndecorated(boolean)\">" +
-                 "<code>C1.setUndecorated(boolean)</code></a></dd></dl>"},
+                 "undecorated.</div>" + NL + "&nbsp;" + NL + "<dl>" + NL + "<dt><span class=\"strong\">Since:</span></dt>" + NL +
+                 "<dd>1.4</dd>" + NL + "<dt><span class=\"strong\">See Also:</span>" +
+                 "</dt>" + NL + "<dd><a href=\"pkg1/C1.html#setUndecorated(boolean)\">" +
+                 "<code>C1.setUndecorated(boolean)</code></a></dd>" + NL + "</dl>"},
         {BUG_ID + FS + "serialized-form.html", "<span class=\"strong\">Deprecated.</span>" +
                  "&nbsp;<i>As of JDK version 1.5, replaced by" + NL +
                  " <a href=\"pkg1/C1.html#setUndecorated(boolean)\">" +
                  "<code>setUndecorated(boolean)</code></a>.</i></div>" + NL +
                  "<div class=\"block\">Reads the object stream.</div>" + NL +
-                 "<dl><dt><span class=\"strong\">Throws:" +
+                 "<dl>" + NL + "<dt><span class=\"strong\">Throws:" +
                  "</span></dt>" + NL + "<dd><code><code>" +
                  "IOException</code></code></dd>" + NL +
-                 "<dd><code>java.io.IOException</code></dd></dl>"},
+                 "<dd><code>java.io.IOException</code></dd>" + NL + "</dl>"},
         {BUG_ID + FS + "serialized-form.html", "<span class=\"strong\">Deprecated.</span>" +
                  "&nbsp;</div>" + NL + "<div class=\"block\">" +
                  "The name for this class.</div>"}};
diff --git a/langtools/test/com/sun/javadoc/testIndentation/TestIndentation.java b/langtools/test/com/sun/javadoc/testIndentation/TestIndentation.java
new file mode 100644
index 0000000..09a31cd
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testIndentation/TestIndentation.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug      8011288
+ * @summary  Erratic/inconsistent indentation of signatures
+ * @library  ../lib/
+ * @build    JavadocTester
+ * @run main TestIndentation
+ */
+
+public class TestIndentation extends JavadocTester {
+
+    //Test information.
+    private static final String BUG_ID = "8011288";
+
+    //Javadoc arguments.
+    private static final String[] ARGS = new String[] {
+        "-d", BUG_ID, "-sourcepath", SRC_DIR, "p"
+    };
+
+    //Input for string search tests.
+    private static final String[][] TEST = {
+        { BUG_ID + FS + "p" + FS + "Indent.html",
+          "<pre>public&nbsp;&lt;T&gt;&nbsp;void&nbsp;m(T&nbsp;t1," },
+        { BUG_ID + FS + "p" + FS + "Indent.html",
+          NL + "                  T&nbsp;t2)" },
+        { BUG_ID + FS + "p" + FS + "Indent.html",
+          NL + "           throws java.lang.Exception" }
+    };
+    private static final String[][] NEGATED_TEST = NO_TEST;
+
+    /**
+     * The entry point of the test.
+     * @param args the array of command line arguments.
+     */
+    public static void main(String[] args) {
+        TestIndentation tester = new TestIndentation();
+        run(tester, ARGS, TEST, NEGATED_TEST);
+        tester.printSummary();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugId() {
+        return BUG_ID;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugName() {
+        return getClass().getName();
+    }
+}
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java b/langtools/test/com/sun/javadoc/testIndentation/p/Indent.java
similarity index 77%
copy from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
copy to langtools/test/com/sun/javadoc/testIndentation/p/Indent.java
index 06196c2..888ad91 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
+++ b/langtools/test/com/sun/javadoc/testIndentation/p/Indent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,16 +21,8 @@
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
+package p;
 
-@GenerateNativeHeader
-public class TestClass2 {
-    byte b;
-    short s;
-    int i;
-    long l;
-    float f;
-    double d;
-    Object o;
-    String t;
+public class Indent {
+    public <T> void m(T t1, T t2) throws Exception { }
 }
diff --git a/langtools/test/com/sun/javadoc/testJavaFX/TestJavaFX.java b/langtools/test/com/sun/javadoc/testJavaFX/TestJavaFX.java
index 266abfd..d605536 100644
--- a/langtools/test/com/sun/javadoc/testJavaFX/TestJavaFX.java
+++ b/langtools/test/com/sun/javadoc/testJavaFX/TestJavaFX.java
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 7112427
+ * @bug 7112427 8012295
  * @summary Test of the JavaFX doclet features.
  * @author jvalenta
  * @library ../lib/
@@ -38,27 +38,26 @@
     private static final String[][] TEST =
         new String[][] {
             {"./" + BUG_ID + "/C.html",
-                "<dt><span class=\"strong\">See Also:</span></dt><dd><a href=\"C.html#getRate()\"><code>getRate()</code></a>, " + NL +
+                "<dt><span class=\"strong\">See Also:</span></dt>" + NL + "<dd><a href=\"C.html#getRate()\"><code>getRate()</code></a>, " + NL +
                 "<a href=\"C.html#setRate(double)\"><code>setRate(double)</code></a></dd>"},
             {"./" + BUG_ID + "/C.html",
                 "<pre>public final&nbsp;void&nbsp;setRate(double&nbsp;value)</pre>" + NL +
                 "<div class=\"block\">Sets the value of the property rate.</div>" + NL +
-                "<dl><dt><span class=\"strong\">Property description:</span></dt>" },
+                "<dl>" + NL + "<dt><span class=\"strong\">Property description:</span></dt>" },
             {"./" + BUG_ID + "/C.html",
                 "<pre>public final&nbsp;double&nbsp;getRate()</pre>" + NL +
                 "<div class=\"block\">Gets the value of the property rate.</div>" + NL +
-                "<dl><dt><span class=\"strong\">Property description:</span></dt>" },
+                "<dl>" + NL + "<dt><span class=\"strong\">Property description:</span></dt>" },
             {"./" + BUG_ID + "/C.html",
                 "<td class=\"colLast\"><code><strong><a href=\"C.html#rateProperty\">rate</a></strong></code>" + NL +
                 "<div class=\"block\">Defines the direction/speed at which the <code>Timeline</code> is expected to"},
-            {"./" + BUG_ID + "/C.html",
-                "<sub id=\"expert\">Expert tag text</sub>"},
+
             {"./" + BUG_ID + "/C.html",
                 "<span class=\"strong\">Default value:</span>"},
             {"./" + BUG_ID + "/C.html",
-                "<P>Sets the value of the property <CODE>Property</CODE>"},
+                "<p>Sets the value of the property <code>Property</code>"},
             {"./" + BUG_ID + "/C.html",
-                "<P>Gets the value of the property <CODE>Property</CODE>"},
+                "<p>Gets the value of the property <code>Property</code>"},
             {"./" + BUG_ID + "/C.html",
                 "<span class=\"strong\">Property description:</span>"},
             {"./" + BUG_ID + "/C.html",
diff --git a/langtools/test/com/sun/javadoc/testLiteralCodeInPre/TestLiteralCodeInPre.java b/langtools/test/com/sun/javadoc/testLiteralCodeInPre/TestLiteralCodeInPre.java
new file mode 100644
index 0000000..bce27a9
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testLiteralCodeInPre/TestLiteralCodeInPre.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug      8002387
+ * @summary  Improve rendered HTML formatting for {@code}
+ * @library  ../lib/
+ * @build    JavadocTester TestLiteralCodeInPre
+ * @run main TestLiteralCodeInPre
+ */
+
+public class TestLiteralCodeInPre extends JavadocTester {
+
+    //Test information.
+    private static final String BUG_ID = "8002387";
+    private static final String OUTPUT_DIR = BUG_ID;
+
+    //Javadoc arguments.
+    private static final String[] ARGS = new String[] {
+        "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-Xdoclint:none", "pkg"
+    };
+
+    //Input for string search tests.
+    private static final String[][] TEST = {
+        { BUG_ID + FS + "pkg" + FS + "Test.html",
+            "no_pre()</pre>" + NL +
+            "<div class=\"block\">abc<code>def</code>ghi</div>" },
+        { BUG_ID + FS + "pkg" + FS + "Test.html",
+            "no_pre_extra_whitespace()</pre>" + NL +
+            "<div class=\"block\">abc<code>def  </code>ghi</div>" },
+        { BUG_ID + FS + "pkg" + FS + "Test.html",
+            "in_pre()</pre>" + NL +
+            "<div class=\"block\"><pre> abc<code>  def  </code>ghi</pre></div>" },
+        { BUG_ID + FS + "pkg" + FS + "Test.html",
+            "pre_after_text()</pre>" + NL +
+            "<div class=\"block\">xyz <pre> abc<code>  def  </code>ghi</pre></div>" },
+        { BUG_ID + FS + "pkg" + FS + "Test.html",
+            "after_pre()</pre>" + NL +
+            "<div class=\"block\">xyz <pre> pqr </pre> abc<code>def  </code>ghi</div>" },
+        { BUG_ID + FS + "pkg" + FS + "Test.html",
+            "back_in_pre()</pre>" + NL +
+            "<div class=\"block\">xyz <pre> pqr </pre> mno <pre> abc<code>  def  </code>ghi</pre></div>" },
+        { BUG_ID + FS + "pkg" + FS + "Test.html",
+            "typical_usage_code()</pre>" + NL +
+            "<div class=\"block\">Lorem ipsum dolor sit amet, consectetur adipiscing elit." + NL +
+            " Example:  <pre><code>" + NL +
+            "   line 1 &lt;T&gt; void m(T t) {" + NL +
+            "   line 2     // do something with T" + NL +
+            "   line 3 }" + NL +
+            " </code></pre>" + NL +
+            " and so it goes.</div>" },
+        { BUG_ID + FS + "pkg" + FS + "Test.html",
+            "typical_usage_literal()</pre>" + NL +
+            "<div class=\"block\">Lorem ipsum dolor sit amet, consectetur adipiscing elit." + NL +
+            " Example:  <pre>" + NL +
+            "   line 1 &lt;T&gt; void m(T t) {" + NL +
+            "   line 2     // do something with T" + NL +
+            "   line 3 }" + NL +
+            " </pre>" + NL +
+            " and so it goes.</div>" },
+        { BUG_ID + FS + "pkg" + FS + "Test.html",
+            "recommended_usage_literal()</pre>" + NL +
+            "<div class=\"block\">Lorem ipsum dolor sit amet, consectetur adipiscing elit." + NL +
+            " Example:  <pre>" + NL +
+            "   line 1 &lt;T&gt; void m(T t) {" + NL +
+            "   line 2     // do something with T" + NL +
+            "   line 3 } </pre>" + NL +
+            " and so it goes.</div>" }
+    };
+
+    private static final String[][] NEGATED_TEST = NO_TEST;
+
+    /**
+     * The entry point of the test.
+     * @param args the array of command line arguments.
+     */
+    public static void main(String[] args) {
+        TestLiteralCodeInPre tester = new TestLiteralCodeInPre();
+        run(tester, ARGS, TEST, NEGATED_TEST);
+        tester.printSummary();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugId() {
+        return BUG_ID;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugName() {
+        return getClass().getName();
+    }
+}
diff --git a/langtools/test/com/sun/javadoc/testLiteralCodeInPre/pkg/Test.java b/langtools/test/com/sun/javadoc/testLiteralCodeInPre/pkg/Test.java
new file mode 100644
index 0000000..3d6fffb
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testLiteralCodeInPre/pkg/Test.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+/** */
+public class Test {
+    /**
+     * abc{@code def}ghi
+     */
+    public void no_pre() { }
+
+    /**
+     * abc{@code  def  }ghi
+     */
+    public void no_pre_extra_whitespace() { }
+
+    /**
+     * <pre> abc{@code  def  }ghi</pre>
+     */
+    public void in_pre() { }
+
+    /**
+     * xyz <pre> abc{@code  def  }ghi</pre>
+     */
+    public void pre_after_text() { }
+
+    /**
+     * xyz <pre> pqr </pre> abc{@code  def  }ghi
+     */
+    public void after_pre() { }
+
+    /**
+     * xyz <pre> pqr </pre> mno <pre> abc{@code  def  }ghi</pre>
+     */
+    public void back_in_pre() { }
+
+    /**
+     * Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+     * Example:  <pre>{@code
+     *   line 1 <T> void m(T t) {
+     *   line 2     // do something with T
+     *   line 3 }
+     * }</pre>
+     * and so it goes.
+     */
+    public void typical_usage_code() { }
+
+    /**
+     * Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+     * Example:  <pre>{@literal
+     *   line 1 <T> void m(T t) {
+     *   line 2     // do something with T
+     *   line 3 }
+     * }</pre>
+     * and so it goes.
+     */
+    public void typical_usage_literal() { }
+
+    /**
+     * Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+     * Example:  <pre>{@literal
+     *   line 1 <T> void m(T t) {
+     *   line 2     // do something with T
+     *   line 3 } }</pre>
+     * and so it goes.
+     */
+    public void recommended_usage_literal() { }
+
+    /**
+     * abc {@code
+     */
+    public void bad_code_no_content() { }
+
+    /**
+     * abc {@code abc
+     */
+    public void bad_code_content() { }
+}
diff --git a/langtools/test/com/sun/javadoc/testNestedInlineTag/testtaglets/BoldTaglet.java b/langtools/test/com/sun/javadoc/testNestedInlineTag/testtaglets/BoldTaglet.java
index c5d4912..d77ec0c 100644
--- a/langtools/test/com/sun/javadoc/testNestedInlineTag/testtaglets/BoldTaglet.java
+++ b/langtools/test/com/sun/javadoc/testNestedInlineTag/testtaglets/BoldTaglet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -55,7 +55,7 @@
     /**
      * {@inheritDoc}
      */
-    public TagletOutput getTagletOutput(Tag tag, TagletWriter writer) {
+    public Content getTagletOutput(Tag tag, TagletWriter writer) {
         ArrayList inlineTags = new ArrayList();
         inlineTags.add(new TextTag(tag.holder(), "<b>"));
         inlineTags.addAll(Arrays.asList(tag.inlineTags()));
diff --git a/langtools/test/com/sun/javadoc/testNestedInlineTag/testtaglets/GreenTaglet.java b/langtools/test/com/sun/javadoc/testNestedInlineTag/testtaglets/GreenTaglet.java
index 129c020..719d01c 100644
--- a/langtools/test/com/sun/javadoc/testNestedInlineTag/testtaglets/GreenTaglet.java
+++ b/langtools/test/com/sun/javadoc/testNestedInlineTag/testtaglets/GreenTaglet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -57,7 +57,7 @@
     /**
      * {@inheritDoc}
      */
-    public TagletOutput getTagletOutput(Tag tag, TagletWriter writer) {
+    public Content getTagletOutput(Tag tag, TagletWriter writer) {
         ArrayList inlineTags = new ArrayList();
         inlineTags.add(new TextTag(tag.holder(), "<font color=\"green\">"));
         inlineTags.addAll(Arrays.asList(tag.inlineTags()));
diff --git a/langtools/test/com/sun/javadoc/testNestedInlineTag/testtaglets/UnderlineTaglet.java b/langtools/test/com/sun/javadoc/testNestedInlineTag/testtaglets/UnderlineTaglet.java
index 2cee071..ad422bc 100644
--- a/langtools/test/com/sun/javadoc/testNestedInlineTag/testtaglets/UnderlineTaglet.java
+++ b/langtools/test/com/sun/javadoc/testNestedInlineTag/testtaglets/UnderlineTaglet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -57,7 +57,7 @@
     /**
      * {@inheritDoc}
      */
-    public TagletOutput getTagletOutput(Tag tag, TagletWriter writer) {
+    public Content getTagletOutput(Tag tag, TagletWriter writer) {
         ArrayList inlineTags = new ArrayList();
         inlineTags.add(new TextTag(tag.holder(), "<u>"));
         inlineTags.addAll(Arrays.asList(tag.inlineTags()));
diff --git a/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java b/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java
index cc66945..db5c2f2 100644
--- a/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java
+++ b/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java
@@ -80,21 +80,21 @@
                 "Class TypeParameters&lt;E&gt;</h2>"},
             //Check class type parameters section.
             {BUG_ID + FS + "pkg" + FS + "TypeParameters.html",
-                "<dt><span class=\"strong\">Type Parameters:</span></dt><dd><code>E</code> - " +
+                "<dt><span class=\"strong\">Type Parameters:</span></dt>" + NL + "<dd><code>E</code> - " +
                 "the type parameter for this class."},
             //Type parameters in @see/@link
             {BUG_ID + FS + "pkg" + FS + "TypeParameters.html",
-                "<dl><dt><span class=\"strong\">See Also:</span></dt><dd>" +
+                "<dl>" + NL + "<dt><span class=\"strong\">See Also:</span></dt>" + NL + "<dd>" +
                 "<a href=\"../pkg/TypeParameters.html\" title=\"class in pkg\">" +
-                "<code>TypeParameters</code></a></dd></dl>"},
+                "<code>TypeParameters</code></a></dd>" + NL + "</dl>"},
             //Method that uses class type parameter.
             {BUG_ID + FS + "pkg" + FS + "TypeParameters.html",
                 "(<a href=\"../pkg/TypeParameters.html\" title=\"type " +
                     "parameter in TypeParameters\">E</a>&nbsp;param)"},
             //Method type parameter section.
             {BUG_ID + FS + "pkg" + FS + "TypeParameters.html",
-                "<span class=\"strong\">Type Parameters:</span></dt><dd><code>T</code> - This is the first " +
-                    "type parameter.</dd><dd><code>V</code> - This is the second type " +
+                "<span class=\"strong\">Type Parameters:</span></dt>" + NL + "<dd><code>T</code> - This is the first " +
+                    "type parameter.</dd>" + NL + "<dd><code>V</code> - This is the second type " +
                     "parameter."},
             //Signature of method with type parameters
             {BUG_ID + FS + "pkg" + FS + "TypeParameters.html",
@@ -235,8 +235,8 @@
                 "@AnnotationType</a>(<a href=\"../pkg/AnnotationType.html#optional()\">" +
                 "optional</a>=\"Parameter Annotation\",<a " +
                 "href=\"../pkg/AnnotationType.html#required()\">required</a>=1994)" + NL +
-                "                    int&nbsp;documented," + NL +
-                "                    int&nbsp;undocmented)</pre>"},
+                "                             int&nbsp;documented," + NL +
+                "                             int&nbsp;undocmented)</pre>"},
 
             //CONSTRUCTOR PARAMS
             {BUG_ID + FS + "pkg" + FS + "AnnotationTypeUsage.html",
@@ -245,8 +245,8 @@
                 "@AnnotationType</a>(<a href=\"../pkg/AnnotationType.html#optional()\">" +
                 "optional</a>=\"Constructor Param Annotation\",<a " +
                 "href=\"../pkg/AnnotationType.html#required()\">required</a>=1994)" + NL +
-                "                   int&nbsp;documented," + NL +
-                "                   int&nbsp;undocmented)</pre>"},
+                "                           int&nbsp;documented," + NL +
+                "                           int&nbsp;undocmented)</pre>"},
 
             //=================================
             // ANNOTATION TYPE USAGE TESTING (All Different Types).
@@ -306,7 +306,7 @@
             // Handle multiple bounds.
             //==============================================================
             {BUG_ID + FS + "pkg" + FS + "MultiTypeParameters.html",
-                "public&nbsp;&lt;T extends java.lang.Number & java.lang.Runnable&gt;&nbsp;T&nbsp;foo(T&nbsp;t)"},
+                "public&nbsp;&lt;T extends java.lang.Number &amp; java.lang.Runnable&gt;&nbsp;T&nbsp;foo(T&nbsp;t)"},
 
             //==============================================================
             // Test Class-Use Documenation for Type Parameters.
@@ -323,7 +323,7 @@
                      "<td class=\"colLast\"><code><strong><a href=\"../../pkg2/ClassUseTest1.html\" " +
                      "title=\"class in pkg2\">ClassUseTest1</a>&lt;T extends " +
                      "<a href=\"../../pkg2/Foo.html\" title=\"class in pkg2\">Foo" +
-                     "</a> & <a href=\"../../pkg2/Foo2.html\" title=\"interface in pkg2\">" +
+                     "</a> &amp; <a href=\"../../pkg2/Foo2.html\" title=\"interface in pkg2\">" +
                      "Foo2</a>&gt;</strong></code>&nbsp;</td>"
             },
             {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo.html",
@@ -375,7 +375,7 @@
                     "<td class=\"colLast\"><code><strong><a href=\"../../pkg2/ClassUseTest1.html\" " +
                      "title=\"class in pkg2\">ClassUseTest1</a>&lt;T extends " +
                      "<a href=\"../../pkg2/Foo.html\" title=\"class in pkg2\">Foo" +
-                     "</a> & <a href=\"../../pkg2/Foo2.html\" title=\"interface in pkg2\">" +
+                     "</a> &amp; <a href=\"../../pkg2/Foo2.html\" title=\"interface in pkg2\">" +
                      "Foo2</a>&gt;</strong></code>&nbsp;</td>"
            },
            {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo2.html",
@@ -443,7 +443,7 @@
                      "<td class=\"colFirst\"><code>&lt;T extends <a href=\"../" +
                      "../pkg2/ParamTest.html\" title=\"class in pkg2\">ParamTest" +
                      "</a>&lt;<a href=\"../../pkg2/Foo3.html\" title=\"class in " +
-                     "pkg2\">Foo3</a>&gt;&gt;&nbsp;<br><a href=\"../../pkg2/" +
+                     "pkg2\">Foo3</a>&gt;&gt;<br><a href=\"../../pkg2/" +
                      "ParamTest.html\" title=\"class in pkg2\">ParamTest</a>" +
                      "&lt;<a href=\"../../pkg2/Foo3.html\" title=\"class in " +
                      "pkg2\">Foo3</a>&gt;</code></td>"
@@ -486,7 +486,7 @@
                      "<td class=\"colFirst\"><code>&lt;T extends <a href=\"../../" +
                      "pkg2/ParamTest.html\" title=\"class in pkg2\">ParamTest</a>&lt;" +
                      "<a href=\"../../pkg2/Foo3.html\" title=\"class in pkg2\">Foo3" +
-                     "</a>&gt;&gt;&nbsp;<br><a href=\"../../pkg2/ParamTest.html\" " +
+                     "</a>&gt;&gt;<br><a href=\"../../pkg2/ParamTest.html\" " +
                      "title=\"class in pkg2\">ParamTest</a>&lt;<a href=\"../../pkg2/" +
                      "Foo3.html\" title=\"class in pkg2\">Foo3</a>&gt;</code></td>"
             },
@@ -524,7 +524,7 @@
                      "../pkg2/ParamTest2.html\" title=\"class in pkg2\">" +
                      "ParamTest2</a>&lt;java.util.List&lt;? extends <a href=\".." +
                      "/../pkg2/Foo4.html\" title=\"class in pkg2\">Foo4</a>&gt;" +
-                     "&gt;&gt;&nbsp;<br><a href=\"../../pkg2/ParamTest2.html\" " +
+                     "&gt;&gt;<br><a href=\"../../pkg2/ParamTest2.html\" " +
                      "title=\"class in pkg2\">ParamTest2</a>&lt;java.util.List" +
                      "&lt;? extends <a href=\"../../pkg2/Foo4.html\" title=\"" +
                      "class in pkg2\">Foo4</a>&gt;&gt;</code></td>"
@@ -569,7 +569,7 @@
                      "../pkg2/ParamTest2.html\" title=\"class in pkg2\">" +
                      "ParamTest2</a>&lt;java.util.List&lt;? extends <a href=\".." +
                      "/../pkg2/Foo4.html\" title=\"class in pkg2\">Foo4</a>&gt;" +
-                     "&gt;&gt;&nbsp;<br><a href=\"../../pkg2/ParamTest2.html\" " +
+                     "&gt;&gt;<br><a href=\"../../pkg2/ParamTest2.html\" " +
                      "title=\"class in pkg2\">ParamTest2</a>&lt;java.util.List" +
                      "&lt;? extends <a href=\"../../pkg2/Foo4.html\" title=\"" +
                      "class in pkg2\">Foo4</a>&gt;&gt;</code></td>"
diff --git a/langtools/test/com/sun/javadoc/testParamTaglet/TestParamTaglet.java b/langtools/test/com/sun/javadoc/testParamTaglet/TestParamTaglet.java
index 3def6b8..2271539 100644
--- a/langtools/test/com/sun/javadoc/testParamTaglet/TestParamTaglet.java
+++ b/langtools/test/com/sun/javadoc/testParamTaglet/TestParamTaglet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -48,13 +48,13 @@
     private static final String[][] TEST = {
         //Regular param tags.
         {BUG_ID + FS + "pkg" + FS + "C.html",
-            "<span class=\"strong\">Parameters:</span></dt><dd><code>param1</code> - testing 1 2 3.</dd>" +
-                "<dd><code>param2</code> - testing 1 2 3."
+            "<span class=\"strong\">Parameters:</span></dt>" + NL + "<dd><code>param1</code> - testing 1 2 3.</dd>" +
+                NL + "<dd><code>param2</code> - testing 1 2 3."
         },
         //Param tags that don't match with any real parameters.
         {BUG_ID + FS + "pkg" + FS + "C.html",
-            "<span class=\"strong\">Parameters:</span></dt><dd><code><I>p1</I></code> - testing 1 2 3.</dd>" +
-                "<dd><code><I>p2</I></code> - testing 1 2 3."
+            "<span class=\"strong\">Parameters:</span></dt>" + NL + "<dd><code><I>p1</I></code> - testing 1 2 3.</dd>" +
+                NL + "<dd><code><I>p2</I></code> - testing 1 2 3."
         },
         //{@inherit} doc misuse does not cause doclet to throw exception.
         // Param is printed with nothing inherited.
diff --git a/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/TestSerializedFormDeprecationInfo.java b/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/TestSerializedFormDeprecationInfo.java
index 4a2a1cc..fd026b9 100644
--- a/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/TestSerializedFormDeprecationInfo.java
+++ b/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/TestSerializedFormDeprecationInfo.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -41,29 +41,29 @@
     // Test for normal run of javadoc. The serialized-form.html should
     // display the inline comments, tags and deprecation information if any.
     private static final String[][] TEST_CMNT_DEPR = {
-        {BUG_ID + FS + "serialized-form.html", "<dl>" +
+        {BUG_ID + FS + "serialized-form.html", "<dl>" + NL +
                  "<dt><span class=\"strong\">Throws:</span></dt>" + NL + "<dd><code>" +
-                 "java.io.IOException</code></dd><dt><span class=\"strong\">See Also:</span>" +
-                 "</dt><dd><a href=\"pkg1/C1.html#setUndecorated(boolean)\">" +
-                 "<code>C1.setUndecorated(boolean)</code></a></dd></dl>"},
+                 "java.io.IOException</code></dd>"+ NL + "<dt><span class=\"strong\">See Also:</span>" +
+                 "</dt>" + NL + "<dd><a href=\"pkg1/C1.html#setUndecorated(boolean)\">" +
+                 "<code>C1.setUndecorated(boolean)</code></a></dd>" + NL + "</dl>"},
         {BUG_ID + FS + "serialized-form.html", "<span class=\"strong\">Deprecated.</span>" +
                  "&nbsp;<i>As of JDK version 1.5, replaced by" + NL +
                  " <a href=\"pkg1/C1.html#setUndecorated(boolean)\">" +
                  "<code>setUndecorated(boolean)</code></a>.</i></div>" + NL +
                  "<div class=\"block\">This field indicates whether the C1 " +
                  "is undecorated.</div>" + NL + "&nbsp;" + NL +
-                 "<dl><dt><span class=\"strong\">Since:</span></dt>" + NL +
-                 "  <dd>1.4</dd>" + NL + "<dt><span class=\"strong\">See Also:</span>" +
-                 "</dt><dd><a href=\"pkg1/C1.html#setUndecorated(boolean)\">" +
-                 "<code>C1.setUndecorated(boolean)</code></a></dd></dl>"},
+                 "<dl>" + NL + "<dt><span class=\"strong\">Since:</span></dt>" + NL +
+                 "<dd>1.4</dd>" + NL + "<dt><span class=\"strong\">See Also:</span>" +
+                 "</dt>" + NL + "<dd><a href=\"pkg1/C1.html#setUndecorated(boolean)\">" +
+                 "<code>C1.setUndecorated(boolean)</code></a></dd>" + NL + "</dl>"},
         {BUG_ID + FS + "serialized-form.html", "<span class=\"strong\">Deprecated.</span>" +
                  "&nbsp;<i>As of JDK version 1.5, replaced by" + NL +
                  " <a href=\"pkg1/C1.html#setUndecorated(boolean)\">" +
                  "<code>setUndecorated(boolean)</code></a>.</i></div>" + NL +
                  "<div class=\"block\">Reads the object stream.</div>" + NL +
-                 "<dl><dt><span class=\"strong\">Throws:</span></dt>" + NL + "<dd><code><code>" +
+                 "<dl>" + NL + "<dt><span class=\"strong\">Throws:</span></dt>" + NL + "<dd><code><code>" +
                  "IOException</code></code></dd>" + NL +
-                 "<dd><code>java.io.IOException</code></dd></dl>"},
+                 "<dd><code>java.io.IOException</code></dd>" + NL + "</dl>"},
         {BUG_ID + FS + "serialized-form.html", "<span class=\"strong\">Deprecated.</span>" +
                  "&nbsp;</div>" + NL + "<div class=\"block\">" +
                  "The name for this class.</div>"}};
diff --git a/langtools/test/com/sun/javadoc/testSimpleTagInherit/TestSimpleTagInherit.java b/langtools/test/com/sun/javadoc/testSimpleTagInherit/TestSimpleTagInherit.java
new file mode 100644
index 0000000..4b5ac23
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testSimpleTagInherit/TestSimpleTagInherit.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug      8008768
+ * @summary  Using {@inheritDoc} in simple tag defined via -tag fails
+ * @library  ../lib/
+ * @build    JavadocTester TestSimpleTagInherit
+ * @run main TestSimpleTagInherit
+ */
+
+public class TestSimpleTagInherit extends JavadocTester {
+
+    //Test information.
+    private static final String BUG_ID = "8008768";
+    private static final String OUTPUT_DIR = BUG_ID;
+
+    //Javadoc arguments.
+    private static final String[] ARGS = new String[] {
+        "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR,
+        "-tag", "custom:optcm:<em>Custom:</em>",
+        "p"
+    };
+
+    //Input for string search tests.
+    private static final String[][] TEST = {
+        { BUG_ID + FS + "p" + FS + "TestClass.html",
+          "<dt><span class=\"strong\"><em>Custom:</em></span></dt>" + NL +
+          "<dd>doc for BaseClass class</dd>" },
+        { BUG_ID + FS + "p" + FS + "TestClass.html",
+          "<dt><span class=\"strong\"><em>Custom:</em></span></dt>" + NL +
+          "<dd>doc for BaseClass method</dd>" }
+    };
+    private static final String[][] NEGATED_TEST = NO_TEST;
+
+    /**
+     * The entry point of the test.
+     * @param args the array of command line arguments.
+     */
+    public static void main(String[] args) {
+        TestSimpleTagInherit tester = new TestSimpleTagInherit();
+        run(tester, ARGS, TEST, NEGATED_TEST);
+        tester.printSummary();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugId() {
+        return BUG_ID;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugName() {
+        return getClass().getName();
+    }
+}
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java b/langtools/test/com/sun/javadoc/testSimpleTagInherit/p/BaseClass.java
similarity index 77%
copy from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
copy to langtools/test/com/sun/javadoc/testSimpleTagInherit/p/BaseClass.java
index 06196c2..c7a6e17 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
+++ b/langtools/test/com/sun/javadoc/testSimpleTagInherit/p/BaseClass.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,16 +21,14 @@
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
+package p;
 
-@GenerateNativeHeader
-public class TestClass2 {
-    byte b;
-    short s;
-    int i;
-    long l;
-    float f;
-    double d;
-    Object o;
-    String t;
+/**
+ * @custom doc for BaseClass class
+ */
+public class BaseClass {
+    /**
+     * @custom doc for BaseClass method
+     */
+    public void m() { }
 }
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java b/langtools/test/com/sun/javadoc/testSimpleTagInherit/p/TestClass.java
similarity index 77%
copy from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
copy to langtools/test/com/sun/javadoc/testSimpleTagInherit/p/TestClass.java
index 06196c2..80c1001 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
+++ b/langtools/test/com/sun/javadoc/testSimpleTagInherit/p/TestClass.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,16 +21,14 @@
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
+package p;
 
-@GenerateNativeHeader
-public class TestClass2 {
-    byte b;
-    short s;
-    int i;
-    long l;
-    float f;
-    double d;
-    Object o;
-    String t;
+/**
+ * @custom {@inheritDoc}
+ */
+public class TestClass extends BaseClass {
+    /**
+     * @custom {@inheritDoc}
+     */
+    public void m() { }
 }
diff --git a/langtools/test/com/sun/javadoc/testSinceTag/TestSinceTag.java b/langtools/test/com/sun/javadoc/testSinceTag/TestSinceTag.java
index c340431..531047c 100644
--- a/langtools/test/com/sun/javadoc/testSinceTag/TestSinceTag.java
+++ b/langtools/test/com/sun/javadoc/testSinceTag/TestSinceTag.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -48,12 +48,12 @@
     //Input for string search tests.
     private static final String[][] TEST = {
         {BUG_ID + FS + "pkg1" + FS + "C1.html",
-            "<dl><dt><span class=\"strong\">Since:</span></dt>" + NL +
-            "  <dd>JDK1.0</dd>"
+            "<dl>" + NL + "<dt><span class=\"strong\">Since:</span></dt>" + NL +
+            "<dd>JDK1.0</dd>"
         },
         {BUG_ID + FS + "serialized-form.html",
-            "<dl><dt><span class=\"strong\">Since:</span></dt>" + NL +
-            "  <dd>1.4</dd>"
+            "<dl>" + NL + "<dt><span class=\"strong\">Since:</span></dt>" + NL +
+            "<dd>1.4</dd>"
         }
     };
 
diff --git a/langtools/test/com/sun/javadoc/testTaglets/taglets/Foo.java b/langtools/test/com/sun/javadoc/testTaglets/taglets/Foo.java
index e28c452..b0b7e47 100644
--- a/langtools/test/com/sun/javadoc/testTaglets/taglets/Foo.java
+++ b/langtools/test/com/sun/javadoc/testTaglets/taglets/Foo.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -48,7 +48,7 @@
     /**
      * {@inheritDoc}
      */
-    public TagletOutput getTagletOutput(Tag tag, TagletWriter writer) {
+    public Content getTagletOutput(Tag tag, TagletWriter writer) {
         ArrayList inlineTags = new ArrayList();
         inlineTags.add(new TextTag(tag.holder(), "<dt><span class=\"strong\">Foo:</span></dt><dd>"));
         inlineTags.addAll(Arrays.asList(tag.inlineTags()));
diff --git a/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java b/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java
index db86f6b..1d3baaa 100644
--- a/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java
+++ b/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java
@@ -45,7 +45,6 @@
     private static final String[][] NEGATED_TEST = NO_TEST;
     private static final String[][] TEST = {
         // Test for type annotations on Class Extends (ClassExtends.java).
-        /* @ignore 8012173
         {BUG_ID + FS + "typeannos" + FS + "MyClass.html",
             "extends <a href=\"../typeannos/ClassExtA.html\" title=\"annotation " +
             "in typeannos\">@ClassExtA</a> <a href=\"../typeannos/ParameterizedClass.html\" " +
@@ -53,8 +52,6 @@
             "../typeannos/ClassExtB.html\" title=\"annotation in typeannos\">" +
             "@ClassExtB</a> java.lang.String&gt;"
         },
-        */
-        /* @ignore 8012173
         {BUG_ID + FS + "typeannos" + FS + "MyClass.html",
             "implements <a href=\"../typeannos/ClassExtB.html\" title=\"" +
             "annotation in typeannos\">@ClassExtB</a> java.lang.CharSequence, " +
@@ -64,8 +61,6 @@
             "<a href=\"../typeannos/ClassExtB.html\" title=\"annotation in " +
             "typeannos\">@ClassExtB</a> java.lang.String&gt;</pre>"
         },
-        */
-        /* @ignore 8012173
         {BUG_ID + FS + "typeannos" + FS + "MyInterface.html",
             "extends <a href=\"../typeannos/ClassExtA.html\" title=\"annotation " +
             "in typeannos\">@ClassExtA</a> <a href=\"../typeannos/" +
@@ -75,7 +70,6 @@
             "<a href=\"../typeannos/ClassExtB.html\" title=\"annotation in " +
             "typeannos\">@ClassExtB</a> java.lang.CharSequence</pre>"
         },
-        */
 
         // Test for type annotations on Class Parameters (ClassParameters.java).
         {BUG_ID + FS + "typeannos" + FS + "ExtendsBound.html",
@@ -83,7 +77,6 @@
             "href=\"../typeannos/ClassParamA.html\" title=\"annotation in " +
             "typeannos\">@ClassParamA</a> java.lang.String&gt;</span>"
         },
-        /* @ignore 8012173
         {BUG_ID + FS + "typeannos" + FS + "ExtendsGeneric.html",
             "<pre> class <span class=\"strong\">ExtendsGeneric&lt;K extends " +
             "<a href=\"../typeannos/ClassParamA.html\" title=\"annotation in " +
@@ -92,7 +85,6 @@
             "../typeannos/ClassParamB.html\" title=\"annotation in typeannos\">" +
             "@ClassParamB</a> java.lang.String&gt;&gt;</span>"
         },
-        */
         {BUG_ID + FS + "typeannos" + FS + "TwoBounds.html",
             "<pre> class <span class=\"strong\">TwoBounds&lt;K extends <a href=\"" +
             "../typeannos/ClassParamA.html\" title=\"annotation in typeannos\">" +
@@ -103,23 +95,22 @@
         {BUG_ID + FS + "typeannos" + FS + "Complex1.html",
             "class <span class=\"strong\">Complex1&lt;K extends <a href=\"../" +
             "typeannos/ClassParamA.html\" title=\"annotation in typeannos\">" +
-            "@ClassParamA</a> java.lang.String & java.lang.Runnable&gt;</span>"
+            "@ClassParamA</a> java.lang.String &amp; java.lang.Runnable&gt;</span>"
         },
         {BUG_ID + FS + "typeannos" + FS + "Complex2.html",
             "class <span class=\"strong\">Complex2&lt;K extends java.lang." +
-            "String & <a href=\"../typeannos/ClassParamB.html\" title=\"" +
+            "String &amp; <a href=\"../typeannos/ClassParamB.html\" title=\"" +
             "annotation in typeannos\">@ClassParamB</a> java.lang.Runnable&gt;</span>"
         },
         {BUG_ID + FS + "typeannos" + FS + "ComplexBoth.html",
             "class <span class=\"strong\">ComplexBoth&lt;K extends <a href=\"" +
             "../typeannos/ClassParamA.html\" title=\"annotation in typeannos\"" +
-            ">@ClassParamA</a> java.lang.String & <a href=\"../typeannos/" +
+            ">@ClassParamA</a> java.lang.String &amp; <a href=\"../typeannos/" +
             "ClassParamA.html\" title=\"annotation in typeannos\">@ClassParamA" +
             "</a> java.lang.Runnable&gt;</span>"
         },
 
         // Test for type annotations on fields (Fields.java).
-        /* @ignore 8012173
         {BUG_ID + FS + "typeannos" + FS + "DefaultScope.html",
             "<pre><a href=\"../typeannos/Parameterized.html\" title=\"class in " +
             "typeannos\">Parameterized</a>&lt;<a href=\"../typeannos/FldA.html\" " +
@@ -127,7 +118,6 @@
             "href=\"../typeannos/FldB.html\" title=\"annotation in typeannos\">" +
             "@FldB</a> java.lang.String&gt; bothTypeArgs</pre>"
         },
-        */
         {BUG_ID + FS + "typeannos" + FS + "DefaultScope.html",
             "<pre><a href=\"../typeannos/FldA.html\" title=\"annotation in " +
             "typeannos\">@FldA</a> java.lang.String <a href=\"../typeannos/" +
@@ -147,7 +137,6 @@
             "typeannos\">@FldC</a> <a href=\"../typeannos/FldB.html\" title=\"" +
             "annotation in typeannos\">@FldB</a> [] array2Deep</pre>"
         },
-        /* @ignore 8012173
         {BUG_ID + FS + "typeannos" + FS + "ModifiedScoped.html",
             "<pre>public final&nbsp;<a href=\"../typeannos/Parameterized.html\" " +
             "title=\"class in typeannos\">Parameterized</a>&lt;<a href=\"../" +
@@ -160,7 +149,6 @@
             "title=\"annotation in typeannos\">@FldB</a> java.lang.String&gt; " +
             "nestedParameterized</pre>"
         },
-        */
         {BUG_ID + FS + "typeannos" + FS + "ModifiedScoped.html",
             "<pre>public final&nbsp;<a href=\"../typeannos/FldA.html\" " +
             "title=\"annotation in typeannos\">@FldA</a> java.lang.String[][] " +
@@ -184,7 +172,6 @@
             "<pre><a href=\"../typeannos/MRtnA.html\" title=\"annotation in " +
             "typeannos\">@MRtnA</a> java.lang.String[][]&nbsp;array2()</pre>"
         },
-        /* @ignore 8012173
         {BUG_ID + FS + "typeannos" + FS + "MtdModifiedScoped.html",
             "<pre>public final&nbsp;<a href=\"../typeannos/MtdParameterized.html\" " +
             "title=\"class in typeannos\">MtdParameterized</a>&lt;<a href=\"../" +
@@ -197,7 +184,6 @@
             "MRtnB.html\" title=\"annotation in typeannos\">@MRtnB</a> java." +
             "lang.String&gt;&nbsp;nestedMtdParameterized()</pre>"
         },
-        */
 
         // Test for type annotations on method type parameters (MethodTypeParameters.java).
         {BUG_ID + FS + "typeannos" + FS + "UnscopedUnmodified.html",
@@ -205,7 +191,6 @@
             "annotation in typeannos\">@MTyParamA</a> java.lang.String&gt;" +
             "&nbsp;void&nbsp;methodExtends()</pre>"
         },
-        /* @ignore 8012173
         {BUG_ID + FS + "typeannos" + FS + "UnscopedUnmodified.html",
             "<pre>&lt;K extends <a href=\"../typeannos/MTyParamA.html\" title=\"" +
             "annotation in typeannos\">@MTyParamA</a> <a href=\"../typeannos/" +
@@ -214,13 +199,11 @@
             "title=\"annotation in typeannos\">@MTyParamB</a> java.lang.String" +
             "&gt;&gt;&nbsp;void&nbsp;nestedExtends()</pre>"
         },
-        */
         {BUG_ID + FS + "typeannos" + FS + "PublicModifiedMethods.html",
             "<pre>public final&nbsp;&lt;K extends <a href=\"../typeannos/" +
             "MTyParamA.html\" title=\"annotation in typeannos\">@MTyParamA</a> " +
             "java.lang.String&gt;&nbsp;void&nbsp;methodExtends()</pre>"
         },
-        /* @ignore 8012173
         {BUG_ID + FS + "typeannos" + FS + "PublicModifiedMethods.html",
             "<pre>public final&nbsp;&lt;K extends <a href=\"../typeannos/" +
             "MTyParamA.html\" title=\"annotation in typeannos\">@MTyParamA</a> " +
@@ -231,7 +214,6 @@
             "title=\"annotation in typeannos\">@MTyParamB</a> java.lang.String" +
             "&gt;&gt;&nbsp;void&nbsp;dual()</pre>"
         },
-        */
 
         // Test for type annotations on parameters (Parameters.java).
         {BUG_ID + FS + "typeannos" + FS + "Parameters.html",
@@ -240,7 +222,6 @@
             "ParaParameterized</a>&lt;java.lang.String,java.lang.String&gt;" +
             "&nbsp;a)</pre>"
         },
-        /* @ignore 8012173
         {BUG_ID + FS + "typeannos" + FS + "Parameters.html",
             "<pre>void&nbsp;nestedParaParameterized(<a href=\"../typeannos/" +
             "ParaParameterized.html\" title=\"class in typeannos\">" +
@@ -254,7 +235,6 @@
             "typeannos/ParamB.html\" title=\"annotation in typeannos\">@ParamB" +
             "</a> java.lang.String&gt;&nbsp;a)</pre>"
         },
-        */
         {BUG_ID + FS + "typeannos" + FS + "Parameters.html",
             "<pre>void&nbsp;array2Deep(<a href=\"../typeannos/ParamA.html\" " +
             "title=\"annotation in typeannos\">@ParamA</a> java.lang.String " +
@@ -266,14 +246,14 @@
         // Test for type annotations on throws (Throws.java).
         {BUG_ID + FS + "typeannos" + FS + "ThrDefaultUnmodified.html",
             "<pre>void&nbsp;oneException()" + NL +
-            "            throws <a href=\"../typeannos/ThrA.html\" title=\"" +
+            "           throws <a href=\"../typeannos/ThrA.html\" title=\"" +
             "annotation in typeannos\">@ThrA</a> java.lang.Exception</pre>"
         },
         {BUG_ID + FS + "typeannos" + FS + "ThrDefaultUnmodified.html",
             "<pre>void&nbsp;twoExceptions()" + NL +
-            "             throws <a href=\"../typeannos/ThrA.html\" title=\"" +
+            "            throws <a href=\"../typeannos/ThrA.html\" title=\"" +
             "annotation in typeannos\">@ThrA</a> java.lang.RuntimeException," + NL +
-            "                    <a href=\"../typeannos/ThrA.html\" title=\"" +
+            "                   <a href=\"../typeannos/ThrA.html\" title=\"" +
             "annotation in typeannos\">@ThrA</a> java.lang.Exception</pre>"
         },
         {BUG_ID + FS + "typeannos" + FS + "ThrPublicModified.html",
@@ -290,16 +270,16 @@
         },
         {BUG_ID + FS + "typeannos" + FS + "ThrWithValue.html",
             "<pre>void&nbsp;oneException()" + NL +
-            "            throws <a href=\"../typeannos/ThrB.html\" title=\"" +
+            "           throws <a href=\"../typeannos/ThrB.html\" title=\"" +
             "annotation in typeannos\">@ThrB</a>(<a href=\"../typeannos/" +
             "ThrB.html#value()\">value</a>=\"m\") java.lang.Exception</pre>"
         },
         {BUG_ID + FS + "typeannos" + FS + "ThrWithValue.html",
             "<pre>void&nbsp;twoExceptions()" + NL +
-            "             throws <a href=\"../typeannos/ThrB.html\" title=\"" +
+            "            throws <a href=\"../typeannos/ThrB.html\" title=\"" +
             "annotation in typeannos\">@ThrB</a>(<a href=\"../typeannos/" +
             "ThrB.html#value()\">value</a>=\"m\") java.lang.RuntimeException," + NL +
-            "                    <a href=\"../typeannos/ThrA.html\" title=\"" +
+            "                   <a href=\"../typeannos/ThrA.html\" title=\"" +
             "annotation in typeannos\">@ThrA</a> java.lang.Exception</pre>"
         },
 
@@ -342,7 +322,7 @@
         {BUG_ID + FS + "typeannos" + FS + "DefaultUnmodified.html",
             "<pre>void&nbsp;withException(<a href=\"../typeannos/RcvrA.html\" " +
             "title=\"annotation in typeannos\">@RcvrA</a>&nbsp;" +
-            "DefaultUnmodified&nbsp;this)" + NL + "             throws java." +
+            "DefaultUnmodified&nbsp;this)" + NL + "            throws java." +
             "lang.Exception</pre>"
         },
         {BUG_ID + FS + "typeannos" + FS + "DefaultUnmodified.html",
@@ -356,8 +336,8 @@
             "<pre>&lt;T extends java.lang.Runnable&gt;&nbsp;void&nbsp;accept(" +
             "<a href=\"../typeannos/RcvrA.html\" title=\"annotation in " +
             "typeannos\">@RcvrA</a>&nbsp;DefaultUnmodified&nbsp;this," + NL +
-            "                                         T&nbsp;r)" + NL +
-            "      throws java.lang.Exception</pre>"
+            "                                           T&nbsp;r)" + NL +
+            "                                    throws java.lang.Exception</pre>"
         },
         {BUG_ID + FS + "typeannos" + FS + "PublicModified.html",
             "<pre>public final&nbsp;java.lang.String&nbsp;nonVoid(<a href=\"" +
@@ -368,16 +348,16 @@
             "<pre>public final&nbsp;&lt;T extends java.lang.Runnable&gt;&nbsp;" +
             "void&nbsp;accept(<a href=\"../typeannos/RcvrA.html\" title=\"" +
             "annotation in typeannos\">@RcvrA</a>&nbsp;PublicModified&nbsp;this," + NL +
-            "                                         T&nbsp;r)" + NL +
-            "                  throws java.lang.Exception</pre>"
+            "                                                        T&nbsp;r)" + NL +
+            "                                                 throws java.lang.Exception</pre>"
         },
         {BUG_ID + FS + "typeannos" + FS + "WithValue.html",
             "<pre>&lt;T extends java.lang.Runnable&gt;&nbsp;void&nbsp;accept(" +
             "<a href=\"../typeannos/RcvrB.html\" title=\"annotation in " +
             "typeannos\">@RcvrB</a>(<a href=\"../typeannos/RcvrB.html#value()\">" +
             "value</a>=\"m\")&nbsp;WithValue&nbsp;this," + NL +
-            "                                         T&nbsp;r)" + NL +
-            "      throws java.lang.Exception</pre>"
+            "                                           T&nbsp;r)" + NL +
+            "                                    throws java.lang.Exception</pre>"
         },
         {BUG_ID + FS + "typeannos" + FS + "WithFinal.html",
             "<pre>java.lang.String&nbsp;nonVoid(<a href=\"../typeannos/RcvrB." +
diff --git a/langtools/test/com/sun/javadoc/testTypeParams/TestTypeParameters.java b/langtools/test/com/sun/javadoc/testTypeParams/TestTypeParameters.java
index cef99f1..ee352a1 100644
--- a/langtools/test/com/sun/javadoc/testTypeParams/TestTypeParameters.java
+++ b/langtools/test/com/sun/javadoc/testTypeParams/TestTypeParameters.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -54,7 +54,7 @@
     private static final String[][] TEST1 = {
         {BUG_ID + FS + "pkg" + FS + "C.html",
             "<td class=\"colFirst\"><code>&lt;W extends java.lang.String,V extends " +
-            "java.util.List&gt;&nbsp;<br>java.lang.Object</code></td>"
+            "java.util.List&gt;<br>java.lang.Object</code></td>"
         },
         {BUG_ID + FS + "pkg" + FS + "C.html",
             "<code>&lt;T&gt;&nbsp;java.lang.Object</code>"
diff --git a/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java b/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java
index f53e6f4..ba0f291 100644
--- a/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java
+++ b/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java
@@ -90,7 +90,7 @@
         //Test @value tag used with custom tag.
         {BUG_ID + FS + "pkg1" + FS + "CustomTagUsage.html",
             "<dt><span class=\"strong\">Todo:</span></dt>" + NL +
-                "  <dd>the value of this constant is 55.</dd>"},
+                "<dd>the value of this constant is 55.</dd>"},
         //Test @value warning printed when used with non-constant.
         {WARNING_OUTPUT,"warning - @value tag (which references nonConstant) " +
             "can only be used in constants."
diff --git a/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java
index 6a5b2af..f90c196 100644
--- a/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java
+++ b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,8 +24,7 @@
 /*
  * @test
  * @bug 8006735
- * @ignore
- * @summary  Smoke test for ensuring that annotations are emited to javadoc
+ * @summary  Smoke test for ensuring that annotations are emitted to javadoc
  *
  * @author   Mahmood Ali <mali>
  * @library  ../../lib/
@@ -37,7 +36,7 @@
 public class TestSmoke extends JavadocTester {
 
     //Test information.
-    private static final String BUG_ID = "NOT_SPECIFIED_YET";
+    private static final String BUG_ID = "8006735";
 
     //Javadoc arguments.
     private static final String[] ARGS = new String[] {
@@ -52,8 +51,24 @@
         {BUG_ID + FS + "pkg" + FS + "T0x06.html", "@DA"},
         {BUG_ID + FS + "pkg" + FS + "T0x0B.html", "@DA"},
         {BUG_ID + FS + "pkg" + FS + "T0x0F.html", "@DA"},
+        /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
         {BUG_ID + FS + "pkg" + FS + "T0x20.html", "@DA"},
+        */
+        /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
+        {BUG_ID + FS + "pkg" + FS + "T0x20A.html", "@DTPA"},
+        */
+        /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
+        {BUG_ID + FS + "pkg" + FS + "T0x20B.html", "@DA"},
+        */
+        /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
         {BUG_ID + FS + "pkg" + FS + "T0x22.html", "@DA"},
+        */
+        /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
+        {BUG_ID + FS + "pkg" + FS + "T0x22A.html", "@DTPA"},
+        */
+        /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
+        {BUG_ID + FS + "pkg" + FS + "T0x22B.html", "@DA"},
+        */
         {BUG_ID + FS + "pkg" + FS + "T0x10.html", "@DA"},
         {BUG_ID + FS + "pkg" + FS + "T0x10A.html", "@DA"},
         {BUG_ID + FS + "pkg" + FS + "T0x12.html", "@DA"},
@@ -77,7 +92,11 @@
         {BUG_ID + FS + "pkg" + FS + "T0x0B.html", "@A"},
         {BUG_ID + FS + "pkg" + FS + "T0x0F.html", "@A"},
         {BUG_ID + FS + "pkg" + FS + "T0x20.html", "@A"},
+        {BUG_ID + FS + "pkg" + FS + "T0x20A.html", "@A"},
+        {BUG_ID + FS + "pkg" + FS + "T0x20B.html", "@A"},
         {BUG_ID + FS + "pkg" + FS + "T0x22.html", "@A"},
+        {BUG_ID + FS + "pkg" + FS + "T0x22A.html", "@A"},
+        {BUG_ID + FS + "pkg" + FS + "T0x22B.html", "@A"},
         {BUG_ID + FS + "pkg" + FS + "T0x10.html", "@A"},
         {BUG_ID + FS + "pkg" + FS + "T0x10A.html", "@A"},
         {BUG_ID + FS + "pkg" + FS + "T0x12.html", "@A"},
diff --git a/langtools/test/com/sun/javadoc/typeAnnotations/smoke/pkg/TargetTypes.java b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/pkg/TargetTypes.java
index 435a680..104b74a 100644
--- a/langtools/test/com/sun/javadoc/typeAnnotations/smoke/pkg/TargetTypes.java
+++ b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/pkg/TargetTypes.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,24 +36,19 @@
  * @author Yuri Gaevsky
  */
 
-@Target({TYPE_USE})
+@Target(TYPE_USE)
 @Retention(RetentionPolicy.RUNTIME)
 @interface A {}
 
-@Target({TYPE_USE})
+@Target(TYPE_USE)
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 @interface DA {}
 
-/** wildcard bound */
-class T0x1C {
-    void m0x1C(List<? extends @A @DA String> lst) {}
-}
-
-/** wildcard bound generic/array */
-class T0x1D<T> {
-    void m0x1D(List<? extends @A @DA List<int[]>> lst) {}
-}
+@Target(TYPE_PARAMETER)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@interface DTPA {}
 
 /** typecast */
 class T0x00 {
@@ -76,76 +71,6 @@
     }
 }
 
-/** object creation (new) */
-class T0x04 {
-    void m0x04() {
-        new @A @DA ArrayList<String>();
-    }
-}
-
-/** local variable */
-class T0x08 {
-    void m0x08() {
-      @A @DA String s = null;
-    }
-}
-
-/** method parameter generic/array */
-class T0x0D {
-    void m0x0D(HashMap<@A @DA Object, List<@A @DA List<@A @DA Class>>> s1) {}
-}
-
-/** method receiver */
-class T0x06 {
-    void m0x06(@A @DA T0x06 this) {}
-}
-
-/** method return type generic/array */
-class T0x0B {
-    Class<@A @DA Object> m0x0B() { return null; }
-}
-
-/** field generic/array */
-class T0x0F {
-    HashMap<@A @DA Object, @A @DA Object> c1;
-}
-
-/** method type parameter */
-class T0x20<T, U> {
-    <@A @DA T, @A @DA U> void m0x20() {}
-}
-
-/** class type parameter */
-class T0x22<@A @DA T, @A @DA U> {
-}
-
-/** class type parameter bound */
-class T0x10<T extends @A @DA Cloneable> {
-}
-
-class T0x10A<T extends @A @DA Object> {
-}
-
-/** method type parameter bound */
-class T0x12<T> {
-    <T extends @A @DA Cloneable> void m0x12() {}
-}
-
-/** class type parameter bound generic/array */
-class T0x11<T extends List<@A @DA T>> {
-}
-
-/** method type parameter bound generic/array */
-class T0x13 {
-    static <T extends Comparable<@A @DA T>> T m0x13() {
-        return null;
-    }
-}
-
-/** class extends/implements generic/array */
-class T0x15<T> extends ArrayList<@A @DA T> {
-}
-
 /** type test (instanceof) generic/array */
 class T0x03<T> {
     void m0x03(T typeObj, Object obj) {
@@ -153,6 +78,13 @@
     }
 }
 
+/** object creation (new) */
+class T0x04 {
+    void m0x04() {
+        new @A @DA ArrayList<String>();
+    }
+}
+
 /** object creation (new) generic/array */
 class T0x05<T> {
     void m0x05() {
@@ -160,6 +92,18 @@
     }
 }
 
+/** method receiver */
+class T0x06 {
+    void m0x06(@A @DA T0x06 this) {}
+}
+
+/** local variable */
+class T0x08 {
+    void m0x08() {
+      @A @DA String s = null;
+    }
+}
+
 /** local variable generic/array */
 class T0x09<T> {
     void g() {
@@ -171,20 +115,55 @@
     }
 }
 
-/** type argument in constructor call generic/array */
-class T0x19 {
-    <T> T0x19() {}
+/** method return type generic/array */
+class T0x0B {
+    Class<@A @DA Object> m0x0B() { return null; }
+}
 
-    void g() {
-       new <List<@A @DA String>> T0x19();
+/** method parameter generic/array */
+class T0x0D {
+    void m0x0D(HashMap<@A @DA Object, List<@A @DA List<@A @DA Class>>> s1) {}
+}
+
+/** field generic/array */
+class T0x0F {
+    HashMap<@A @DA Object, @A @DA Object> c1;
+}
+
+/** class type parameter bound */
+class T0x10<T extends @A @DA Cloneable> {
+}
+
+class T0x10A<T extends @A @DA Object> {
+}
+
+/** class type parameter bound generic/array */
+class T0x11<T extends List<@A @DA T>> {
+}
+
+/** method type parameter bound */
+class T0x12<T> {
+    <T extends @A @DA Cloneable> void m0x12() {}
+}
+
+/** method type parameter bound generic/array */
+class T0x13 {
+    static <T extends Comparable<@A @DA T>> T m0x13() {
+        return null;
     }
 }
 
-/** type argument in method call generic/array */
-class T0x1B<T> {
-    void m0x1B() {
-        Collections.<T @A @DA []>emptyList();
-    }
+/** class extends/implements */
+class T0x14 extends @A @DA Thread implements @A @DA Serializable, @A @DA Cloneable {
+}
+
+/** class extends/implements generic/array */
+class T0x15<T> extends ArrayList<@A @DA T> {
+}
+
+/** exception type in throws */
+class T0x16 {
+    void m0x16() throws @A @DA Exception {}
 }
 
 /** type argument in constructor call */
@@ -196,6 +175,15 @@
     }
 }
 
+/** type argument in constructor call generic/array */
+class T0x19 {
+    <T> T0x19() {}
+
+    void g() {
+       new <List<@A @DA String>> T0x19();
+    }
+}
+
 /** type argument in method call */
 class T0x1A<T,U> {
     public static <T, U> T m() { return null; }
@@ -204,11 +192,43 @@
     }
 }
 
-/** class extends/implements */
-class T0x14 extends @A @DA Thread implements @A @DA Serializable, @A @DA Cloneable {
+/** type argument in method call generic/array */
+class T0x1B<T> {
+    void m0x1B() {
+        Collections.<T @A @DA []>emptyList();
+    }
 }
 
-/** exception type in throws */
-class T0x16 {
-    void m0x16() throws @A @DA Exception {}
+/** wildcard bound */
+class T0x1C {
+    void m0x1C(List<? extends @A @DA String> lst) {}
+}
+
+/** wildcard bound generic/array */
+class T0x1D<T> {
+    void m0x1D(List<? extends @A @DA List<int[]>> lst) {}
+}
+
+/** method type parameter */
+class T0x20 {
+    <@A @DA T> void m0x20() {}
+}
+
+class T0x20A {
+    <@A @DTPA T> void m0x20A() {}
+}
+
+class T0x20B {
+    <T> void m0x20B(@A @DA T p) {}
+}
+
+/** class type parameter */
+class T0x22<@A @DA T> {
+}
+
+class T0x22A<@A @DTPA T> {
+}
+
+class T0x22B<T> {
+    @A @DA T f;
 }
diff --git a/langtools/test/tools/javac/Diagnostics/compressed/T8012003a.java b/langtools/test/tools/javac/Diagnostics/compressed/T8012003a.java
new file mode 100644
index 0000000..9772964
--- /dev/null
+++ b/langtools/test/tools/javac/Diagnostics/compressed/T8012003a.java
@@ -0,0 +1,24 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug     8012003
+ * @summary Method diagnostics resolution need to be simplified in some cases
+ *          test general overload resolution simplifications
+ * @compile/fail/ref=T8012003a.out -XDrawDiagnostics -Xdiags:compact T8012003a.java
+ */
+
+class T8012003a {
+    void m1(Integer i) { }
+
+    void m2(Integer i) { }
+    void m2(Integer i, Object o) { }
+
+    void m3(Integer i) { }
+    void m3(String s) { }
+
+    void test() {
+        m1("");
+        m1(false ? "" : "");
+        m2("");
+        m3('x');
+    }
+}
diff --git a/langtools/test/tools/javac/Diagnostics/compressed/T8012003a.out b/langtools/test/tools/javac/Diagnostics/compressed/T8012003a.out
new file mode 100644
index 0000000..b128716
--- /dev/null
+++ b/langtools/test/tools/javac/Diagnostics/compressed/T8012003a.out
@@ -0,0 +1,6 @@
+T8012003a.java:19:12: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer)
+T8012003a.java:20:20: compiler.err.prob.found.req: (compiler.misc.incompatible.type.in.conditional: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer))
+T8012003a.java:21:12: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer)
+T8012003a.java:22:9: compiler.err.cant.apply.symbols: kindname.method, m3, char,{(compiler.misc.inapplicable.method: kindname.method, T8012003a, m3(java.lang.Integer), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: char, java.lang.Integer))),(compiler.misc.inapplicable.method: kindname.method, T8012003a, m3(java.lang.String), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: char, java.lang.String)))}
+- compiler.note.compressed.diags
+4 errors
diff --git a/langtools/test/tools/javac/Diagnostics/compressed/T8012003b.java b/langtools/test/tools/javac/Diagnostics/compressed/T8012003b.java
new file mode 100644
index 0000000..f5fbeb0
--- /dev/null
+++ b/langtools/test/tools/javac/Diagnostics/compressed/T8012003b.java
@@ -0,0 +1,37 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug     8012003
+ * @summary Method diagnostics resolution need to be simplified in some cases
+ *          test lambda-related overload resolution simplifications
+ * @compile/fail/ref=T8012003b.out -XDrawDiagnostics -Xdiags:compact T8012003b.java
+ */
+
+class T8012003b {
+
+    interface Consumer_V<X> {
+        void m(X x);
+    }
+
+    interface Consumer_NV<X> {
+        Integer m(X x);
+    }
+
+    void m1(Runnable r) { }
+    void m1(Runnable r, String s) { }
+
+    void m2(Consumer_V<Integer> ci) { }
+
+    void m3(Consumer_NV<String> ci) { }
+
+    void g(String arg) { }
+    String g2(String arg) { return arg; }
+
+    void test() {
+        m1(this::g);
+        m1(()->1);
+        m1(()->false ? "" : "");
+        m2(this::g);
+        m3(this::g2);
+        m3(this::k);
+    }
+}
diff --git a/langtools/test/tools/javac/Diagnostics/compressed/T8012003b.out b/langtools/test/tools/javac/Diagnostics/compressed/T8012003b.out
new file mode 100644
index 0000000..246900b
--- /dev/null
+++ b/langtools/test/tools/javac/Diagnostics/compressed/T8012003b.out
@@ -0,0 +1,8 @@
+T8012003b.java:30:12: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, g, java.lang.String, compiler.misc.no.args, kindname.class, T8012003b, (compiler.misc.arg.length.mismatch)))
+T8012003b.java:31:16: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: int, void))
+T8012003b.java:32:22: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.conditional.target.cant.be.void))
+T8012003b.java:33:12: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Integer, java.lang.String)))
+T8012003b.java:34:12: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer))
+T8012003b.java:35:12: compiler.err.invalid.mref: kindname.method, (compiler.misc.cant.resolve.location.args: kindname.method, k, , , (compiler.misc.location: kindname.class, T8012003b, null))
+- compiler.note.compressed.diags
+6 errors
diff --git a/langtools/test/tools/javac/Diagnostics/compressed/T8012003c.java b/langtools/test/tools/javac/Diagnostics/compressed/T8012003c.java
new file mode 100644
index 0000000..a64f977
--- /dev/null
+++ b/langtools/test/tools/javac/Diagnostics/compressed/T8012003c.java
@@ -0,0 +1,24 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug     8012003
+ * @summary Method diagnostics resolution need to be simplified in some cases
+ *          test simplification of lambda type-checking error leading to resolution failure
+ * @compile/fail/ref=T8012003c.out -XDrawDiagnostics -Xdiags:compact T8012003c.java
+ */
+
+class T8012003c {
+
+    interface I {
+        void m(P p);
+    }
+
+    void m(I i) { }
+
+    void test() {
+        m(p->p.m());
+    }
+}
+
+class P {
+    private void m() { }
+}
diff --git a/langtools/test/tools/javac/Diagnostics/compressed/T8012003c.out b/langtools/test/tools/javac/Diagnostics/compressed/T8012003c.out
new file mode 100644
index 0000000..7af49cc
--- /dev/null
+++ b/langtools/test/tools/javac/Diagnostics/compressed/T8012003c.out
@@ -0,0 +1,3 @@
+T8012003c.java:18:15: compiler.err.report.access: m(), private, P
+- compiler.note.compressed.diags
+1 error
diff --git a/langtools/test/tools/javac/annotations/clinit/AnnoWithClinit1.java b/langtools/test/tools/javac/annotations/clinit/AnnoWithClinit1.java
new file mode 100644
index 0000000..4c3498f
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/clinit/AnnoWithClinit1.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8013485
+ * @summary Annotations that gets a clinit can't be verified for correct elements in a second compilation unit
+ * @compile AnnoWithClinit1.java
+ */
+
+public @interface AnnoWithClinit1 {
+    Foo f = new Foo();
+
+    @AnnoWithClinit1
+    static class C {} // this is in the same CU so there wont be a
+                      // <clinit> when the this anno instance is checked
+
+    class Foo {}
+}
+
+
+@AnnoWithClinit1
+class BarAnnoClinit1 {}
+
+@interface AAnnoClinit1 {
+    Runnable r2 = new Runnable() { public void run() { }};
+    String str1();
+    String str2withdefault() default "bar";
+}
+
+@AAnnoClinit1(str1="value")
+class TestAnnoClinit1 { }
diff --git a/langtools/test/tools/javac/annotations/clinit/AnnoWithClinitFail.java b/langtools/test/tools/javac/annotations/clinit/AnnoWithClinitFail.java
new file mode 100644
index 0000000..52d0e8a
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/clinit/AnnoWithClinitFail.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8013485
+ * @summary Annotations that gets a clinit can't be verified for correct elements in a second compilation unit
+ * @compile/fail/ref=AnnoWithClinitFail.out -XDrawDiagnostics AnnoWithClinitFail.java
+ */
+
+public @interface AnnoWithClinitFail {
+    Foo f = new Foo();
+
+    String foo();
+    String bar() default "bar";
+
+    @AnnoWithClinitFail
+    static class C {} // this is in the same CU so there wont be a
+                      // <clinit> when the this anno instance is checked
+
+    class Foo {}
+}
+
+@AnnoWithClinitFail
+class TestAnnoWithClinitFail { }
diff --git a/langtools/test/tools/javac/annotations/clinit/AnnoWithClinitFail.out b/langtools/test/tools/javac/annotations/clinit/AnnoWithClinitFail.out
new file mode 100644
index 0000000..c9526b4
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/clinit/AnnoWithClinitFail.out
@@ -0,0 +1,3 @@
+AnnoWithClinitFail.java:37:5: compiler.err.annotation.missing.default.value: AnnoWithClinitFail, foo
+AnnoWithClinitFail.java:44:1: compiler.err.annotation.missing.default.value: AnnoWithClinitFail, foo
+2 errors
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/attribution/Scopes.java b/langtools/test/tools/javac/annotations/typeAnnotations/attribution/Scopes.java
index da01c38..810038c 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/attribution/Scopes.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/attribution/Scopes.java
@@ -28,11 +28,17 @@
  * @author Mahmood Ali
  * @compile Scopes.java
  */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
 class Scopes {
 
   void test(@A(VALUE) Scopes this) { }
   void test1(@A(value=VALUE) Scopes this) { }
 
   private static final int VALUE = 1;
+
+  @Target(ElementType.TYPE_USE)
   @interface A { int value(); }
 }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java
index b026216..952b73c 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java
@@ -66,12 +66,12 @@
     }
 
     ClassFile getClassFile(URL url) throws IOException, ConstantPoolException {
-            InputStream in = url.openStream();
-            try {
-                return ClassFile.read(in);
-            } finally {
-                in.close();
-            }
+        InputStream in = url.openStream();
+        try {
+            return ClassFile.read(in);
+        } finally {
+            in.close();
+        }
     }
 
     /************ Helper annotations counting methods ******************/
@@ -83,20 +83,43 @@
         test("CLASS",cf, null, null, Attribute.RuntimeInvisibleAnnotations, false);
     }
 
-    void test(ClassFile cf, Method m) {
-        test("METHOD",cf, null, m, Attribute.RuntimeVisibleTypeAnnotations, true);
-        test("METHOD",cf, null, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
-        test("METHOD",cf, null, m, Attribute.RuntimeVisibleAnnotations, true);
-        test("METHOD",cf, null, m, Attribute.RuntimeInvisibleAnnotations, false);
+    void test(ClassFile cf, Field f, Boolean local) {
+        if (!local) {
+            test("FIELD",cf, f, null, Attribute.RuntimeVisibleTypeAnnotations, true);
+            test("FIELD",cf, f, null, Attribute.RuntimeInvisibleTypeAnnotations, false);
+            test("FIELD",cf, f, null, Attribute.RuntimeVisibleAnnotations, true);
+            test("FIELD",cf, f, null, Attribute.RuntimeInvisibleAnnotations, false);
+        } else {
+            test("CODE",cf, f, null, Attribute.RuntimeVisibleTypeAnnotations, true);
+            test("CODE",cf, f, null, Attribute.RuntimeInvisibleTypeAnnotations, false);
+            test("CODE",cf, f, null, Attribute.RuntimeVisibleAnnotations, true);
+            test("CODE",cf, f, null, Attribute.RuntimeInvisibleAnnotations, false);
+        }
     }
 
     void test(ClassFile cf, Field f) {
-        test("FIELD",cf, f, null, Attribute.RuntimeVisibleTypeAnnotations, true);
-        test("FIELD",cf, f, null, Attribute.RuntimeInvisibleTypeAnnotations, false);
-        test("FIELD",cf, f, null, Attribute.RuntimeVisibleAnnotations, true);
-        test("FIELD",cf, f, null, Attribute.RuntimeInvisibleAnnotations, false);
+        test(cf, f, false);
     }
 
+    // 'local' determines whether to look for annotations in code attribute or not.
+    void test(ClassFile cf, Method m, Boolean local) {
+        if (!local) {
+            test("METHOD",cf, null, m, Attribute.RuntimeVisibleTypeAnnotations, true);
+            test("METHOD",cf, null, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
+            test("METHOD",cf, null, m, Attribute.RuntimeVisibleAnnotations, true);
+            test("METHOD",cf, null, m, Attribute.RuntimeInvisibleAnnotations, false);
+        } else  {
+            test("MCODE",cf, null, m, Attribute.RuntimeVisibleTypeAnnotations, true);
+            test("MCODE",cf, null, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
+            test("MCODE",cf, null, m, Attribute.RuntimeVisibleAnnotations, true);
+            test("MCODE",cf, null, m, Attribute.RuntimeInvisibleAnnotations, false);
+        }
+    }
+
+    // default to not looking in code attribute
+    void test(ClassFile cf, Method m ) {
+        test(cf, m, false);
+    }
 
     // Test the result of Attributes.getIndex according to expectations
     // encoded in the class/field/method name; increment annotations counts.
@@ -105,18 +128,47 @@
         String name = null;
         int index = -1;
         Attribute attr = null;
+        Code_attribute cAttr = null;
         boolean isTAattr = annName.contains("TypeAnnotations");
         try {
             switch(testtype) {
                 case "FIELD":
                     name = f.getName(cf.constant_pool);
                     index = f.attributes.getIndex(cf.constant_pool, annName);
-                    if(index!= -1) attr = f.attributes.get(index);
+                    if(index!= -1)
+                        attr = f.attributes.get(index);
+                    break;
+                case "CODE":
+                    name = f.getName(cf.constant_pool);
+                    //fetch index of and code attribute and annotations from code attribute.
+                    index = cf.attributes.getIndex(cf.constant_pool, Attribute.Code);
+                    if(index!= -1) {
+                        attr = cf.attributes.get(index);
+                        assert attr instanceof Code_attribute;
+                        cAttr = (Code_attribute)attr;
+                        index = cAttr.attributes.getIndex(cf.constant_pool, annName);
+                        if(index!= -1)
+                            attr = cAttr.attributes.get(index);
+                    }
                     break;
                 case "METHOD":
                     name = m.getName(cf.constant_pool);
                     index = m.attributes.getIndex(cf.constant_pool, annName);
-                    if(index!= -1) attr = m.attributes.get(index);
+                    if(index!= -1)
+                        attr = m.attributes.get(index);
+                    break;
+                case "MCODE":
+                    name = m.getName(cf.constant_pool);
+                    //fetch index of and code attribute and annotations from code attribute.
+                    index = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
+                    if(index!= -1) {
+                        attr = m.attributes.get(index);
+                        assert attr instanceof Code_attribute;
+                        cAttr = (Code_attribute)attr;
+                        index = cAttr.attributes.getIndex(cf.constant_pool, annName);
+                        if(index!= -1)
+                            attr = cAttr.attributes.get(index);
+                    }
                     break;
                 default:
                     name = cf.getName();
@@ -126,7 +178,6 @@
         } catch(ConstantPoolException cpe) { cpe.printStackTrace(); }
 
         if (index != -1) {
-            assert attr instanceof RuntimeTypeAnnotations_attribute;
             if(isTAattr) { //count RuntimeTypeAnnotations
                 RuntimeTypeAnnotations_attribute tAttr =
                         (RuntimeTypeAnnotations_attribute)attr;
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest1.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest1.java
index ed3c094..a33ea2d 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest1.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest1.java
@@ -24,7 +24,6 @@
 /*
  * @test
  * @bug 8005085 8005877 8004829 8005681 8006734 8006775
- * @ignore
  * @summary Combinations of Target ElementTypes on (repeated)type annotations.
  */
 
@@ -32,10 +31,25 @@
 import java.io.File;
 
 public class CombinationsTargetTest1 extends ClassfileTestHelper {
-    // Helps identify test case in event of failure.
+
+    // Test count helps identify test case in event of failure.
     int testcount = 0;
-    int src1 = 1, src2 = 2, src4 = 4,
-        src5 = 5, src6 = 6, src7 = 7;
+
+    // Base test case template descriptions
+    enum srce  {
+        src1("(repeating) type annotations at class level"),
+        src2("(repeating) type annotations on method"),
+        src3("(repeating) type annotations on wildcard, type arguments in anonymous class"),
+        src4("(repeating) type annotations on type parameters, bounds and  type arguments on class decl"),
+        src5("(repeating) type annotations on type parameters, bounds and  type arguments on method"),
+        src6("(repeating) type annotations on type parameters, bounds and  type arguments in method");
+
+        String description;
+
+        srce(String desc) {
+            this.description = this + ": " +desc;
+        }
+    }
 
     String[] ETypes={"TYPE", "FIELD", "METHOD", "PARAMETER", "CONSTRUCTOR",
                      "LOCAL_VARIABLE", "ANNOTATION_TYPE", "PACKAGE"};
@@ -52,7 +66,6 @@
         // Determines which repeat and order in source(ABMix).
         Boolean As= false, BDs=true, ABMix=false;
         int testrun=0;
-        // A repeats and/or B/D repeats, ABMix for order of As and Bs.
         Boolean [][] bRepeat = new Boolean[][]{{false,false,false},//no repeats
                                                {true,false,false}, //repeat @A
                                                {false,true,false}, //repeat @B
@@ -64,29 +77,29 @@
             for(String et : ETypes) {
                switch(et) {
                    case "METHOD":
-                       test( 8,  0, 2, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, src1);
-                       test(10,  0, 2, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, src2);
-                       test( 8,  0, 0, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, src4);
-                       test(10,  0, 2, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, src6);
-                       test( 0,  8, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, src1);
-                       test( 0, 10, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, src2);
-                       test( 0,  8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, src4);
-                       test( 0, 10, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, src6);
+                       test( 8,  0, 2, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src1);
+                       test(10,  0, 2, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src2);
+                       test( 6,  0, 0, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src3);
+                       test(10,  0, 2, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src5);
+                       test( 0,  8, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
+                       test( 0, 10, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src2);
+                       test( 0,  6, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src3);
+                       test( 0, 10, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src5);
                        break;
                    case "CONSTRUCTOR":
                    case "FIELD":
-                       test( 8,  0, 4, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, src1);
-                       test( 6,  0, 3, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, src5);
-                       test( 9,  0, 0, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, src7);
-                       test( 0,  8, 0, 4, As, BDs, ABMix, "RUNTIME", et, ++testrun, src1);
-                       test( 0,  6, 0, 3, As, BDs, ABMix, "RUNTIME", et, ++testrun, src5);
-                       test( 0,  9, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, src7);
+                       test( 8,  0, 4, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src1);
+                       test( 6,  0, 3, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src4);
+                       test( 9,  0, 0, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src6);
+                       test( 0,  8, 0, 4, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
+                       test( 0,  6, 0, 3, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src4);
+                       test( 0,  9, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src6);
                        break;
                    default:/*TYPE,PARAMETER,LOCAL_VARIABLE,ANNOTATION_TYPE,PACKAGE*/
-                       test( 8,  0, 2, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, src1);
-                       test( 6,  0, 3, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, src5);
-                       test( 0,  8, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, src1);
-                       test( 0,  6, 0, 3, As, BDs, ABMix, "RUNTIME", et, ++testrun, src5);
+                       test( 8,  0, 2, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src1);
+                       test( 6,  0, 3, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src4);
+                       test( 0,  8, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
+                       test( 0,  6, 0, 3, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src4);
                }
             }
         }
@@ -94,7 +107,7 @@
 
     public void test(int tinv, int tvis, int inv, int vis, Boolean Arepeats,
                      Boolean BDrepeats, Boolean ABmix, String rtn, String et2,
-                     Integer N, int source) throws Exception {
+                     Integer N, srce source) throws Exception {
         ++testcount;
         expected_tvisibles = tvis;
         expected_tinvisibles = tinv;
@@ -125,7 +138,8 @@
         //if sourcString() set hasInnerClass it also set innerClassname.
         if(hasInnerClass) {
             StringBuffer sb = new StringBuffer(classFile.getAbsolutePath());
-            classFile=new File(sb.insert(sb.lastIndexOf(".class"),innerClassname).toString());
+            classFile=new File(sb.insert(sb.lastIndexOf(".class"),
+                                         innerClassname).toString());
         }
         ClassFile cf = ClassFile.read(classFile);
 
@@ -152,7 +166,7 @@
     //
     String sourceString(String testname, String retentn, String annot2,
                         Boolean Arepeats, Boolean BDrepeats, Boolean ABmix,
-                        int src) {
+                        srce src) {
 
         String As = "@A", Bs = "@B", Ds = "@D";
         if(Arepeats) As = "@A @A";
@@ -201,11 +215,11 @@
 
             "@Retention("+retentn+")\n" +
             "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" +
-            "@interface DC { D[] value(); }\n\n");
+            "@interface DC { D[] value(); }\n");
 
         // Test case sources with sample generated source.
         switch(src) {
-            case 1: // repeating type annotations at class level
+            case src1: // repeating type annotations at class level
                     /*
                      * @A @B class Test1 {
                      * @A @B Test1(){}
@@ -218,21 +232,21 @@
                      * }}
                      */
                 source = new String(
-                "// (repeating) type annotations at class level. \n" +
-                "_As_ _Bs_ class " + testname + " {\n" +
-                "_As_ _Bs_ " + testname +"(){} \n" +
-                "_As_ _Bs_ Integer i1 = 0; \n" +
-                "String _As_ _Bs_ [] _As_ _Bs_ [] sa = null; \n" +
-                "// type usage in method body \n" +
-                "String test("+testname+" this, " +
-                   "String param, String ... vararg) { \n" +
-                "    Object o = new  String  [3]; \n" +
-                "    return (String) null; \n" +
-                "} \n" +
-                "} \n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
-                "\n\n";
+                    "// " + src.description + "\n" +
+                    "_As_ _Bs_ class " + testname + " {\n" +
+                    "_As_ _Bs_ " + testname +"(){} \n" +
+                    "_As_ _Bs_ Integer i1 = 0; \n" +
+                    "String _As_ _Bs_ [] _As_ _Bs_ [] sa = null; \n" +
+                    "// type usage in method body \n" +
+                    "String test("+testname+" this, " +
+                       "String param, String ... vararg) { \n" +
+                    "    Object o = new  String  [3]; \n" +
+                    "    return (String) null; \n" +
+                    "}\n" +
+                    "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+                    "\n";
                 break;
-            case 2: // (repeating) type annotations on method.
+            case src2: // (repeating) type annotations on method.
                     /*
                      * class Test12 {
                      * Test12(){}
@@ -243,26 +257,26 @@
                      * }}
                      */
                 source = new String(
-                "// (repeating) type annotations on method. \n" +
-                "class " + testname + " {\n" +
-                testname +"(){} \n" +
-                "// type usage on method \n" +
-                "_As_ _Bs_ String test(_As_ _Bs_  "+testname+" this, " +
-                   "_As_ _Bs_  String param, _As_ _Bs_  String _As_ _Bs_  ... vararg) { \n" +
-                "    Object o = new String [3]; \n" +
-                "    return (String) null; \n" +
-                "} \n" +
-                "} \n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
-                "\n\n";
+                    "// " + src.description + "\n" +
+                    "class " + testname + " {\n" +
+                    testname +"(){} \n" +
+                    "// type usage on method \n" +
+                    "_As_ _Bs_ String test(_As_ _Bs_  "+testname+" this, " +
+                       "_As_ _Bs_  String param, _As_ _Bs_  String _As_ _Bs_  ... vararg) { \n" +
+                    "    Object o = new String [3]; \n" +
+                    "    return (String) null; \n" +
+                    "}\n" +
+                    "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+                    "\n";
                 break;
-            case 4: //(repeating) annotations on wildcard, type arguments in anonymous class.
+            case src3: //(repeating) annotations on wildcard, type arguments in anonymous class.
                     /*
                      * class Test13<T extends Object> {
                      *     public T data = null;
                      *     T getData() { return data;}
                      *     String mtest( Test13<String> t){ return t.getData(); }
                      *     public void test() {
-                     *         mtest( new Test13<@A @B String>() {
+                     *         mtest( new Test13<String>() {
                      *                  void m1(List<@A @B ? extends @A @B  Object> lst) {}
                      *                  void m2() throws@A @B Exception { }
                      *                });
@@ -270,22 +284,23 @@
                      * }
                      */
                 source = new String( source +
-                "// (repeating) annotations on wildcard, type arguments in anonymous class. \n" +
-                "class " + testname + "<T extends Object> {\n" +
-                "    public T data = null;\n" +
-                "    T getData() { return data;}\n" +
-                "    String mtest( " + testname + "<String> t){ return t.getData(); }\n" +
-                "    public void test() {\n" +
-                "        mtest( new " + testname + "<_As_ _Bs_ String>() {\n" +
-                "                 void m1(List<_As_ _Bs_ ? extends _As_ _Bs_  Object> lst) {}\n" +
-                "                 void m2() throws_As_ _Bs_ Exception { }\n" +
-                "               });\n" +
-                "    }\n" +
-                "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + "\n\n";
-                hasInnerClass=true;
-                innerClassname="$1";
+                    "// " + src.description + "\n" +
+                    "class " + testname + "<T extends Object> {\n" +
+                    "    public T data = null;\n" +
+                    "    T getData() { return data;}\n" +
+                    "    String mtest( " + testname + "<String> t){ return t.getData(); }\n" +
+                    "    public void test() {\n" +
+                    "        mtest( new " + testname + "<String>() {\n" +
+                    "                 void m1(List<_As_ _Bs_ ? extends _As_ _Bs_  Object> lst) {}\n" +
+                    "                 void m2() throws_As_ _Bs_ Exception { }\n" +
+                    "               });\n" +
+                    "    }\n" +
+                    "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+                    "\n";
+                    hasInnerClass=true;
+                    innerClassname="$1";
             break;
-            case 5: // (repeating)annotations on type parameters, bounds and  type arguments on class decl.
+            case src4: // (repeating)annotations on type parameters, bounds and  type arguments on class decl.
                     /*
                      * @A @B @D
                      * class Test2<@A @B @C @D T extends @A @B Object> {
@@ -297,18 +312,18 @@
                      * }
                      */
                 source = new String( source +
-                "// (repeating)annotations on type parameters, bounds and  type arguments on class decl. \n" +
-                "_As_ _Bs_ _Ds_\n" +  //8004829: A and B on type parameter below.
-                "class " + testname + "<_As_ _Bs_ @C _Ds_ T extends _As_ _Bs_ Object> {\n" +
-                "    Map<List<String>, Integer> map =\n" +
-                "        new HashMap<List< String>, Integer>();\n" +
-                "    Map<List<String>,Integer> map2 = new HashMap<>();\n" +
-                "    String test(" + testname + "<T> this) { return null;}\n" +
-                "    <T> String genericMethod(T t) { return null; }\n" +
-                "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
-                "\n\n";
-            break;
-            case 6: // (repeating) annotations on type parameters, bounds and  type arguments on method.
+                    "// " + src.description + "\n" +
+                    "_As_ _Bs_ _Ds_\n" +  //8004829: A and B on type parameter below.
+                    "class " + testname + "<_As_ _Bs_ @C _Ds_ T extends _As_ _Bs_ Object> {\n" +
+                    "    Map<List<String>, Integer> map =\n" +
+                    "        new HashMap<List< String>, Integer>();\n" +
+                    "    Map<List<String>,Integer> map2 = new HashMap<>();\n" +
+                    "    String test(" + testname + "<T> this) { return null;}\n" +
+                    "    <T> String genericMethod(T t) { return null; }\n" +
+                    "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
+                    "\n";
+                break;
+            case src5: // (repeating) annotations on type parameters, bounds and  type arguments on method.
                     /*
                      * class Test14<T extends Object> {
                      *     Map<List<String>, Integer> map =
@@ -319,17 +334,17 @@
                      * }
                      */
                 source = new String( source +
-                "// (repeating) annotations on type parameters, bounds and  type arguments on method. \n" +
-                "class " + testname + "<T extends Object> {\n" +
-                "    Map<List<String>, Integer> map =\n" +
-                "        new HashMap<List<String>, Integer>();\n" +
-                "    Map<List<String>, Integer> map2 = new HashMap<>();\n" +
-                "    String test(_As_ _Bs_ " + testname + "<_Ds_ T> this) { return null;}\n" +
-                "    <@C _Ds_ T> _As_ _Bs_ String genericMethod(_As_ _Bs_ _Ds_ T t) { return null; }\n" +
-                "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
-                "\n\n";
-            break;
-            case 7: // repeating annotations on type parameters, bounds and  type arguments in method.
+                    "// " + src.description + "\n" +
+                    "class " + testname + "<T extends Object> {\n" +
+                    "    Map<List<String>, Integer> map =\n" +
+                    "        new HashMap<List<String>, Integer>();\n" +
+                    "    Map<List<String>, Integer> map2 = new HashMap<>();\n" +
+                    "    String test(_As_ _Bs_ " + testname + "<_Ds_ T> this) { return null;}\n" +
+                    "    <@C _Ds_ T> _As_ _Bs_ String genericMethod(_As_ _Bs_ _Ds_ T t) { return null; }\n" +
+                    "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
+                    "\n";
+                break;
+            case src6: // repeating annotations on type parameters, bounds and  type arguments in method.
                     /*
                      * class Test7{
                      *     <E extends Comparable> Map<List<E>, E > foo(E e) {
@@ -344,22 +359,22 @@
                      * }
                      */
                 source = new String( source +
-                "// (repeating)annotations on type parameters of class, method return value in method. \n" +
-                "class "+ testname + "{\n" +
-                "    <E extends Comparable> Map<List<E>, E > foo(E e) {\n" +
-                "        class maptest <_As_ _Bs_ _Ds_ E> {\n" +                  // inner class $1maptest
-                "            Map<List<_As_ _Bs_ _Ds_ E>,_As_ _Bs_ _Ds_ E> getMap() { \n" +
-                "                return new HashMap<List<E>,E>();\n" +
-                "            }\n" +
-                "        }\n" +
-                "        return new maptest<E>().getMap();\n" +
-                "   }\n" +
-                "   Map<List<String>,String> shm = foo(new String(\"hello\"));\n" +
-                "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
-                "\n\n";
-                hasInnerClass=true;
-                innerClassname="$1maptest";
-            break;
+                    "// " + src.description + "\n" +
+                    "class "+ testname + "{\n" +
+                    "    <E extends Comparable> Map<List<E>, E > foo(E e) {\n" +
+                    "        class maptest <_As_ _Bs_ _Ds_ E> {\n" +                  // inner class $1maptest
+                    "            Map<List<_As_ _Bs_ _Ds_ E>,_As_ _Bs_ _Ds_ E> getMap() { \n" +
+                    "                return new HashMap<List<E>,E>();\n" +
+                    "            }\n" +
+                    "        }\n" +
+                    "        return new maptest<E>().getMap();\n" +
+                    "   }\n" +
+                    "   Map<List<String>,String> shm = foo(new String(\"hello\"));\n" +
+                    "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
+                    "\n";
+                    hasInnerClass=true;
+                    innerClassname="$1maptest";
+                break;
         }
         return imports + source;
     }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java
index e3414db..b660855 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java
@@ -23,8 +23,7 @@
 
 /*
  * @test
- * @bug 8005085 8005877 8004829 8005681 8006734 8006775
- * @ignore
+ * @bug 8005085 8005877 8004829 8005681 8006734 8006775 8006507
  * @summary Combinations of Target ElementTypes on (repeated)type annotations.
  */
 
@@ -32,9 +31,27 @@
 import java.io.File;
 
 public class CombinationsTargetTest2 extends ClassfileTestHelper {
-    // Helps identify test case in event of failure.
+
+    // Test count helps identify test case in event of failure.
     int testcount = 0;
-    int src3 = 3, src8 = 8, src9 = 9;
+
+    // Base test case template descriptions
+    enum srce  {
+        src1("(repeating) type annotations on on field in method body",true),
+        src2("(repeating) type annotations on type parameters, bounds and  type arguments", true),
+        src3("(repeating) type annotations on type parameters of class, method return value in method", true),
+        src4("(repeating) type annotations on field in anonymous class", false),
+        src5("(repeating) type annotations on field in anonymous class", false);
+
+        String description;
+        Boolean local;
+
+        srce(String desc, Boolean b) {
+            this.description = this + ": " +desc;
+            this.local = b;
+        }
+    }
+
 
     String[] ETypes={"TYPE", "FIELD", "METHOD", "PARAMETER", "CONSTRUCTOR",
                      "LOCAL_VARIABLE", "ANNOTATION_TYPE", "PACKAGE"};
@@ -51,31 +68,36 @@
         // Determines which repeat and order in source(ABMix).
         Boolean As= false, BDs=true, ABMix=false;
         int testrun=0;
-        // A repeats and/or B/D repeats, ABMix for order of As and Bs.
         Boolean [][] bRepeat = new Boolean[][]{{false,false,false},//no repeats
                                                {true,false,false}, //repeat @A
                                                {false,true,false}, //repeat @B
                                                {true,true,false},  //repeat both
                                                {false,false,true}  //repeat mix
         };
+
         for(Boolean[] bCombo : bRepeat) {
             As=bCombo[0]; BDs=bCombo[1]; ABMix=bCombo[2];
             for(String et : ETypes) {
                switch(et) {
                    case "METHOD":
-                       test( 8,  0, 0, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, src3);
-                       test( 0,  8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, src3);
+                       test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src1);
+                       test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
+                       test( 2, 0, 2, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src5);
+                       test( 0, 2, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src5);
                        break;
-                   case "CONSTRUCTOR":
                    case "FIELD":
-                       test( 8,  0, 0, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, src3);
-                       test( 8,  0, 0, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, src8);
-                       test( 6,  0, 0, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, src9);
-                       test( 0,  8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, src3);
-                       test( 0,  8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, src8);
-                       test( 0,  6, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, src9);
+                       test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src1);
+                       test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src2);
+                       test( 6, 0, 0, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src3);
+                       test( 2, 0, 2, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src4);
+                       test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
+                       test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src2);
+                       test( 0, 6, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src3);
+                       test( 0, 2, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src4);
                        break;
                    default:/*TYPE,PARAMETER,LOCAL_VARIABLE,ANNOTATION_TYPE,PACKAGE*/
+                       test( 0, 2, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src4);
+                       test( 0, 2, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src5);
                        break;
                }
             }
@@ -84,7 +106,7 @@
 
     public void test(int tinv, int tvis, int inv, int vis, Boolean Arepeats,
                      Boolean BDrepeats, Boolean ABmix, String rtn, String et2,
-                     Integer N, int source) throws Exception {
+                     Integer N, srce source) throws Exception {
         ++testcount;
         expected_tvisibles = tvis;
         expected_tinvisibles = tinv;
@@ -97,14 +119,19 @@
                 ", tvis=" + tvis + ", inv=" + inv + ", vis=" + vis +
                 ", Arepeats=" + Arepeats + ", BDrepeats=" + BDrepeats +
                 ", ABmix=" + ABmix + ", retention: " + rtn + ", anno2: " +
-                et2 + ", src=" + source;
+                et2 + ", src=" + source + "\n    " + source.description;
 
-// Uncomment this block to run the tests but skip failing scenarios.
-//        // 8005681 - skip cases with repeated annotations on new, array, cast.
-//        if((source==3 || source==8 || source==9) && (ABmix || (Arepeats && BDrepeats))) {
-//            System.out.println(testDef+"\n8005681-skip repeated annotations on new,array,cast");
-//            return;
-//        }
+        if(
+// 8005681 - src1,2,3 - skip cases with repeated annotations on new, array, cast.
+            (( source.equals(srce.src1) || source.equals(srce.src2) ||
+              source.equals(srce.src3)) && (ABmix || (Arepeats && BDrepeats)))
+ // 8008928 - src4,5 - this change cause crash with t-a on anon class)
+            || (source.equals(srce.src4) || source.equals(srce.src5))
+          ) {
+            System.out.println(testDef +
+                       "\n    8005681-skip repeated annotations on new,array,cast");
+            return;
+        }
 
         println(testDef);
         // Create test source and File.
@@ -123,6 +150,7 @@
         if(hasInnerClass) {
             StringBuffer sb = new StringBuffer(classFile.getAbsolutePath());
             classFile=new File(sb.insert(sb.lastIndexOf(".class"),innerClassname).toString());
+            println("classfile: " + classFile.getAbsolutePath());
         }
         ClassFile cf = ClassFile.read(classFile);
 
@@ -130,10 +158,16 @@
         test(cf);
 
         for (Field f : cf.fields) {
-            test(cf, f);
+            if(source.local)
+                test(cf, f, true);
+            else
+                test(cf,f);
         }
         for (Method m: cf.methods) {
-            test(cf, m);
+            if(source.local)
+                test(cf, m, true);
+            else
+                test(cf, m);
         }
         countAnnotations();
         if (errors > 0) {
@@ -149,7 +183,7 @@
     //
     String sourceString(String testname, String retentn, String annot2,
                         Boolean Arepeats, Boolean BDrepeats, Boolean ABmix,
-                        int src) {
+                        srce src) {
 
         String As = "@A", Bs = "@B", Ds = "@D";
         if(Arepeats) As = "@A @A";
@@ -198,7 +232,7 @@
 
         // Test case sources with sample generated source
         switch(src) {
-            case 3: // (repeating) type annotations on field in method body
+            case src1: // (repeating) type annotations on field in method body
                     /*
                      * class Test1 {
                      * Test1(){}
@@ -210,18 +244,19 @@
                      * }}
                       */
                 source = new String(
-                "class " + testname + " {\n" +
-                "" + testname +"(){} \n" +
-                "// type usage in method body \n" +
-                "String test("+testname+" this, " +
-                   "String param, String ... vararg) { \n" +
-                "    _As_ _Bs_\n    Object o = new _As_ _Bs_  String _As_ _Bs_  [3]; \n" +
-                "        return (_As_ _Bs_  String) null; \n" +
-                "} \n" +
-                "} \n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
-                "\n\n";
-                break;
-            case 8: // (repeating) annotations on type parameters, bounds and  type arguments in new statement.
+                    "// " + src.description + "\n" +
+                    "class " + testname + " {\n" +
+                    "" + testname +"(){} \n" +
+                    "// type usage in method body \n" +
+                    "String test("+testname+" this, " +
+                       "String param, String ... vararg) { \n" +
+                    "    _As_ _Bs_\n    Object o = new _As_ _Bs_  String _As_ _Bs_  [3]; \n" +
+                    "        return (_As_ _Bs_  String) null; \n" +
+                    "} \n" +
+                    "} \n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+                    "\n\n";
+                    break;
+            case src2: // (repeating) annotations on type parameters, bounds and  type arguments in new statement.
                     /*
                      * class Test2<T extends Object> {
                      *     Map<List<String>, Integer> map =
@@ -232,17 +267,17 @@
                      * }
                      */
                 source = new String( source +
-                "// (repeating) annotations on type parameters, bounds and  type arguments. \n" +
-                "class " + testname + "<T extends Object> {\n" +
-                "    Map<List<String>, Integer> map =\n" +
-                "        new HashMap<_As_ _Bs_ List<_As_ _Bs_ String>, _As_ _Bs_ Integer>();\n" +
-                "    Map<List<String>, Integer> map2 = new _As_ _Bs_ HashMap<>();\n" +
-                "    String test(" + testname + "<T> this) { return null;}\n" +
-                "    <T> String genericMethod(T t) { return null; }\n" +
-                "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
-                "\n\n";
-            break;
-            case 9: // (repeating)annotations on type parameters of class, method return value in method.
+                    "// " + src.description + "\n" +
+                    "class " + testname + "<T extends Object> {\n" +
+                    "    Map<List<String>, Integer> map =\n" +
+                    "        new HashMap<_As_ _Bs_ List<_As_ _Bs_ String>, _As_ _Bs_ Integer>();\n" +
+                    "    Map<List<String>, Integer> map2 = new _As_ _Bs_ HashMap<>();\n" +
+                    "    String test(" + testname + "<T> this) { return null;}\n" +
+                    "    <T> String genericMethod(T t) { return null; }\n" +
+                    "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+                    "\n\n";
+                break;
+            case src3: // (repeating)annotations on type parameters of class, method return value in method.
                     /*
                      * class Test3{
                      *     <E extends Comparable> Map<List<E>, E > foo(E e) {
@@ -258,24 +293,72 @@
                      * }
                      */
                 source = new String( source +
-                "// (repeating)annotations on type parameters of class, method return value in method. \n" +
-                "class "+ testname + "{\n" +
-                "    <E extends Comparable> Map<List<E>, E > foo(E e) {\n" +
-                "        class maptest <E> {\n" +                  // inner class $1maptest
-                "            Map<List<E>,E> getMap() { \n" +
-                "                Map<List<E>,E> Em = new HashMap<List<_As_ _Bs_ _Ds_ E>,_As_ _Bs_ _Ds_ E>();\n" +
-                "                return Em;\n" +
-                "            }\n" +
-                "        }\n" +
-                "        return new maptest<E>().getMap();\n" +
-                "   }\n" +
-                "   Map<List<String>,String> shm = foo(new String(\"hello\"));\n" +
-                "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
-                "\n\n";
-                hasInnerClass=true;
-                innerClassname="$1maptest";
-            break;
-
+                    "// " + src.description + "\n" +
+                    "class "+ testname + "{\n" +
+                    "    <E extends Comparable> Map<List<E>, E > foo(E e) {\n" +
+                    "        class maptest <E> {\n" +                  // inner class $1maptest
+                    "            Map<List<E>,E> getMap() { \n" +
+                    "                Map<List<E>,E> Em = new HashMap<List<_As_ _Bs_ _Ds_ E>,_As_ _Bs_ _Ds_ E>();\n" +
+                    "                return Em;\n" +
+                    "            }\n" +
+                    "        }\n" +
+                    "        return new maptest<E>().getMap();\n" +
+                    "   }\n" +
+                    "   Map<List<String>,String> shm = foo(new String(\"hello\"));\n" +
+                    "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
+                    "\n\n";
+                    hasInnerClass=true;
+                    innerClassname="$1maptest";
+                break;
+            case src4: // (repeating)annotations on field in anonymous class
+                    /*
+                     * class Test95{
+                     *     void mtest( Test95 t){  }
+                     *     public void test() {
+                     *         mtest( new Test95() {
+                     *             @A @A @B @B String data2 = "test";
+                     *         });
+                     *     }
+                     * }
+                     */
+                source = new String( source +
+                    "// " + src.description + "\n" +
+                    "class "+ testname + "{\n" +
+                    "    void mtest( "+ testname + " t){  }\n" +
+                    "    public void test() {\n" +
+                    "        mtest( new "+ testname + "() {\n" +
+                    "            _As_ _Bs_ String data2 = \"test\";\n" +
+                    "        });\n" +
+                    "    }\n" +
+                    "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+                    "\n\n";
+                    hasInnerClass=true;
+                    innerClassname="$1";
+                break;
+            case src5: // (repeating)annotations on method in anonymous class
+                    /*
+                     * class Test120{
+                     *     void mtest( Test120 t){  }
+                     *     public void test() {
+                     *         mtest( new Test120() {
+                     *             @A @B @A @B String m2(){return null;};
+                     *         });
+                     *     }
+                     */
+                source = new String( source +
+                    "// " + src.description + "\n" +
+                    "class "+ testname + "{\n" +
+                    "    void mtest( "+ testname + " t){  }\n" +
+                    "    public void test() {\n" +
+                    "        mtest( new "+ testname + "() {\n" +
+                    "            _As_ _Bs_ String m2(){return null;};\n" +
+                    "        });\n" +
+                    "    }\n" +
+                    "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+                    "\n\n";
+                    hasInnerClass=true;
+                    innerClassname="$1";
+                break;
         }
         return imports + source;
     }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest3.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest3.java
new file mode 100644
index 0000000..ee1ad3a
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest3.java
@@ -0,0 +1,539 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8005085 8005681 8008769 8010015
+ * @summary Check (repeating)type annotations on lambda usage.
+ * @run main CombinationsTargetTest3
+ */
+
+import com.sun.tools.classfile.*;
+import java.io.File;
+import java.util.Vector;
+
+public class CombinationsTargetTest3 extends ClassfileTestHelper {
+
+    // Helps identify test case in event of failure.
+    int testcount = 0;
+
+    // Known failure cases due to open bugs.
+    Vector<String> skippedTests = new Vector<>();
+    void printSkips() {
+        if(!skippedTests.isEmpty()) {
+            println(skippedTests.size() + " tests were skipped:");
+            for(String t : skippedTests)
+                println("    " + t);
+        }
+    }
+
+    // Test case descriptions and expected annotation counts.
+    enum srce  {
+        src1("type annotations on lambda expression as method arg.",4,0),
+        src2("type annotations on new in single line lambda expression",2,0),
+        src3("type annotations in lambda expression code block",4,0),
+        src4("type annotations in code block with recursion,cast",2,0),
+        src5("type annotations in lambda expression code block",4,0),
+        src6("type annotations on type parm in method reference",4,0),
+        src7("type annotations on inner class field of lambda expression",2,2),
+        src8("type annotations in inner class of lambda expression",4,2),
+        src9("type annotations on static method of interface",4,2);
+
+        String description;
+        // Expected annotation counts are same for Vis or Invis, but which one
+        // depends on retention type.
+        Integer[] exp = { 0, 0 };
+
+        // If class to test is inner class, this may be set in SourceString()
+        String innerClassname = null ;
+
+        // If class to test is not main or inner class; set in sourceString()
+        String altClassName = null;
+
+        srce(String desc, int e1, int e2) {
+            description = this + ": " +desc;
+            exp[0]=e1;
+            exp[1]=e2;
+        }
+    }
+
+    // Check for RuntimeInvisible or RuntimeVisible annotations.
+    String[] RType={"CLASS", "RUNTIME"};
+
+    // This can be a compile only test.
+    static boolean compileonly=false;
+
+    // Collect failure for end of test report()
+    Vector<String> vFailures = new Vector<>();
+
+    // pass/fail determined after all tests have run.
+    void report() {
+        if(vFailures.isEmpty()) {
+            printSkips();
+            println("PASS");
+        } else {
+           System.err.println("FAILED: There were failures:");
+           for(String f : vFailures)
+               System.err.println(f);
+           throw new RuntimeException("There were failures. See test log.");
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        if(args.length>0 && args[0].compareTo("compileonly")==0)
+            compileonly=true;
+        new CombinationsTargetTest3().run();
+    }
+
+    void run() throws Exception {
+        // Determines which repeat and order in source(ABMix).
+        Boolean As= false, BDs=true, ABMix=false;
+        int testrun=0;
+        // A repeats and/or B/D repeats, ABMix for order of As and Bs.
+        Boolean [][] bRepeat = new Boolean[][]{{false,false,false}, //no repeats
+                                               {true,false,false}, //repeat @A
+                                               {false,true,false}, //repeat @B
+                                               {true,true,false},  //repeat both
+                                               {false,false,true}  //repeat mix
+        };
+        // Added ElementType's. All set; not permuted (so far) for this test
+        String et = "TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE";
+
+        // test loop
+        for(Boolean[] bCombo : bRepeat) {
+            As=bCombo[0]; BDs=bCombo[1]; ABMix=bCombo[2];
+            for(srce src : srce.values())
+                for( String rtype : RType ) {
+                   switch( rtype ) {
+                       case "RUNTIME":
+                           test(0,src.exp[0],0,src.exp[1],As, BDs, ABMix,
+                                "RUNTIME", et, ++testrun, src);
+                           break;
+                       case "CLASS":
+                           test(src.exp[0],0,src.exp[1],0,As, BDs, ABMix,
+                                "CLASS", et, ++testrun, src);
+                           break;
+                }
+            }
+        }
+        report();
+    }
+
+    // Filter out skipped cases, compile, pass class file to test method,
+    // count annotations and asses results.
+    public void test(int tinv, int tvis, int inv, int vis, Boolean Arepeats,
+                     Boolean BDrepeats, Boolean ABmix, String rtn, String et2,
+                     Integer N, srce source) throws Exception {
+        ++testcount;
+        expected_tvisibles = tvis;
+        expected_tinvisibles = tinv;
+        expected_visibles = vis;
+        expected_invisibles = inv;
+        File testFile = null;
+        String tname="Test" + N.toString();
+        String testDef = "Test " + testcount + " parameters: tinv=" + tinv +
+                ", tvis=" + tvis + ", inv=" + inv + ", vis=" + vis +
+                ", Arepeats=" + Arepeats + ", BDrepeats=" + BDrepeats +
+                ", ABmix=" + ABmix + ", retention: " + rtn + ", anno2: " +
+                et2 + ", src=" + source;
+
+        // Skip failing cases with bug ID's
+        if ((source.equals(srce.src2) || source.equals(srce.src4) ||
+            source.equals(srce.src5)) &&
+            (ABmix || (Arepeats && BDrepeats))) {
+                skippedTests.add(testDef +
+                  "\n--8005681 repeated type-annotations on new/cast/array in" +
+                  " inner class in lambda expression.");
+            return;
+        }//8008769 Repeated type-annotations on type parm of local variable
+         else if (source.equals(srce.src6) &&
+                   (ABmix || (Arepeats && BDrepeats))) {
+            skippedTests.add(testDef +  "\n--8008769 Repeated " +
+                             "type-annotations on type parm of local variable");
+            return;
+        }
+
+        println(testDef);
+        // Create test source and File.
+        String sourceString = sourceString(tname, rtn, et2, Arepeats,
+                                           BDrepeats, ABmix, source);
+        testFile = writeTestFile(tname+".java", sourceString);
+        // Compile test source and read classfile.
+        File classFile = null;
+        try {
+            classFile = compile(testFile);
+            System.out.println("pass compile: " + tname + ".java");
+        } catch (Error err) {
+            System.err.println("fail compile. Source:\n" + sourceString);
+            throw err;
+        }
+        if(!compileonly) {
+            //check if innerClassname is set
+            String classdir = classFile.getAbsolutePath();
+            if(source.innerClassname != null) {
+                StringBuffer sb = new StringBuffer(classdir);
+                classFile=new File(sb.insert(sb.lastIndexOf(".class"),
+                                   source.innerClassname).toString());
+                source.innerClassname=null;
+            } else if (source.altClassName != null) {
+                classdir = classdir.substring(0,classdir.lastIndexOf("Test"));
+                classFile=new File(classdir.concat(source.altClassName));
+                source.innerClassname=null;
+            }
+            ClassFile cf = ClassFile.read(classFile);
+
+            println("Testing classfile: " + cf.getName());
+            //Test class,fields and method counts.
+            test(cf);
+
+            for (Field f : cf.fields) {
+                test(cf, f);
+                test(cf, f, true);
+            }
+            for (Method m: cf.methods) {
+                test(cf, m);
+                test(cf, m, true);
+            }
+
+            countAnnotations(); // sets errors=0 before counting.
+            if (errors > 0) {
+                System.err.println( testDef );
+                System.err.println( "Source:\n" + sourceString );
+                vFailures.add(testDef);
+            }
+        }
+        if(errors==0) println("Pass"); println("");
+    }
+
+    /*
+     * Source definitions for test cases.
+     * To add a test:
+     *   Add enum to srce(near top of file) with expected annotation counts.
+     *   Add source defintion below.
+     */
+    String sourceString(String testname, String retentn, String annot2,
+                        Boolean Arepeats, Boolean BDrepeats, Boolean ABmix,
+                        srce src) {
+
+        String As = "@A", Bs = "@B", Ds = "@D";
+        if(Arepeats) As = "@A @A";
+        if(BDrepeats) {
+            Bs = "@B @B";
+            Ds = "@D @D";
+        }
+        if(ABmix) { As = "@A @B"; Bs = "@A @B"; Ds = "@D @D"; }
+
+        // Source to check for TYPE_USE and TYPE_PARAMETER annotations.
+        // Source base (annotations) is same for all test cases.
+        String source = new String();
+        String imports = new String("import java.lang.annotation.*; \n" +
+            "import static java.lang.annotation.RetentionPolicy.*; \n" +
+            "import static java.lang.annotation.ElementType.*; \n" +
+            "import java.util.List; \n" +
+            "import java.util.ArrayList;\n\n");
+
+            String sourceBase = new String(
+            "@Retention("+retentn+") @Target({TYPE_USE,_OTHER_}) @Repeatable( AC.class ) @interface A { }\n" +
+            "@Retention("+retentn+") @Target({TYPE_USE,_OTHER_}) @interface AC { A[] value(); } \n" +
+            "@Retention("+retentn+") @Target({TYPE_USE,_OTHER_}) @Repeatable( BC.class ) @interface B { }\n" +
+            "@Retention("+retentn+") @Target({TYPE_USE,_OTHER_}) @interface BC { B[] value(); } \n" +
+            "@Retention("+retentn+") @Target({TYPE_USE,TYPE_PARAMETER,_OTHER_}) @Repeatable(DC.class) @interface D { }\n" +
+            "@Retention("+retentn+") @Target({TYPE_USE,TYPE_PARAMETER,_OTHER_}) @interface DC { D[] value(); }");
+
+        // Test case sources with sample generated source
+        switch(src) {
+            case src1: //(repeating) type annotations on lambda expressions.
+                /*
+                 * class Test1 {
+                 * Test1(){}
+                 * interface MapFun<T,R> {  R m( T n); }
+                 * void meth( MapFun<String,Integer> mf ) {
+                 *     assert( mf.m("four") == 4);
+                 * }
+                 * void test(Integer i) {
+                 *     // lambda expression as method arg
+                 *     meth( (@A @B String s) -> { @A @B Integer len = s.length(); return len; } );
+                 * }}
+                 */
+                source = new String( source +
+                "// " + src.description + "\n" +
+                "class " + testname + " {\n" +
+                "  " + testname +"(){} \n" +
+                "  interface MapFun<T,R> {  R m( T n); }\n\n" +
+                "  void meth( MapFun<String,Integer> mf ) {\n" +
+                "    assert( mf.m(\"four\") == 4);\n" +
+                "  }\n\n" +
+                "  void test(Integer i) {\n" +
+                "    // lambda expression as method arg\n" +
+                "    meth( (_As_ _Bs_ String s) -> { _As_ _Bs_ Integer len = s.length(); return len; } );\n" +
+                "}}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+                "\n";
+                break;
+            case src2: //(repeating) type annotations on new in single line lambda expression.
+                /*
+                 * //case2: (repeating) type annotations on new in single lambda expressions.
+                 * class Test2{
+                 *   interface MapFun<T, R> {  R m( T n); }
+                 *   MapFun<Integer, String> its;
+                 * void test(Integer i) {
+                 *   its = a -> "~"+new @A @B Integer(a).toString()+"~";
+                 *   System.out.println("in: " + i + " out: " + its.m(i));
+                 * }}
+                 */
+                source = new String( source +
+                "// " + src.description + "\n" +
+                "class " + testname + "{\n" +
+                "  interface MapFun<T, R> {  R m( T n); }\n" +
+                "  MapFun<Integer, String> its;\n" +
+                "  void test(Integer i) {\n" +
+                "    its = a -> \"~\"+new _As_ _Bs_ Integer(a).toString()+\"~\";\n" +
+                "    System.out.println(\"in: \" + i + \" out: \" + its.m(i));\n" +
+                "  }\n" +
+                "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+                "\n";
+            break;
+            case src3: //(repeating) type annotations in lambda expression code block.
+                /*
+                 * class Test183{
+                 *   interface MapFun<T, R> {  R m( T n); }
+                 *   MapFun<List<Integer>, String> iLs;
+                 *   void testm(Integer i) {
+                 *       iLs = l -> { @A @B @A @B String ret = new String();
+                 *                    for( @A @B @A @B Integer i2 : l)
+                 *                        ret=ret.concat(i2.toString() + " ");
+                 *                    return ret; };
+                 *   List<Integer> li = new ArrayList<>();
+                 *   for(int j=0; j<i; j++) li.add(j);
+                 *   System.out.println(iLs.m(li) );
+                 * }}
+                 */
+                source = new String( source +
+                "// " + src.description + "\n" +
+                "class "+ testname + "{\n" +
+                "  interface MapFun<T, R> {  R m( T n); }\n" +
+                "  MapFun<List<Integer>, String> iLs;\n" +
+                "  void testm(Integer i) {\n" +
+                "    iLs = l -> { _As_ _Bs_ String ret = new String();\n" +
+                "                 for( _As_ _Bs_ Integer i2 : l)\n" +
+                "                   ret=ret.concat(i2.toString() + \" \");\n" +
+                "                 return ret; };\n" +
+                "  List<Integer> li = new ArrayList<>();\n" +
+                "  for(int j=0; j<i; j++) li.add(j);\n" +
+                "  System.out.println(iLs.m(li) );\n" +
+                "}\n" +
+                "\n" +
+                "    public static void main(String... args) {new " + testname + "().testm(5); }\n" +
+                "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+                "\n";
+            break;
+            case src4: //(repeating) type annotations in code block with recursion,cast
+                /*
+                 * class Test194{
+                 *   interface MapFun<T, R> {  R m( T n); }
+                 *   MapFun<Integer, Double>  nf;
+                 *   void testm(Integer i) {
+                 *       nf = j -> { return j == 1 ? 1.0 : (@A @B @A @B  Double)(nf.m(j-1) * j); };
+                 *       System.out.println( "nf.m(" + i + "): " + nf.m(i));
+                 *   }
+                 * }
+                 */
+                source = new String( source +
+                "// " + src.description + "\n" +
+                "class "+ testname + "{\n" +
+                "  interface MapFun<T, R> {  R m( T n); }\n" +
+                "  MapFun<Integer, Double>  nf;\n" +
+                "  void testm(Integer i) {\n" +
+                "    nf = j -> { return j == 1 ? 1.0 : (_As_ _Bs_  Double)(nf.m(j-1) * j); };\n" +
+                "    System.out.println( \"nf.m(\" + i + \"): \" + nf.m(i));\n" +
+                "  }\n" +
+                "  public static void main(String... args) {new " + testname + "().testm(5); }\n" +
+                "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+                "\n";
+            break;
+            case src5: //(repeating) type annotations in lambda expression code block.
+                   /*
+                    * class Test180 {
+                    *   interface MapFun<T, R> {  R m( T n); }
+                    *   MapFun<Integer,List<Integer>> iLi;
+                    *   void test(Integer i) {
+                    *     // type parameter use.
+                    *     iLi = n -> { List<@A @B @A @B Integer> LI = new ArrayList<@A @B @A @B Integer>(n);
+                    *                  for(int nn = n; nn >=0; nn--) LI.add(nn);
+                    *                  return LI; };
+                    *     List<Integer> li = iLi.m(i);
+                    *     for(Integer k : li) System.out.print(k);
+                    *   }
+                    * }
+                    */
+                source = new String( source +
+                "// " + src.description + "\n" +
+                "class "+ testname + "{\n" +
+                "  interface MapFun<T, R> {  R m( T n); }\n" +
+                "  MapFun<Integer,List<Integer>> iLi;\n" +
+                "  void test(Integer i) {\n" +
+                "    // type parameter use.\n" +
+                "    iLi = n -> { List<_As_ _Bs_ Integer> LI = new ArrayList<_As_ _Bs_ Integer>(n);\n" +
+                "                 for(int nn = n; nn >=0; nn--) LI.add(nn);\n" +
+                "                 return LI; };\n" +
+                "    List<Integer> li = iLi.m(i);\n" +
+                "    for(Integer k : li) System.out.print(k);\n" +
+                "}\n" +
+                "  public static void main(String... args) {new " + testname + "().test(5); }\n" +
+                "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
+                "\n";
+            break;
+            case src6: //(repeating) type annotations on type parm in method reference.
+                /*
+                 * class Test240{
+                 *   interface PrintString { void print(String s); }
+                 *   public void printArray(Object[] oa, PrintString ps) {
+                 *       for(Object o : oa ) ps.print(o.toString());
+                 *   }
+                 *   public void test() {
+                 *       Integer[] intarray = {1,2,3,4,5};
+                 *       printArray(intarray, @A @B @A @B TPrint::<@A @B @A @B String>print);
+                 *   }
+                 * }
+                 * class TPrint {
+                 *    public static <T> void print(T t) { System.out.println( t.toString()); }
+                 * }
+                 */
+                source = new String( source +
+                "// " + src.description + "\n" +
+                "class "+ testname + "{\n" +
+                "  interface PrintString { void print(String s); }\n" +
+                "  public void printArray(Object[] oa, PrintString ps) {\n" +
+                "      for(Object o : oa ) ps.print(o.toString());\n" +
+                "  }\n" +
+                "  public void test() {\n" +
+                "    Integer[] intarray = {1,2,3,4,5};\n" +
+                "    printArray(intarray, _As_ _Bs_ TPrint::<_As_ _Bs_ String>print);\n" +
+                "  }\n" +
+                "  public static void main(String... args) {new " + testname + "().test(); }\n" +
+                "}\n\n" +
+                "class TPrint {\n" +
+                "  public static <T> void print(T t) { System.out.println( t.toString()); }\n" +
+                "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+                "\n";
+            break;
+            case src7: //(repeating)type annotations in inner class of lambda expression.
+                /*
+                 * class Test2{
+                 *   interface MapFun<T, R> {  R m( T n); }
+                 *   MapFun<Class<?>,String> cs;
+                 *   void test() {
+                 *     cs = c -> {
+                 *         class innerClass   {
+                 *           @A @B Class<?> icc = null;
+                 *           String getString() { return icc.toString(); }
+                 *         }
+                 *         return new innerClass().getString();
+                 *     };
+                 *     System.out.println("cs.m : " + cs.m(Integer.class));
+                 *   }
+                 * }
+                 */
+                source = new String( source +
+                "// " + src.description + "\n" +
+                "class "+ testname + "{\n" +
+                "  interface MapFun<T, R> {  R m( T n); }\n" +
+                "  MapFun<Class<?>,String> cs;\n" +
+                "  void test() {\n" +
+                "    cs = c -> {\n" +
+                "        class innerClass   {\n" +
+                "          _As_ _Bs_ Class<?> icc = null;\n" +
+                "          innerClass(Class<?> _c) { icc = _c; }\n" +
+                "          String getString() { return icc.toString(); }\n" +
+                "        }\n" +
+                "        return new innerClass(c).getString();\n" +
+                "    };\n" +
+                "    System.out.println(\"cs.m : \" + cs.m(Integer.class));\n" +
+                "  }\n" +
+                "\n" +
+                "    public static void main(String... args) {new " + testname + "().test(); }\n" +
+                "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+                "\n";
+                src.innerClassname="$1innerClass";
+            break;
+            case src8: //(repeating)type annotations in inner class of lambda expression.
+                /*
+                 * class Test2{
+                 *   interface MapFun<T, R> {  R m( T n); }
+                 *   MapFun<Class<?>,String> cs;
+                 *   void test() {
+                 *     cs = c -> {
+                 *         class innerClass   {
+                 *             Class<?> icc;
+                 *             innerClass(@A @B Class<?> _c) { icc = _c; }
+                 *             @A @B String getString() { return icc.toString(); }
+                 *         }
+                 *         return new innerClass(c).getString();
+                 *     };
+                 *     System.out.println("cs.m : " + cs.m(Integer.class));
+                 *   }
+                 * }
+                 */
+                source = new String( source +
+                "// " + src.description + "\n" +
+                "class "+ testname + "{\n" +
+                "  interface MapFun<T, R> {  R m( T n); }\n" +
+                "  MapFun<Class<?>,String> cs;\n" +
+                "  void test() {\n" +
+                "    cs = c -> {\n" +
+                "        class innerClass {\n" +
+                "            Class<?> icc;\n" +
+                "            innerClass(_As_ _Bs_ Class<?> _c) { icc = _c; }\n" +
+                "            _As_ _Bs_ String getString() { return icc.toString(); }\n" +
+                "        }\n" +
+                "        return new innerClass(c).getString();\n" +
+                "    };\n" +
+                "    System.out.println(\"cs.m : \" + cs.m(Integer.class));\n" +
+                "  }\n" +
+                "\n" +
+                "    public static void main(String... args) {new " + testname + "().test(); }\n" +
+                "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+                "\n";
+                src.innerClassname="$1innerClass";
+            break;
+            case src9: //(repeating)type annotations on static method of interface
+                /*
+                 *  class Test90{
+                 *    interface I  {
+                 *      static @A @B @A @B String m() { @A @B @A @B String ret = "I.m"; return ret; }
+                 *    }
+                 *  }
+                 */
+                source = new String( source +
+                "// " + src.description + "\n" +
+                "class "+ testname + "{\n" +
+                "  interface I  { \n" +
+                "    static _As_ _Bs_ String m() { _As_ _Bs_ String ret = \"I.m\"; return ret; }\n" +
+                "  }\n" +
+                "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+                "\n";
+                src.innerClassname="$I";
+            break;
+        }
+        return imports + source;
+    }
+}
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/DeadCode.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/DeadCode.java
index 6d00bcc..afcbd59 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/DeadCode.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/DeadCode.java
@@ -49,7 +49,7 @@
             test(cf, f);
         }
         for (Method m: cf.methods) {
-            test(cf, m);
+            test(cf, m, true);
         }
 
         countAnnotations();
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/NewTypeArguments.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/NewTypeArguments.java
index f39857c..24a8026 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/NewTypeArguments.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/NewTypeArguments.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -48,7 +48,7 @@
             test(cf, f);
         }
         for (Method m: cf.methods) {
-            test(cf, m);
+            test(cf, m, true);
         }
 
         countAnnotations();
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/T8008762.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/T8008762.java
new file mode 100644
index 0000000..046fc0a
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/T8008762.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8008762
+ * @ignore 8013409: test failures for type annotations
+ * @summary Type annotation on inner class in anonymous class
+ *          shows up as regular annotation
+ */
+import java.lang.annotation.*;
+import static java.lang.annotation.RetentionPolicy.*;
+import static java.lang.annotation.ElementType.*;
+
+import com.sun.tools.classfile.*;
+
+public class T8008762 extends ClassfileTestHelper{
+    public static void main(String[] args) throws Exception {
+        new T8008762().run();
+    }
+
+    public void run() throws Exception {
+        expected_tinvisibles = 0;
+        expected_tvisibles = 4;
+
+        ClassFile cf = getClassFile("T8008762$Test$1$InnerAnon.class");
+        test(cf);
+        for (Field f : cf.fields) {
+            test(cf, f, false);
+        }
+        for (Method m : cf.methods) {
+            test(cf, m, false);
+        }
+        countAnnotations();
+
+        if (errors > 0)
+            throw new Exception(errors + " errors found");
+        System.out.println("PASSED");
+    }
+
+    /*********************** Test class *************************/
+    static class Test {
+        Object mtest( Test t){ return null; }
+        public void test() {
+          mtest( new Test() {
+                class InnerAnon { // Test1$1$InnerAnon.class
+                  @A @B String ai_data = null;
+                  @A @B String ai_m(){ return null; };
+                }
+               InnerAnon IA = new InnerAnon();
+            });
+        }
+        @Retention(RUNTIME) @Target(TYPE_USE) @interface A { }
+        @Retention(RUNTIME) @Target(TYPE_USE) @interface B { }
+    }
+}
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/T8008769.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/T8008769.java
new file mode 100644
index 0000000..a727a67
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/T8008769.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * @test
+ * @summary Repeated type-annotations on type parm of local variable
+ *          are not written to classfile.
+ * @bug 8008769
+ */
+import java.lang.annotation.*;
+import static java.lang.annotation.RetentionPolicy.*;
+import static java.lang.annotation.ElementType.*;
+import com.sun.tools.classfile.*;
+
+public class T8008769 extends ClassfileTestHelper{
+    public static void main(String[] args) throws Exception {
+        new T8008769().run();
+    }
+
+    public void run() throws Exception {
+        expected_tvisibles = 4;
+        ClassFile cf = getClassFile("T8008769$Test.class");
+        for (Method m : cf.methods) {
+            test(cf, m, true);
+        }
+        countAnnotations();
+
+        if (errors > 0)
+            throw new Exception(errors + " errors found");
+        System.out.println("PASSED");
+    }
+
+    /*********************** Test class *************************/
+    static class Test<T> {
+        public void test() {
+            Test<@A @B String>    t0 = new Test<>(); // 2 ok
+            Test<@B @B String>    t1 = new Test<>(); // 1 missing
+            Test<@A @A @A String> t2 = new Test<>(); // 1 missing
+       }
+    }
+    @Retention(RUNTIME) @Target(TYPE_USE) @Repeatable( AC.class ) @interface A { }
+    @Retention(RUNTIME) @Target(TYPE_USE) @Repeatable( BC.class ) @interface B { }
+    @Retention(RUNTIME) @Target(TYPE_USE) @interface AC { A[] value(); }
+    @Retention(RUNTIME) @Target(TYPE_USE) @interface BC { B[] value(); }
+}
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/T8010015.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/T8010015.java
new file mode 100644
index 0000000..72029a8
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/T8010015.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Wrong classfile attribution in inner class of lambda expression.
+ * @bug 8010015
+ */
+
+import java.lang.annotation.*;
+import static java.lang.annotation.RetentionPolicy.*;
+import static java.lang.annotation.ElementType.*;
+import com.sun.tools.classfile.*;
+
+/*
+ * A type-annotations on a field in an inner class not in a lambda expression
+ * results in RuntimeTypeAnnotations_attibute and RuntimeAnnotations_attribute.
+ * On a field in an innner class in a lambda expression, it leaves off the
+ * RuntimeAnnotations_attribute.
+ */
+public class T8010015 extends ClassfileTestHelper{
+    public static void main(String[] args) throws Exception {
+        new T8010015().run();
+    }
+
+    public void run() throws Exception {
+        expected_tvisibles = 1;
+        expected_visibles = 1;
+        ClassFile cf = getClassFile("T8010015$Test$1innerClass.class");
+        for (Field f : cf.fields) {
+            test(cf, f);
+        }
+        countAnnotations();
+
+        if (errors > 0)
+            throw new Exception(errors + " errors found");
+        System.out.println("PASSED");
+    }
+
+    /*********************** Test class **************************/
+    interface MapFun<T, R> { R m( T n); }
+    static class Test {
+        MapFun<Class<?>,String> cs;
+        void test() {
+            cs = c -> {
+                     class innerClass {
+                         @A Class<?> icc = null;
+                         innerClass(Class<?> _c) { icc = _c; }
+                         String getString() { return icc.toString(); }
+                     }
+                     return new innerClass(c).getString();
+            };
+            System.out.println("cs.m : " + cs.m(Integer.class));
+        }
+
+    public static void main(String... args) {new Test().test(); }
+    }
+    @Retention(RUNTIME) @Target({TYPE_USE,FIELD}) @interface A { }
+}
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/TestNewCastArray.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/TestNewCastArray.java
new file mode 100644
index 0000000..c91924d
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/TestNewCastArray.java
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8005681
+ * @summary Repeated annotations on new,array,cast.
+ */
+import java.lang.annotation.*;
+import java.io.*;
+import java.util.List;
+import com.sun.tools.classfile.*;
+
+import java.lang.annotation.*;
+import static java.lang.annotation.RetentionPolicy.*;
+import static java.lang.annotation.ElementType.*;
+
+public class TestNewCastArray {
+    int errors = 0;
+    List<String> failedTests = new java.util.LinkedList<>();
+
+    // 'b' tests fail with only even numbers of annotations (8005681).
+    String[] testclasses = {"Test1",
+        "Test2a", "Test3a", "Test4a", "Test5a",
+        "Test2b", "Test3b", "Test4b", "Test5b"
+    };
+
+    public static void main(String[] args) throws Exception {
+        new TestNewCastArray().run();
+    }
+
+    void check(String testcase, int expected, int actual) {
+        String res = testcase + ": (expected) " + expected + ", " + actual + " (actual): ";
+        if(expected == actual) {
+            res = res.concat("PASS");
+        } else {
+            errors++;
+            res = res.concat("FAIL");
+            failedTests.add(res);
+        }
+        System.out.println(res);
+    }
+
+    void report() {
+        if(errors!=0) {
+            System.err.println("Failed tests: " + errors +
+                                   "\nfailed test cases:\n");
+            for(String t: failedTests)
+                System.err.println("  " + t);
+           throw new RuntimeException("FAIL: There were test failures.");
+           } else
+            System.out.println("PASS");
+    }
+
+    void test(String clazz, String ttype, ClassFile cf, Method m, Field f,
+              String name, boolean codeattr) {
+        int actual = 0;
+        int expected = 0, cexpected = 0;
+        int index = 0;
+        String memberName = null;
+        Attribute attr = null;
+        Code_attribute cAttr = null;
+        String testcase = "undefined";
+        try {
+        switch(ttype) {
+            case "METHOD":
+                index = m.attributes.getIndex(cf.constant_pool, name);
+                memberName = m.getName(cf.constant_pool);
+                if(index != -1)
+                    attr = m.attributes.get(index);
+                break;
+            case "MCODE":
+                memberName = m.getName(cf.constant_pool);
+                //fetch index of and code attribute and annotations from code attribute.
+                index = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
+                if(index!= -1) {
+                    attr = m.attributes.get(index);
+                    assert attr instanceof Code_attribute;
+                    cAttr = (Code_attribute)attr;
+                    index = cAttr.attributes.getIndex(cf.constant_pool, name);
+                    if(index!= -1)
+                        attr = cAttr.attributes.get(index);
+                }
+                break;
+            case "FIELD":
+                index = f.attributes.getIndex(cf.constant_pool, name);
+                memberName = f.getName(cf.constant_pool);
+                if(index != -1)
+                    attr = f.attributes.get(index);
+                break;
+            case "CODE":
+                memberName = f.getName(cf.constant_pool);
+                //fetch index of and code attribute and annotations from code attribute.
+                index = cf.attributes.getIndex(cf.constant_pool, Attribute.Code);
+                if(index!= -1) {
+                    attr = cf.attributes.get(index);
+                    assert attr instanceof Code_attribute;
+                    cAttr = (Code_attribute)attr;
+                    index = cAttr.attributes.getIndex(cf.constant_pool, name);
+                    if(index!= -1)
+                        attr = cAttr.attributes.get(index);
+                }
+                break;
+            default:
+                break;
+        }
+        } catch(ConstantPoolException cpe) { cpe.printStackTrace(); }
+        testcase = clazz+" "+ttype + ": " + memberName + ", " + name;
+        if(index != -1) {
+            //count RuntimeTypeAnnotations
+            assert attr instanceof RuntimeTypeAnnotations_attribute;
+            RuntimeTypeAnnotations_attribute tAttr =
+                    (RuntimeTypeAnnotations_attribute)attr;
+                actual += tAttr.annotations.length;
+        }
+        if(memberName.compareTo("<init>")==0) memberName=clazz+memberName;
+        switch ( memberName ) {
+            //METHOD:
+            case "Test1<init>": expected=0; break;
+            case "testr22_22": expected=4; break;
+            case "testr11_11": expected=4; break;
+            case "testr12_21": expected=4; break;
+            case "testr20_02": expected=2; break;
+
+            case "Test2a<init>": cexpected=0; break;
+            case "test00_00_11_11": cexpected=4; break;
+            case "test21_12_21_12": cexpected=8; break;
+            case "test_new1": cexpected=2; break;
+            case "test_new2": cexpected=2; break;
+            case "test_cast1": cexpected=2; break;
+            case "test_cast2": cexpected=2; break;
+
+            case "Test2b<init>": cexpected=0; break;
+            case "test20_02_20_02": cexpected=4; break;
+            case "test22_22_22_22": cexpected=8; break;
+            case "test_new3": cexpected=1; break;
+            case "test_new4": cexpected=1; break;
+            case "test_new5": cexpected=2; break;
+            case "test_cast3": cexpected=1; break;
+            case "test_cast4": cexpected=2; break;
+
+            case "Test3a<init>": cexpected=10; break;
+            case "SA_21_12c": cexpected = 0; break;
+            case "SA_01_10c": expected = 0; break;
+            case "SA_11_11c": expected = 0; break;
+
+            case "Test3b<init>": cexpected=6; break;
+            case "SA_22_22c": cexpected = 0; break;
+            case "SA_20_02c": cexpected = 0; break;
+
+            case "Test3c<init>": cexpected=8; break;
+            case "SA_10_10": cexpected = 0; break;
+            case "SA_10_01": cexpected = 0; break;
+            case "SA_21_12": cexpected = 0; break;
+
+            case "Test3d<init>": cexpected=6; break;
+            case "SA_20_02": cexpected = 0; break;
+            case "SA_22_22": cexpected = 0; break;
+
+            case "Test4a<init>": cexpected=4; break;
+            case "nS_21": cexpected = 0; break;
+            case "nS_12": cexpected = 0; break;
+
+            case "Test4b<init>": cexpected=4; break;
+            case "nS20":  cexpected = 0; break;
+            case "nS02":  cexpected = 0; break;
+            case "nS22":  cexpected = 0; break;
+
+            case "Test5a<init>": cexpected=4; break;
+            case "ci11": expected = 0; break;
+            case "ci21": expected = 0; break;
+
+            case "Test5b<init>": cexpected=3; break;
+            case "ci2":  expected = 0; break;
+            case "ci22": expected = 0; break;
+
+            default: expected = 0; break;
+        }
+        if(codeattr)
+            check(testcase, cexpected, actual);
+        else
+            check(testcase, expected, actual);
+    }
+
+    public void run() {
+        ClassFile cf = null;
+        InputStream in = null;
+        for( String clazz : testclasses) {
+            String testclazz = "TestNewCastArray$" + clazz + ".class";
+            System.out.println("Testing " + testclazz);
+            try {
+                in = getClass().getResource(testclazz).openStream();
+                cf = ClassFile.read(in);
+                in.close();
+            } catch(Exception e) { e.printStackTrace();  }
+
+            if(clazz.startsWith("Test1")) {
+                for (Field f: cf.fields)
+                    test(clazz, "FIELD", cf, null, f, Attribute.RuntimeVisibleTypeAnnotations, false);
+                for (Method m: cf.methods)
+                    test(clazz, "METHOD", cf, m, null, Attribute.RuntimeVisibleTypeAnnotations, false);
+            } else {
+                for (Field f: cf.fields)
+                    test(clazz, "CODE", cf, null, f, Attribute.RuntimeVisibleTypeAnnotations, true);
+                for (Method m: cf.methods)
+                    test(clazz, "MCODE", cf, m, null, Attribute.RuntimeVisibleTypeAnnotations, true);
+            }
+        }
+        report();
+    }
+
+    //////// test class //////////////////////////
+    // "Test1" not in code attribute.
+    // on arrays on and in method return
+    static class Test1 {
+        Test1(){}
+        // OK expect 5, got 5
+        String @A @A @B @B[] @A @A @B @B [] testr22_22(Test1 this, String param, String ... vararg) {
+            String [][] sarray = new String [2][2];
+            return sarray;
+        }
+        // OK expect 5, got 5
+        String @A @B [] @A @B [] testr11_11(Test1 this, String param, String ... vararg) {
+            String [][] sarray = new String [2][2];
+            return sarray;
+        }
+        // OK expect 5, got 5
+        String @A @B @B []@B @B @A[] testr12_21(Test1 this, String param, String ... vararg) {
+            String [][] sarray = new String [2][2];
+            return sarray;
+        }
+        // OK expect 3, got 3
+        String @A @A [] @B @B [] testr20_02(Test1 this, String param, String ... vararg) {
+            String [][] sarray = new String [2][2];
+            return sarray;
+        }
+    }
+
+    // Inside method body (in method's code attribute)
+    static class Test2a {
+        Test2a(){}
+        Object o = new Integer(1);
+        // expect 4
+        String[][] test00_00_11_11(Test2a this, String param, String ... vararg) {
+            String [] [] sarray = new String @A @B[2] @A @B [2];
+            return sarray;
+        }
+
+        // expect 8
+        String[][] test21_12_21_12(Test2a this, String param, String ... vararg) {
+            String @A @A @B [] @A @B @B [] sarray = new String @A @A @B[2] @A @B @B [2];
+            return sarray;
+        }
+
+        void test_new1() { String nS_21 = new @A @A @B String("Hello");   }
+        void test_new2() { String nS_12 = new @A @B @B String("Hello");   }
+        void test_cast1() { String tcs11 = (@A @B String)o;      }
+        void test_cast2() { String tcs21 = (@A @A @B String)o;   }
+    }
+
+    static class Test2b {
+        Test2b(){}
+        Object o = new Integer(1);
+        // expect 4
+        String[][] test20_02_20_02(Test2b this, String param, String ... vararg) {
+            String @A @A [] @B @B [] sarray = new String @A @A[2] @B @B [2];
+            return sarray;
+        }
+
+        // expect 8
+        String[][] test22_22_22_22(Test2b this, String param, String ... vararg) {
+            String @A @A @B @B [] @A @A @B @B [] sarray = new String @A @A @B @B [2] @A @A @B @B [2];
+            return sarray;
+        }
+
+        void test_new3() { String nS20 = new @A @A String("Hello");       }
+        void test_new4() { String nS02 = new @B @B String("Hello");       }
+        void test_new5() { String nS22 = new @A @A @B @B String("Hello"); }
+        void test_cast3() { String tcs2 =  (@A @A String)o;      }
+        void test_cast4() { String tcs22 = (@A @A @B @B String)o;}
+    }
+
+    // array levels
+    static class Test3a {
+        Test3a(){}
+        // expect 4+2+4=10
+        String [][] SA_21_12c  = new  String @A @A @B [2] @A @B @B[2];
+        String [][] SA_01_10c  = new  String @B [2] @A [2];
+        String [][] SA_11_11c = new  String @A @B [2] @A @B [2];
+    }
+
+    static class Test3b {
+        Test3b(){}
+        // expect 4+2=6
+        String [][] SA_22_22c  = new  String @A @A @B @B[2] @A @A @B @B[2];
+        String [][] SA_20_02c  = new  String @A @A [2] @B @B[2];
+    }
+    static class Test3c {
+        Test3c(){}
+        // OK expect 4
+        String @A [] @A[] SA_10_10  = new  String [2][2];
+        String @A [] @B[] SA_10_01  = new  String [2][2];
+        String @A @A @B[] @A @B @B [] SA_21_12  = new  String [2][2];
+    }
+
+    static class Test3d {
+        Test3d(){}
+        // OK expect 4
+        String @A @A [] @B @B [] SA_20_02  = new  String [2][2];
+        String @A @A @B @B[] @A @A @B @B [] SA_22_22  = new  String [2][2];
+    }
+
+    // on new
+    static class Test4a {
+        Test4a(){}
+        // expect 2+2=4
+        String nS_21 = new @A @A @B String("Hello");
+        String nS_12 = new @A @B @B String("Hello");
+    }
+
+    static class Test4b {
+        Test4b(){}
+        // expect 1+1+2=4
+        String nS20 = new @A @A String("Hello");
+        String nS02 = new @B @B String("Hello");
+        String nS22 = new @A @A @B @B String("Hello");
+    }
+
+    // Cast expressions
+    static class Test5a {
+        Test5a(){}
+        Object o = new Integer(1);
+        // expect 2+2=4
+        Integer ci11 = (@A @B Integer)o;       // OK expect 3, got 3
+        Integer ci21 = (@A @A @B Integer)o;    // OK expect 3, got 3
+    }
+
+    static class Test5b {
+        Test5b(){}
+        Object o = new Integer(1);
+        // Cast expressions
+        // expect 1+2=3
+        Integer ci2 =  (@A @A Integer)o;       // FAIL expect 2, got 1
+        Integer ci22 = (@A @A @B @B Integer)o; // FAIL expect 3, got 1
+    }
+
+@Retention(RUNTIME) @Target({TYPE_USE}) @Repeatable( AC.class ) @interface A { }
+@Retention(RUNTIME) @Target({TYPE_USE}) @Repeatable( BC.class ) @interface B { }
+@Retention(RUNTIME) @Target({FIELD}) @Repeatable( FC.class ) @interface F { }
+@Retention(RUNTIME) @Target({TYPE_USE}) @interface AC { A[] value(); }
+@Retention(RUNTIME) @Target({TYPE_USE}) @interface BC { B[] value(); }
+@Retention(RUNTIME) @Target({FIELD}) @interface FC { F[] value(); }
+
+}
+
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/TypeCasts.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/TypeCasts.java
index 5529fa5..017e75b 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/TypeCasts.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/TypeCasts.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -50,7 +50,7 @@
             test(cf, f);
         }
         for (Method m: cf.methods) {
-            test(cf, m);
+            test(cf, m, true);
         }
 
         countAnnotations();
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/Wildcards.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/Wildcards.java
index e030152..6ae292f 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/Wildcards.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/Wildcards.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -48,7 +48,7 @@
             test(cf, f);
         }
         for (Method m: cf.methods) {
-            test(cf, m);
+            test(cf, m,false);
         }
 
         countAnnotations();
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.java
index 8cd7d6a..70bc051 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.java
@@ -1,7 +1,7 @@
 /*
  * @test /nodynamiccopyright/
  * @bug 8006733 8006775
- * @ignore
+ * @ignore 8013409: test failures for type annotations
  * @summary A static outer class cannot be annotated.
  * @author Werner Dietl
  * @compile/fail/ref=CantAnnotateStaticClass.out -XDrawDiagnostics CantAnnotateStaticClass.java
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/LazyConstantValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LazyConstantValue.java
index 337ac8b..f70cefe 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/LazyConstantValue.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LazyConstantValue.java
@@ -27,7 +27,7 @@
  * @summary Type annotations in a lazy constant need to be attributed
  *   in the correct order.
  * @author Werner Dietl
- * @compile LazyConstantValue.java
+ * @compile/ref=LazyConstantValue.out LazyConstantValue.java
  */
 
 import java.lang.annotation.*;
@@ -40,5 +40,9 @@
     static final String[] lcv = new @TA String[0];
 }
 
+class ClassC {
+    static final Object o = (@TA Object) null;
+}
+
 @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
 @interface TA {}
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/LazyConstantValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LazyConstantValue.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LazyConstantValue.out
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.out
index 212423e..cb65dba 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.out
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.out
@@ -1,11 +1,11 @@
 LintCast.java:15:21: compiler.warn.redundant.cast: java.lang.String
 LintCast.java:21:27: compiler.warn.redundant.cast: java.util.List<java.lang.String>
-LintCast.java:27:20: compiler.warn.redundant.cast: (@A :: int[])
+LintCast.java:27:20: compiler.warn.redundant.cast: int @A []
 LintCast.java:39:24: compiler.warn.redundant.cast: java.lang.String
 LintCast.java:40:26: compiler.warn.redundant.cast: java.lang.String
-LintCast.java:45:23: compiler.warn.redundant.cast: (@A :: java.lang.Object[])
+LintCast.java:45:23: compiler.warn.redundant.cast: java.lang.Object @A []
 LintCast.java:49:27: compiler.warn.redundant.cast: java.util.List<java.lang.String>
-LintCast.java:53:27: compiler.warn.redundant.cast: java.util.List<java.lang.String>
+LintCast.java:53:27: compiler.warn.redundant.cast: java.util.List<@A java.lang.String>
 LintCast.java:57:21: compiler.warn.redundant.cast: java.lang.Object
 LintCast.java:61:27: compiler.warn.redundant.cast: LintCast.Outer.Inner
 10 warnings
\ No newline at end of file
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.java
index cb386d1..55fdfa3 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.java
@@ -6,7 +6,7 @@
  * @compile/fail/ref=StaticMethods.out -XDrawDiagnostics StaticMethods.java
  */
 class StaticMethods {
-  static void main(@A StaticMethods this) { }
+  static void main(StaticMethods this) { }
 }
 
 @interface A { }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.out
index d75a02bf..2e0923a 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.out
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.out
@@ -1,2 +1,2 @@
-StaticMethods.java:9:37: compiler.err.annotation.type.not.applicable
+StaticMethods.java:9:34: compiler.err.non-static.cant.be.ref: kindname.variable, this
 1 error
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/T8008751.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/T8008751.java
new file mode 100644
index 0000000..9f54330
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/T8008751.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary type-annotation on array level in nested class results in NPE
+ * @bug 8008751
+ * @compile T8008751.java
+ */
+import java.lang.annotation.*;
+import static java.lang.annotation.RetentionPolicy.*;
+import static java.lang.annotation.ElementType.*;
+import java.util.List;
+
+class T8008751 {
+    Object mtest( T8008751 t){ return null;  }
+    public void test() {
+       mtest( new T8008751() {
+                class InnerAnon {
+                    @A("ok") String s = (@A("ok") String)( new @A("ok") Object());
+                    @A("ok") Object @A("NPE")[] [] ia_sa1 = null;
+                }
+                // If not instanciated, no crash.
+                InnerAnon IA = new InnerAnon();
+           });
+   }
+}
+@Retention(RUNTIME) @Target(TYPE_USE)  @interface A { String value(); }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/T8009360.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/T8009360.java
new file mode 100644
index 0000000..3dbf477
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/T8009360.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8009360
+ * @summary AssertionError from type annotation on member of anonymous class
+ * @compile T8009360.java
+ */
+import java.lang.annotation.*;
+import static java.lang.annotation.RetentionPolicy.*;
+import static java.lang.annotation.ElementType.*;
+
+class Test1<T> {
+    Object mtest( Test1<T> t){ return null; }
+    public void test() {
+        mtest( new Test1<T>() {
+                @A String data1 = "test";    // ok
+                @A @A String data2 = "test"; // ok
+                @A @B String data3 = "test"; // was AssertionError
+                @B @C String data4 = "test"; // was AssertionError
+           });
+   }
+}
+
+@Target({TYPE_USE,FIELD}) @Repeatable( AC.class) @interface A { }
+@Target({TYPE_USE,FIELD}) @interface AC { A[] value(); }
+@Target({TYPE_USE}) @interface B { }
+@Target({TYPE_USE, FIELD}) @interface C { }
diff --git a/hotspot/src/share/tools/launcher/jli_util.h b/langtools/test/tools/javac/annotations/typeAnnotations/failures/T8011722.java
similarity index 67%
copy from hotspot/src/share/tools/launcher/jli_util.h
copy to langtools/test/tools/javac/annotations/typeAnnotations/failures/T8011722.java
index 535f7c4..7802db5 100644
--- a/hotspot/src/share/tools/launcher/jli_util.h
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/T8011722.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -19,17 +19,20 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
-#ifndef _JLI_UTIL_H
-#define _JLI_UTIL_H
+/*
+ * @test
+ * @bug 8011722
+ * @summary AssertionError from type annotations on qualified type
+ * @compile T8011722.java
+ */
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
 
-#include <stdlib.h>
+public class T8011722 {
+    class InnerException extends Exception { }
+    void foo() throws @C T8011722.@C InnerException {    }
+}
 
-void *JLI_MemAlloc(size_t size);
-void *JLI_MemRealloc(void *ptr, size_t size);
-char *JLI_StringDup(const char *s1);
-void  JLI_MemFree(void *ptr);
-
-#endif  /* _JLI_UTIL_H */
+@Target(ElementType.TYPE_USE) @interface C { }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.java
new file mode 100644
index 0000000..e60f72d
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.java
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 1234567
+ * @summary ensure that declaration annotations are not allowed on
+ *   new array expressions
+ * @author Werner Dietl
+ * @compile/fail/ref=DeclarationAnnotation.out -XDrawDiagnostics DeclarationAnnotation.java
+ */
+class DeclarationAnnotation {
+    Object e1 = new @DA int[5];
+    Object e2 = new @DA String[42];
+    Object e3 = new @DA Object();
+
+    // The declaration annotation is only allowed for
+    // an anonymous class creation.
+    Object ok = new @DA Object() { };
+}
+
+@interface DA { }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.out
new file mode 100644
index 0000000..91c76a5
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.out
@@ -0,0 +1,4 @@
+DeclarationAnnotation.java:10:21: compiler.err.annotation.type.not.applicable
+DeclarationAnnotation.java:11:21: compiler.err.annotation.type.not.applicable
+DeclarationAnnotation.java:12:21: compiler.err.annotation.type.not.applicable
+3 errors
\ No newline at end of file
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DeclarationAnnotation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DeclarationAnnotation.java
new file mode 100644
index 0000000..886efb2
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DeclarationAnnotation.java
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 1234567
+ * @summary ensure that declaration annotations are not allowed on
+ *   method receiver types
+ * @author Werner Dietl
+ * @compile/fail/ref=DeclarationAnnotation.out -XDrawDiagnostics DeclarationAnnotation.java
+ */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+class DeclarationAnnotation {
+    void bad(@DA DeclarationAnnotation this) {}
+    void good(@TA DeclarationAnnotation this) {}
+}
+
+@interface DA { }
+
+@Target(ElementType.TYPE_USE)
+@interface TA { }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DeclarationAnnotation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DeclarationAnnotation.out
new file mode 100644
index 0000000..5cd0173
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DeclarationAnnotation.out
@@ -0,0 +1,2 @@
+DeclarationAnnotation.java:14:14: compiler.err.annotation.type.not.applicable
+1 error
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/Nesting.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/Nesting.java
index 6b5d7fc..1981d78 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/Nesting.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/Nesting.java
@@ -28,6 +28,11 @@
  * @author Werner Dietl
  * @compile Nesting.java
  */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE_USE)
 @interface A { }
 
 class Nesting {
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.out
index fc50011..e64bdba 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.out
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.out
@@ -1,5 +1,5 @@
-StaticThings.java:52:32: compiler.err.annotation.type.not.applicable
-StaticThings.java:54:37: compiler.err.annotation.type.not.applicable
-StaticThings.java:33:26: compiler.err.annotation.type.not.applicable
-StaticThings.java:36:28: compiler.err.annotation.type.not.applicable
-4 errors
\ No newline at end of file
+StaticThings.java:33:26: compiler.err.non-static.cant.be.ref: kindname.variable, this
+StaticThings.java:36:28: compiler.err.non-static.cant.be.ref: kindname.variable, this
+StaticThings.java:52:32: compiler.err.non-static.cant.be.ref: kindname.variable, this
+StaticThings.java:54:37: compiler.err.non-static.cant.be.ref: kindname.variable, this
+4 errors
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.java
index 6327710..14911c3 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.java
@@ -29,6 +29,10 @@
  * @compile/fail/ref=WrongType.out -XDrawDiagnostics WrongType.java
  */
 
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE_USE)
 @interface A {}
 
 class WrongType {
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.out
index 804425a..b544267 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.out
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.out
@@ -1,9 +1,9 @@
-WrongType.java:51:15: compiler.err.cant.resolve.location: kindname.class, XYZ, , , (compiler.misc.location: kindname.class, WrongType, null)
-WrongType.java:61:27: compiler.err.doesnt.exist: Outer
-WrongType.java:62:31: compiler.err.cant.resolve.location: kindname.class, XY, , , (compiler.misc.location: kindname.class, WrongType, null)
-WrongType.java:44:23: compiler.err.incorrect.receiver.type
-WrongType.java:46:23: compiler.err.incorrect.receiver.type
-WrongType.java:59:33: compiler.err.incorrect.receiver.type
-WrongType.java:60:31: compiler.err.incorrect.receiver.type
-WrongType.java:66:28: compiler.err.incorrect.receiver.type
-8 errors
\ No newline at end of file
+WrongType.java:48:16: compiler.err.incorrect.receiver.type: WrongType, java.lang.Object
+WrongType.java:50:16: compiler.err.incorrect.receiver.type: WrongType, java.lang.Object
+WrongType.java:55:15: compiler.err.cant.resolve.location: kindname.class, XYZ, , , (compiler.misc.location: kindname.class, WrongType, null)
+WrongType.java:63:23: compiler.err.incorrect.receiver.type: WrongType.Inner, WrongType
+WrongType.java:64:24: compiler.err.incorrect.receiver.type: WrongType.Inner, java.lang.Object
+WrongType.java:65:27: compiler.err.doesnt.exist: Outer
+WrongType.java:66:31: compiler.err.cant.resolve.location: kindname.class, XY, , , (compiler.misc.location: kindname.class, WrongType, null)
+WrongType.java:70:24: compiler.err.incorrect.receiver.type: WrongType.Generics<X>, WrongType.Generics<Y>
+8 errors
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.java
index 5a6bb42..db3c563 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.java
@@ -5,10 +5,15 @@
  * @author Mahmood Ali
  * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java
  */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
 class MissingAnnotationValue {
   void test() {
     new @A String();
   }
 }
 
+@Target(ElementType.TYPE_USE)
 @interface A { int field(); }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.out
index f83f6df..3dac47d 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.out
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.out
@@ -1,2 +1,2 @@
-MissingAnnotationValue.java:10:9: compiler.err.annotation.missing.default.value: A, field
+MissingAnnotationValue.java:14:9: compiler.err.annotation.missing.default.value: A, field
 1 error
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DeclarationAnnotation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DeclarationAnnotation.java
new file mode 100644
index 0000000..68d77b9
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DeclarationAnnotation.java
@@ -0,0 +1,22 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 1234567
+ * @summary ensure that declaration annotations are not allowed on
+ *   wildcards
+ * @author Werner Dietl
+ * @compile/fail/ref=DeclarationAnnotation.out -XDrawDiagnostics DeclarationAnnotation.java
+ */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.util.List;
+
+class DeclarationAnnotation {
+    List<@DA ? extends Object> bad;
+    List<@TA ? extends Object> good;
+}
+
+@interface DA { }
+
+@Target(ElementType.TYPE_USE)
+@interface TA { }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DeclarationAnnotation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DeclarationAnnotation.out
new file mode 100644
index 0000000..c070ab3
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DeclarationAnnotation.out
@@ -0,0 +1,2 @@
+DeclarationAnnotation.java:15:10: compiler.err.annotation.type.not.applicable
+1 error
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/AnonymousClass.java
similarity index 62%
copy from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
copy to langtools/test/tools/javac/annotations/typeAnnotations/newlocations/AnonymousClass.java
index 06196c2..e4136c2 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/AnonymousClass.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,16 +21,25 @@
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
+import java.lang.annotation.*;
 
-@GenerateNativeHeader
-public class TestClass2 {
-    byte b;
-    short s;
-    int i;
-    long l;
-    float f;
-    double d;
-    Object o;
-    String t;
+/*
+ * @test
+ * @bug 1234567
+ * @summary new type annotation location: anonymous class creation
+ * @author Werner Dietl
+ * @compile AnonymousClass.java
+ */
+class AnonymousClass {
+    Object o1 = new @TA Object() { };
+    // Declaration annotations are also allowed.
+    Object o2 = new @TA @DA Object() { };
 }
+
+@interface DA { }
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TA { }
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TB { }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Lambda.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Lambda.java
index 2a99420..a2d874b 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Lambda.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Lambda.java
@@ -50,6 +50,13 @@
         return LambdaImpl::<@TA Object, @TB Object>new;
     }
 
+    interface LambdaInt2 {
+        void lambda(Object p1, Object p2);
+    }
+
+    LambdaInt2 getLambda() {
+        return (@TA Object x, @TB Object y) -> { @TA Object l = null; System.out.println("We have: " + (@TB Object) x); };
+    }
 }
 
 @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MultiCatch.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MultiCatch.java
index 1745e61..8a1545d 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MultiCatch.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MultiCatch.java
@@ -25,7 +25,6 @@
 
 /*
  * @test
- * @ignore // syntax not sure yet.
  * @bug 8006775
  * @summary new type annotation location: multicatch
  * @author Werner Dietl
@@ -40,6 +39,8 @@
       e.toString();
     }
   }
+  /* Disabled: there is no syntax to annotate all components
+   * of the multicatch.
   void exception02() {
     try {
         System.out.println("Hello 2!");
@@ -47,18 +48,24 @@
       e.toString();
     }
   }
+  */
 }
 
 class ModifiedVars {
-    /*
-  void exception() {
+  void exception01() {
     try {
-      arrays();
-    } catch (final @A Exception e) {
+        System.out.println("Hello 1!");
+    } catch (final @B NullPointerException | @C IllegalArgumentException e) {
       e.toString();
     }
   }
-    */
+  void exception02() {
+    try {
+        System.out.println("Hello 1!");
+    } catch (@Decl @B NullPointerException | @C IllegalArgumentException e) {
+      e.toString();
+    }
+  }
 }
 
 @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
@@ -67,5 +74,5 @@
 @interface B { }
 @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
 @interface C { }
-@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@interface D { }
+
+@interface Decl { }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java
index bbdcba3..38e4615 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -54,7 +54,6 @@
                " } }";
     }
 
-    /* TODO: Outer.this annotation support.
     @TADescriptions({
         @TADescription(annotation = "TA", type = METHOD_RECEIVER),
         @TADescription(annotation = "TB", type = METHOD_RETURN),
@@ -69,5 +68,21 @@
                " @TD Inner(@TC Test Test.this, @TE int b) {}" +
                " } }";
     }
-    */
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = METHOD_RECEIVER),
+        @TADescription(annotation = "TB", type = METHOD_RECEIVER, genericLocation = {1, 0}),
+        @TADescription(annotation = "TC", type = METHOD_RETURN),
+        @TADescription(annotation = "TD", type = METHOD_RECEIVER, genericLocation = {1, 0}),
+        @TADescription(annotation = "TE", type = METHOD_RETURN),
+        @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, paramIndex = 0)
+    })
+    @TestClass("Outer$Middle$Inner")
+    public String innerClass3() {
+        return "class Outer { class Middle { class Inner {" +
+               " @TC Inner(@TA Outer. @TB Middle Middle.this) {}" +
+               " @TE Inner(@TD Middle Outer.Middle.this, @TF int b) {}" +
+               " } } }";
+    }
+
 }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java
index 042b7b0..feaa4f3 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java
@@ -207,7 +207,7 @@
 
         if (isSnippet) {
             // Have a few common nested types for testing
-            sb.append("class Outer { class Inner {} }");
+            sb.append("class Outer { class Inner {} class Middle { class MInner {} } }");
             sb.append("class SOuter { static class SInner {} }");
             sb.append("class GOuter<X, Y> { class GInner<X, Y> {} }");
         }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java
index a7c2818..790a514 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java
@@ -47,11 +47,43 @@
         @TADescription(annotation = "TB", type = EXCEPTION_PARAMETER, exceptionIndex = 1),
         @TADescription(annotation = "TC", type = EXCEPTION_PARAMETER, exceptionIndex = 2)
     })
-    public String multipleExceptions() {
+    public String multipleExceptions1() {
         return "void multipleExceptions() { " +
             "try { new Object(); } catch(@TA Exception e) { }" +
             "try { new Object(); } catch(@TB Exception e) { }" +
             "try { new Object(); } catch(@TC Exception e) { }" +
             " }";
     }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = EXCEPTION_PARAMETER, exceptionIndex = 0),
+        @TADescription(annotation = "TB", type = EXCEPTION_PARAMETER, exceptionIndex = 1),
+        @TADescription(annotation = "TC", type = EXCEPTION_PARAMETER, exceptionIndex = 2)
+    })
+    public String multipleExceptions2() {
+        return "void multipleExceptions() { " +
+            "  try { new Object(); " +
+            "    try { new Object(); " +
+            "      try { new Object(); } catch(@TA Exception e) { }" +
+            "    } catch(@TB Exception e) { }" +
+            "  } catch(@TC Exception e) { }" +
+            "}";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = EXCEPTION_PARAMETER, exceptionIndex = 0),
+        @TADescription(annotation = "TB", type = EXCEPTION_PARAMETER, exceptionIndex = 1),
+        @TADescription(annotation = "TC", type = EXCEPTION_PARAMETER, exceptionIndex = 2)
+    })
+    public String multipleExceptions3() {
+        return "void multipleExceptions() { " +
+            "  try { new Object(); " +
+            "  } catch(@TA Exception e1) { "+
+            "    try { new Object(); " +
+            "    } catch(@TB Exception e2) {" +
+            "      try { new Object(); } catch(@TC Exception e3) { }" +
+            "    }" +
+            "  }" +
+            "}";
+    }
 }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Initializers.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Initializers.java
new file mode 100644
index 0000000..3efd636
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Initializers.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
+
+/*
+ * @test
+ * @bug 1234567
+ * @summary Test population of reference info for instance and class initializers
+ * @author Werner Dietl
+ * @compile -g Driver.java ReferenceInfoUtil.java Initializers.java
+ * @run main Driver Initializers
+ */
+public class Initializers {
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TB", type = NEW,
+                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+    })
+    public String instanceInit1() {
+        return "class Test { { Object o = new @TA ArrayList<@TB String>(); } }";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TB", type = NEW,
+                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TC", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TD", type = NEW,
+                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+    })
+    public String instanceInit2() {
+        return "class Test { Object f = new @TA ArrayList<@TB String>(); " +
+                " { Object o = new @TC ArrayList<@TD String>(); } }";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TB", type = NEW,
+                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+    })
+    public String staticInit1() {
+        return "class Test { static { Object o = new @TA ArrayList<@TB String>(); } }";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TB", type = NEW,
+                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TC", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TD", type = NEW,
+                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TE", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TF", type = NEW,
+                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+    })
+    public String staticInit2() {
+        return "class Test { Object f = new @TA ArrayList<@TB String>(); " +
+                " static Object g = new @TC ArrayList<@TD String>(); " +
+                " static { Object o = new @TE ArrayList<@TF String>(); } }";
+    }
+
+    // TODO: test interaction with several constructors, especially non-initial constuctors.
+    // I don't think this kind of test is possible here.
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = CAST,
+                typeIndex = 0, offset = ReferenceInfoUtil.IGNORE_VALUE),
+    })
+    public String lazyConstantCast1() {
+        return "class Test { public static final Object o = (@TA Object) null; }";
+    }
+
+}
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java
index ddeeb94..b5580a8 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java
@@ -259,4 +259,30 @@
                 "}";
     }
 
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER,
+                paramIndex = 0),
+        @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER,
+                paramIndex = 1),
+        @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER,
+                paramIndex = 1, genericLocation = { 3, 0 }),
+        @TADescription(annotation = "TD", type = LOCAL_VARIABLE,
+                lvarOffset = ReferenceInfoUtil.IGNORE_VALUE,
+                lvarLength = ReferenceInfoUtil.IGNORE_VALUE,
+                lvarIndex = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TE", type = CAST,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
+    })
+    public String returnLambdaExpr1() {
+        return
+                "interface LambdaInt {" +
+                "  void lambda(Object p1, List<Object> p2);" +
+                "}" +
+                "class Test {" +
+                "  LambdaInt getLambda() {" +
+                "    return (@TA Object x, @TB List<@TC Object> y) -> { @TD Object l = null; System.out.println((@TE Object) l); };" +
+                "  }" +
+                "}";
+    }
 }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodThrows.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodThrows.java
index 457ca5b..2b73c6e 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodThrows.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodThrows.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -54,4 +54,24 @@
     public String interfaceMethod() {
         return "interface Test { void test() throws @TA RuntimeException, IllegalArgumentException, @TB Exception; }";
     }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = THROWS, typeIndex = 0,
+                       genericLocation = {}),
+        @TADescription(annotation = "TB", type = THROWS, typeIndex = 0,
+                       genericLocation = {1, 0}),
+        @TADescription(annotation = "TC", type = THROWS, typeIndex = 0,
+                       genericLocation = {1, 0, 1, 0}),
+        @TADescription(annotation = "TD", type = THROWS, typeIndex = 1,
+                       genericLocation = {}),
+        @TADescription(annotation = "TE", type = THROWS, typeIndex = 1,
+                       genericLocation = {1, 0}),
+        @TADescription(annotation = "TF", type = THROWS, typeIndex = 1,
+                       genericLocation = {1, 0, 1, 0})
+    })
+    public String NestedTypes() {
+        return "class Outer { class Middle { class Inner1 extends Exception {}" +
+                "  class Inner2 extends Exception{} } }" +
+                "class Test { void test() throws @TA Outer.@TB Middle.@TC Inner1, @TD Outer.@TE Middle.@TF Inner2 { } }";
+    }
 }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java
index 69694e4..7c16a0d 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java
@@ -26,7 +26,6 @@
 /*
  * @test
  * @bug 8006732 8006775
- * @ignore
  * @summary Test population of reference info for multicatch exception parameters
  * @author Werner Dietl
  * @compile -g Driver.java ReferenceInfoUtil.java MultiCatch.java
@@ -53,4 +52,16 @@
             "try { new Object(); } catch (@TA NullPointerException | @TB IndexOutOfBoundsException | @TC IllegalArgumentException e) { e.toString(); } }";
     }
 
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = EXCEPTION_PARAMETER, exceptionIndex = 1),
+        @TADescription(annotation = "TB", type = EXCEPTION_PARAMETER, exceptionIndex = 1),
+        @TADescription(annotation = "TC", type = EXCEPTION_PARAMETER, exceptionIndex = 2),
+        @TADescription(annotation = "TD", type = EXCEPTION_PARAMETER, exceptionIndex = 2),
+        @TADescription(annotation = "TE", type = EXCEPTION_PARAMETER, exceptionIndex = 3),
+    })
+    public String multiCatch3() {
+        return "void multiCatch3() { " +
+            "try { new Object(); } catch (NullPointerException e1) {}" +
+            "try { new Object(); } catch (@TA @TB NullPointerException | @TC @TD IndexOutOfBoundsException | @TE IllegalArgumentException e2) { e2.toString(); } }";
+    }
 }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java
index e98df7b..3bd39e5 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -831,4 +831,48 @@
                 "  }\n" +
                 "}}\n";
     }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = CLASS_EXTENDS,
+                genericLocation = {}, typeIndex = -1),
+        @TADescription(annotation = "TB", type = CLASS_EXTENDS,
+                genericLocation = {3, 0}, typeIndex = -1),
+        @TADescription(annotation = "TC", type = CLASS_EXTENDS,
+                genericLocation = {3, 1}, typeIndex = -1),
+        @TADescription(annotation = "TD", type = CLASS_EXTENDS,
+                genericLocation = {1, 0}, typeIndex = -1),
+        @TADescription(annotation = "TE", type = CLASS_EXTENDS,
+                genericLocation = {1, 0, 3, 0}, typeIndex = -1),
+        @TADescription(annotation = "TF", type = CLASS_EXTENDS,
+                genericLocation = {1, 0, 3, 1}, typeIndex = -1)
+    })
+    @TestClass("GOuter$GInner$Test")
+    public String testExtends1() {
+        return "class GOuter<A, B> {\n" +
+                "  class GInner<X, Y> {\n" +
+                "    class Test extends @TA GOuter<@TB String, @TC String>.@TD GInner<@TE String, @TF String> {}" +
+                "  }" +
+                "}";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER,
+                genericLocation = {}, paramIndex = 0),
+        @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND,
+                genericLocation = {}, paramIndex = 0, boundIndex = 0),
+        @TADescription(annotation = "TC", type = FIELD,
+                genericLocation = {}),
+        @TADescription(annotation = "TD", type = FIELD,
+                genericLocation = {3, 0})
+    })
+    @TestClass("Test$1Nested")
+    public String testNestedInMethod1() {
+        return "class Test {\n" +
+                "  void foobar() {\n" +
+                "    class Nested<@TA X extends @TB Object> {\n" +
+                "      @TC List<@TD Object> f;\n" +
+                "    }\n" +
+                "  }" +
+                "}";
+    }
 }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NewObjects.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NewObjects.java
index fb3e3f5..30913b1 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NewObjects.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NewObjects.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -75,4 +75,81 @@
         return "void eqtestObjectGeneric() { if (null == new @TA ArrayList<@TB String >()); }";
     }
 
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = {0, 0}),
+        @TADescription(annotation = "TB", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE)
+    })
+    public String returnNewArray1() {
+        return "Object returnNewArray1() { return new @TA String @TB[1]; }";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = {0, 0, 0, 0}),
+        @TADescription(annotation = "TB", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TC", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = {0, 0}),
+    })
+    public String returnNewArray2() {
+        return "Object returnNewArray2() { return new @TA String @TB [1] @TC [2]; }";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = {0, 0, 0, 0}),
+        @TADescription(annotation = "TB", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = {0, 0, 0, 0, 1, 0}),
+        @TADescription(annotation = "TC", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TD", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = {0, 0}),
+    })
+    public String returnNewArray3() {
+        return "Object returnNewArray3() { return new @TA Outer. @TB Inner @TC [1] @TD [2]; }";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = {0, 0, 0, 0}),
+        @TADescription(annotation = "TB", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = {0, 0, 0, 0, 1, 0}),
+        @TADescription(annotation = "TC", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = {0, 0, 0, 0, 1, 0, 1, 0}),
+        @TADescription(annotation = "TD", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TE", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = {0, 0}),
+    })
+    public String returnNewArray4() {
+        return "Object returnNewArray4() { return new @TA Outer. @TB Middle. @TC MInner @TD [1] @TE [2]; }";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TB", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = {3, 0, 0, 0, 0, 0}),
+        @TADescription(annotation = "TC", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = {3, 0, 0, 0, 0, 0, 1, 0}),
+        @TADescription(annotation = "TD", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0}),
+        @TADescription(annotation = "TE", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = {3, 0}),
+        @TADescription(annotation = "TF", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = {3, 0, 0, 0}),
+    })
+    public String returnNewArray5() {
+        return "Object returnNewArray5() { return new @TA ArrayList<@TB Outer. @TC Middle. @TD MInner @TE [] @TF []>(); }";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = FIELD, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = {0, 0, 0, 0}),
+        @TADescription(annotation = "TB", type = FIELD, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = {0, 0, 0, 0, 1, 0}),
+        @TADescription(annotation = "TC", type = FIELD, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TD", type = FIELD, offset = ReferenceInfoUtil.IGNORE_VALUE,
+        genericLocation = {0, 0}),
+    })
+    public String arrayField() {
+        return "@TA Outer. @TB Inner @TC [] @TD [] f;";
+    }
 }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ReferenceInfoUtil.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ReferenceInfoUtil.java
index 33ae4ed..0577c8b 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ReferenceInfoUtil.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ReferenceInfoUtil.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -28,6 +28,7 @@
 
 import com.sun.tools.classfile.Attribute;
 import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.Code_attribute;
 import com.sun.tools.classfile.TypeAnnotation;
 import com.sun.tools.classfile.Field;
 import com.sun.tools.classfile.Method;
@@ -90,6 +91,20 @@
             RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
             annos.addAll(Arrays.asList(tAttr.annotations));
         }
+
+        int cindex = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
+        if (cindex != -1) {
+            Attribute cattr = m.attributes.get(cindex);
+            assert cattr instanceof Code_attribute;
+            Code_attribute cAttr = (Code_attribute)cattr;
+            index = cAttr.attributes.getIndex(cf.constant_pool, name);
+            if (index != -1) {
+                Attribute attr = cAttr.attributes.get(index);
+                assert attr instanceof RuntimeTypeAnnotations_attribute;
+                RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
+                annos.addAll(Arrays.asList(tAttr.annotations));
+            }
+        }
     }
 
     // test the result of Attributes.getIndex according to expectations
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Test.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Test.java
new file mode 100644
index 0000000..b6cb1ca
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Test.java
@@ -0,0 +1,33 @@
+
+import java.util.*;
+import java.lang.annotation.*;
+
+class Test<K> { GOuter<@TC Object, String> entrySet() { return null; } }
+
+@interface A {}
+@interface B {}
+@interface C {}
+@interface D {}
+@interface E {}
+@interface F {}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TB {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TC {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TD {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TE {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TF {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TG {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TH {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TI {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TJ {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TK {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TL {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TM {}
+
+@Repeatable(RTAs.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTA {}
+@Repeatable(RTBs.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTB {}
+@ContainerFor(RTA.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTAs { RTA[] value(); }
+@ContainerFor(RTB.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTBs { RTB[] value(); }
+@Target(value={ElementType.TYPE,ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER,ElementType.CONSTRUCTOR,ElementType.LOCAL_VARIABLE})
+@interface Decl {}
diff --git a/langtools/test/tools/javac/api/6406133/T6406133.java b/langtools/test/tools/javac/api/6406133/T6406133.java
index 3227dda..26eb3e0 100644
--- a/langtools/test/tools/javac/api/6406133/T6406133.java
+++ b/langtools/test/tools/javac/api/6406133/T6406133.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -27,6 +27,8 @@
  * @summary Compiler API ignores locale settings
  * @author  Maurizio Cimadamore
  * @library ../lib
+ * @build ToolTester
+ * @run main T6406133
  */
 
 import javax.tools.*;
diff --git a/langtools/test/tools/javac/api/6410643/T6410643.java b/langtools/test/tools/javac/api/6410643/T6410643.java
index ac5ca4c..80ac51d 100644
--- a/langtools/test/tools/javac/api/6410643/T6410643.java
+++ b/langtools/test/tools/javac/api/6410643/T6410643.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -27,6 +27,8 @@
  * @summary JSR 199: The method JavaCompilerTool.run fails to handle null arguments
  * @author  Peter von der Ah\u00e9
  * @library ../lib
+ * @build ToolTester
+ * @run main T6410643
  */
 
 import javax.tools.JavaFileObject;
diff --git a/langtools/test/tools/javac/api/6411310/T6411310.java b/langtools/test/tools/javac/api/6411310/T6411310.java
index 892444c..885f347 100644
--- a/langtools/test/tools/javac/api/6411310/T6411310.java
+++ b/langtools/test/tools/javac/api/6411310/T6411310.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -27,6 +27,7 @@
  * @summary JSR 199: FileObject should support user-friendly names via getName()
  * @author  Peter von der Ah\u00e9
  * @library ../lib
+ * @build ToolTester
  * @compile T6411310.java
  * @run main T6411310
  */
diff --git a/langtools/test/tools/javac/api/6411333/T6411333.java b/langtools/test/tools/javac/api/6411333/T6411333.java
index 6032b39..146f135 100644
--- a/langtools/test/tools/javac/api/6411333/T6411333.java
+++ b/langtools/test/tools/javac/api/6411333/T6411333.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -27,6 +27,7 @@
  * @summary Ensure 6400208, 6400225, and 6400267 are tested
  * @author  Peter von der Ah\u00e9
  * @library ../lib
+ * @build ToolTester
  * @compile T6411333.java
  * @run main T6411333
  */
diff --git a/langtools/test/tools/javac/api/6412656/T6412656.java b/langtools/test/tools/javac/api/6412656/T6412656.java
index e63ca2c..2dc64b7 100644
--- a/langtools/test/tools/javac/api/6412656/T6412656.java
+++ b/langtools/test/tools/javac/api/6412656/T6412656.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -27,6 +27,8 @@
  * @summary JSR 199: pass annotation processor instances to compiler
  * @author  Peter von der Ah\u00e9
  * @library ../lib
+ * @build ToolTester
+ * @run main T6412656
  */
 
 import java.util.Set;
diff --git a/langtools/test/tools/javac/api/6415780/T6415780.java b/langtools/test/tools/javac/api/6415780/T6415780.java
index c5a4ed5..caf8c06 100644
--- a/langtools/test/tools/javac/api/6415780/T6415780.java
+++ b/langtools/test/tools/javac/api/6415780/T6415780.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -28,6 +28,8 @@
  * @author  igor.tseytin@...
  * @author  Peter von der Ah\u00e9
  * @library ../lib
+ * @build ToolTester
+ * @run main T6415780
  */
 
 import static javax.tools.StandardLocation.CLASS_PATH;
diff --git a/langtools/test/tools/javac/api/6418694/T6418694.java b/langtools/test/tools/javac/api/6418694/T6418694.java
index 7b7c1fe..f23cbf8 100644
--- a/langtools/test/tools/javac/api/6418694/T6418694.java
+++ b/langtools/test/tools/javac/api/6418694/T6418694.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -27,6 +27,7 @@
  * @summary JSR 199: JavaFileManager.hasLocation(Location)
  * @author  Peter von der Ah\u00e9
  * @library ../lib
+ * @build ToolTester
  * @compile T6418694.java
  * @run main T6418694
  */
diff --git a/langtools/test/tools/javac/api/6421111/T6421111.java b/langtools/test/tools/javac/api/6421111/T6421111.java
index fc2c581..96fbf2c 100644
--- a/langtools/test/tools/javac/api/6421111/T6421111.java
+++ b/langtools/test/tools/javac/api/6421111/T6421111.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -27,6 +27,7 @@
  * @summary NullPointerException thrown when retrieving bounds for the type parameter
  * @author  Peter von der Ah\u00e9
  * @library ../lib
+ * @build ToolTester
  * @compile -Xlint:all T6421111.java
  * @run main T6421111
  */
diff --git a/langtools/test/tools/javac/api/6421756/T6421756.java b/langtools/test/tools/javac/api/6421756/T6421756.java
index f8b9306..9d20e03 100644
--- a/langtools/test/tools/javac/api/6421756/T6421756.java
+++ b/langtools/test/tools/javac/api/6421756/T6421756.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -27,6 +27,7 @@
  * @summary 6421756 JSR 199: In the method JavaCompilerTool.getTask 'options' can be supplied in the place of 'classes'
  * @author  Peter von der Ah\u00e9
  * @library ../lib
+ * @build ToolTester
  * @compile T6421756.java
  * @run main T6421756
  */
diff --git a/langtools/test/tools/javac/api/6422215/T6422215.java b/langtools/test/tools/javac/api/6422215/T6422215.java
index 20d8d75..c9a9c39 100644
--- a/langtools/test/tools/javac/api/6422215/T6422215.java
+++ b/langtools/test/tools/javac/api/6422215/T6422215.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -27,6 +27,8 @@
  * @summary JSR 199: What happens if a directory is missing
  * @author  Peter von der Ah\u00e9
  * @library ../lib
+ * @build ToolTester
+ * @run main T6422215
  */
 
 import java.io.File;
diff --git a/langtools/test/tools/javac/api/6422327/T6422327.java b/langtools/test/tools/javac/api/6422327/T6422327.java
index ab3ddfd..e5f9f22 100644
--- a/langtools/test/tools/javac/api/6422327/T6422327.java
+++ b/langtools/test/tools/javac/api/6422327/T6422327.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -27,6 +27,8 @@
  * @summary JSR 199: JavaCompilerTool can compile and generate '.class' of non '.java' files
  * @author  Peter von der Ah\u00e9
  * @library ../lib
+ * @build ToolTester
+ * @run main T6422327
  */
 
 import java.io.File;
diff --git a/langtools/test/tools/javac/api/6423003/T6423003.java b/langtools/test/tools/javac/api/6423003/T6423003.java
index 4af5f62..e7fe2f3 100644
--- a/langtools/test/tools/javac/api/6423003/T6423003.java
+++ b/langtools/test/tools/javac/api/6423003/T6423003.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -27,6 +27,7 @@
  * @summary JSR 199: confusing help message with compiler API
  * @author  Peter von der Ah\u00e9
  * @library ../lib
+ * @build ToolTester
  * @compile T6423003.java
  * @run main T6423003
  */
diff --git a/langtools/test/tools/javac/api/6431257/T6431257.java b/langtools/test/tools/javac/api/6431257/T6431257.java
index f84afb7..9c0b2a4 100644
--- a/langtools/test/tools/javac/api/6431257/T6431257.java
+++ b/langtools/test/tools/javac/api/6431257/T6431257.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -27,6 +27,7 @@
  * @summary JSR 199: Changes to JavaFileManager to support JSR 269 Filer API
  * @author  Peter von der Ah\u00e9
  * @library ../lib
+ * @build ToolTester
  * @compile T6431257.java package-info.java
  * @run main T6431257 foo.bar.baz foo/bar/baz
  */
diff --git a/langtools/test/tools/javac/api/6437349/T6437349.java b/langtools/test/tools/javac/api/6437349/T6437349.java
index c21fe3b..af81251 100644
--- a/langtools/test/tools/javac/api/6437349/T6437349.java
+++ b/langtools/test/tools/javac/api/6437349/T6437349.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -26,6 +26,7 @@
  * @bug     6437349
  * @summary JSR 199: JavaFileObject.isNameCompatible() will give true with some incompatible kinds
  * @library ../lib
+ * @build ToolTester
  * @compile T6437349.java
  * @run main T6437349
  */
diff --git a/langtools/test/tools/javac/api/6437999/T6437999.java b/langtools/test/tools/javac/api/6437999/T6437999.java
index 65f72d0..db2f46a 100644
--- a/langtools/test/tools/javac/api/6437999/T6437999.java
+++ b/langtools/test/tools/javac/api/6437999/T6437999.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -27,6 +27,7 @@
  * @summary Unit test for encoding argument to standard file manager
  * @author  Peter von der Ah\u00e9
  * @library ../lib
+ * @build ToolTester
  * @compile T6437999.java
  * @run main T6437999
  */
diff --git a/langtools/test/tools/javac/api/6440333/T6440333.java b/langtools/test/tools/javac/api/6440333/T6440333.java
index af38054..984ef40 100644
--- a/langtools/test/tools/javac/api/6440333/T6440333.java
+++ b/langtools/test/tools/javac/api/6440333/T6440333.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -27,6 +27,7 @@
  * @summary SimpleJavaFileObject.toString() generates URI with some extra message
  * @author  Peter von der Ah\u00e9
  * @library ../lib
+ * @build ToolTester
  * @compile T6440333.java
  * @run main T6440333
  */
diff --git a/langtools/test/tools/javac/api/6440528/T6440528.java b/langtools/test/tools/javac/api/6440528/T6440528.java
index 188f5d2..0fc9194 100644
--- a/langtools/test/tools/javac/api/6440528/T6440528.java
+++ b/langtools/test/tools/javac/api/6440528/T6440528.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -27,6 +27,7 @@
  * @summary javac deposits package-info.class in bogus directory
  * @author  Peter von der Ah\u00e9
  * @library ../lib
+ * @build ToolTester
  * @compile T6440528.java
  * @run main T6440528
  */
diff --git a/langtools/test/tools/javac/api/6468404/T6468404.java b/langtools/test/tools/javac/api/6468404/T6468404.java
index 8b7e045..dafbb36 100644
--- a/langtools/test/tools/javac/api/6468404/T6468404.java
+++ b/langtools/test/tools/javac/api/6468404/T6468404.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -28,6 +28,7 @@
  * @author  jesse.glick@...
  * @author  Peter von der Ah\u00e9
  * @library ../lib
+ * @build ToolTester
  * @compile T6468404.java
  * @run main T6468404
  */
diff --git a/langtools/test/tools/javac/api/6731573/T6731573.java b/langtools/test/tools/javac/api/6731573/T6731573.java
index 03d699a..b1bdc71 100644
--- a/langtools/test/tools/javac/api/6731573/T6731573.java
+++ b/langtools/test/tools/javac/api/6731573/T6731573.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -27,6 +27,8 @@
  * @summary diagnostic output should optionally include source line
  * @author  Maurizio Cimadamore
  * @library ../lib
+ * @build ToolTester
+ * @run main T6731573
  */
 
 import java.io.*;
diff --git a/langtools/test/tools/javac/api/6733837/T6733837.java b/langtools/test/tools/javac/api/6733837/T6733837.java
index db39c6b..4f1fcf4 100644
--- a/langtools/test/tools/javac/api/6733837/T6733837.java
+++ b/langtools/test/tools/javac/api/6733837/T6733837.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -27,6 +27,8 @@
  * @summary Compiler API ignores locale settings
  * @author  Maurizio Cimadamore
  * @library ../lib
+ * @build ToolTester
+ * @run main T6733837
  */
 
 import java.io.StringWriter;
diff --git a/langtools/test/tools/javac/api/TestGetElementReference.java b/langtools/test/tools/javac/api/TestGetElementReference.java
new file mode 100644
index 0000000..c1c67bc
--- /dev/null
+++ b/langtools/test/tools/javac/api/TestGetElementReference.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8012929
+ * @summary Trees.getElement should work not only for declaration trees, but also for use-trees
+ * @build TestGetElementReference
+ * @run main TestGetElementReference
+ */
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.*;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.lang.model.element.Element;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+public class TestGetElementReference {
+
+    public static void main(String... args) throws IOException {
+        File source = new File(System.getProperty("test.src", "."), "TestGetElementReferenceData.java").getAbsoluteFile();
+        StandardJavaFileManager fm = ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null);
+        DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
+        JavacTask ct = (JavacTask) ToolProvider.getSystemJavaCompiler().getTask(null, null, diagnostics, Arrays.asList("-Xjcov", "-source", "1.8"), null, fm.getJavaFileObjects(source));
+        Trees trees = Trees.instance(ct);
+        CompilationUnitTree cut = ct.parse().iterator().next();
+
+        ct.analyze();
+
+        for (Diagnostic<? extends JavaFileObject> d : diagnostics.getDiagnostics()) {
+            if (d.getKind() == Diagnostic.Kind.ERROR) {
+                throw new IllegalStateException("Should have been attributed without errors: " + diagnostics.getDiagnostics());
+            }
+        }
+
+        Pattern p = Pattern.compile("/\\*getElement:(.*?)\\*/");
+        Matcher m = p.matcher(cut.getSourceFile().getCharContent(false));
+
+        while (m.find()) {
+            TreePath tp = pathFor(trees, cut, m.start() - 1);
+            Element found = trees.getElement(tp);
+            String expected = m.group(1);
+            String actual = found != null ? found.getKind() + ":" + symbolToString(found) : "<null>";
+
+            if (!expected.equals(actual)) {
+                throw new IllegalStateException("expected=" + expected + "; actual=" + actual);
+            }
+        }
+    }
+
+    private static TreePath pathFor(final Trees trees, final CompilationUnitTree cut, final int pos) {
+        final TreePath[] result = new TreePath[1];
+
+        new TreePathScanner<Void, Void>() {
+            @Override public Void scan(Tree node, Void p) {
+                if (   node != null
+                    && trees.getSourcePositions().getStartPosition(cut, node) <= pos
+                    && pos <= trees.getSourcePositions().getEndPosition(cut, node)) {
+                    result[0] = new TreePath(getCurrentPath(), node);
+                    return super.scan(node, p);
+                }
+                return null;
+            }
+        }.scan(cut, null);
+
+        return result[0];
+    }
+
+    private static String symbolToString(Element el) {
+        switch (el.getKind()) {
+            case METHOD: return symbolToString(el.getEnclosingElement()) + "." + el.toString();
+            case CONSTRUCTOR: return symbolToString(el.getEnclosingElement().getEnclosingElement()) + "." + el.toString();
+            default:
+                return el.toString();
+        }
+    }
+
+    static class TestFileObject extends SimpleJavaFileObject {
+        private final String text;
+        public TestFileObject(String text) {
+            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+            this.text = text;
+        }
+        @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return text;
+        }
+    }
+
+}
diff --git a/langtools/test/tools/javac/api/TestGetElementReferenceData.java b/langtools/test/tools/javac/api/TestGetElementReferenceData.java
new file mode 100644
index 0000000..a72d95f
--- /dev/null
+++ b/langtools/test/tools/javac/api/TestGetElementReferenceData.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test;
+/*getElement:PACKAGE:test*/
+import java.lang.annotation.*;
+import static test.TestGetElementReferenceData.Sub.*;
+
+public class TestGetElementReferenceData {
+
+    private static void test() {
+        StringBuilder/*getElement:CLASS:java.lang.StringBuilder*/ sb = new/*getElement:CONSTRUCTOR:java.lang.StringBuilder()*/ StringBuilder();
+        sb/*getElement:LOCAL_VARIABLE:sb*/.append/*getElement:METHOD:java.lang.StringBuilder.append(int)*/(0);
+        sb.reverse( /*getElement:METHOD:java.lang.StringBuilder.reverse()*/);
+        java.util.List< /*getElement:INTERFACE:java.util.List*/ String> l;
+        utility/*getElement:METHOD:test.TestGetElementReferenceData.Base.utility()*/();
+        target(TestGetElementReferenceData :: test/*getElement:METHOD:test.TestGetElementReferenceData.test()*/);
+    }
+    private static void target(Runnable r) { r.run(); }
+    public static class Base {
+        public static void utility() {}
+    }
+    public static class Sub extends @TypeAnnotation( /*getElement:ANNOTATION_TYPE:test.TestGetElementReferenceData.TypeAnnotation*/) Base {
+    }
+   @Deprecated( /*getElement:ANNOTATION_TYPE:java.lang.Deprecated*/)
+    public static class TypeParam<TT/*getElement:TYPE_PARAMETER:TT*/> {
+    }
+    @Target(ElementType.TYPE_USE)
+    @interface TypeAnnotation {
+    }
+}
diff --git a/langtools/test/tools/javac/api/TestJavacTaskScanner.java b/langtools/test/tools/javac/api/TestJavacTaskScanner.java
index 78ed5bb..7103ba7 100644
--- a/langtools/test/tools/javac/api/TestJavacTaskScanner.java
+++ b/langtools/test/tools/javac/api/TestJavacTaskScanner.java
@@ -27,6 +27,7 @@
  * @summary Additional functionality test of task and JSR 269
  * @author  Peter von der Ah\u00e9
  * @library ./lib
+ * @build ToolTester
  * @run main TestJavacTaskScanner TestJavacTaskScanner.java
  */
 
@@ -110,7 +111,8 @@
         DeclaredType type = (DeclaredType)task.parseType("List<String>", clazz);
         for (Element member : elements.getAllMembers((TypeElement)type.asElement())) {
             TypeMirror mt = types.asMemberOf(type, member);
-            System.out.format("%s : %s -> %s%n", member.getSimpleName(), member.asType(), mt);
+            System.out.format("type#%d: %s : %s -> %s%n",
+                numParseTypeElements, member.getSimpleName(), member.asType(), mt);
             numParseTypeElements++;
         }
     }
@@ -122,7 +124,8 @@
 
     private void testGetAllMembers(TypeElement clazz) {
         for (Element member : elements.getAllMembers(clazz)) {
-            System.out.format("%s : %s%n", member.getSimpleName(), member.asType());
+            System.out.format("elem#%d: %s : %s%n",
+                numAllMembers, member.getSimpleName(), member.asType());
             numAllMembers++;
         }
     }
@@ -160,7 +163,7 @@
         StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, encoding);
         try {
             fm.setLocation(SOURCE_PATH,  Arrays.asList(test_src));
-            fm.setLocation(CLASS_PATH,   Arrays.asList(test_classes, javac_classes));
+            fm.setLocation(CLASS_PATH,   join(test_class_path, Arrays.asList(javac_classes)));
             fm.setLocation(CLASS_OUTPUT, Arrays.asList(test_classes));
         } catch (IOException e) {
             throw new AssertionError(e);
diff --git a/langtools/test/tools/javac/api/guide/Test.java b/langtools/test/tools/javac/api/guide/Test.java
index 9c1057f..a05295f 100644
--- a/langtools/test/tools/javac/api/guide/Test.java
+++ b/langtools/test/tools/javac/api/guide/Test.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -27,6 +27,7 @@
  * @summary Various bugs fixed while writing Compiler API Guide
  * @author  Peter von der Ah\u0081
  * @library ../lib
+ * @build ToolTester
  * @compile Test.java
  * @run main Test
  */
diff --git a/langtools/test/tools/javac/api/lib/ToolTester.java b/langtools/test/tools/javac/api/lib/ToolTester.java
index 2f1a50e..ba66da8 100644
--- a/langtools/test/tools/javac/api/lib/ToolTester.java
+++ b/langtools/test/tools/javac/api/lib/ToolTester.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -24,7 +24,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.nio.charset.Charset;
-import java.util.Arrays;
+import java.util.*;
 import javax.tools.*;
 
 import static javax.tools.StandardLocation.CLASS_PATH;
@@ -34,6 +34,8 @@
 public class ToolTester {
     public final File test_src     = new File(System.getProperty("test.src", "."));
     public final File test_classes = new File(System.getProperty("test.classes", "."));
+    public final List<File> test_class_path = pathToFiles(System.getProperty("test.class.path"),
+                                     Arrays.asList(test_classes));
     public final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
     public final StandardJavaFileManager fm = getFileManager(tool, null, null);
     public JavaCompiler.CompilationTask task = null;
@@ -43,11 +45,36 @@
         StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, encoding);
         try {
             fm.setLocation(SOURCE_PATH,  Arrays.asList(test_src));
-            fm.setLocation(CLASS_PATH,   Arrays.asList(test_classes));
+            fm.setLocation(CLASS_PATH,   test_class_path);
             fm.setLocation(CLASS_OUTPUT, Arrays.asList(test_classes));
         } catch (IOException e) {
             throw new AssertionError(e);
         }
         return fm;
     }
+
+    protected List<File> pathToFiles(String path, List<File> defaultPath) {
+        List<File> files = new ArrayList<>();
+        for (String f: path.split(File.pathSeparator)) {
+            if (f.isEmpty())
+                continue;
+            File file = new File(f);
+            if (file.exists())
+                files.add(file);
+        }
+        if (files.isEmpty())
+            files.addAll(defaultPath);
+        return files;
+    }
+
+    protected <T> List<T> join(List<T> a, List<T> b) {
+        if (a.isEmpty())
+            return b;
+        if (b.isEmpty())
+            return a;
+        List<T> result = new ArrayList<>();
+        result.addAll(a);
+        result.addAll(b);
+        return result;
+    }
 }
diff --git a/langtools/test/tools/javac/defaultMethods/defaultMethodExecution/DefaultMethodRegressionTests.java b/langtools/test/tools/javac/defaultMethods/defaultMethodExecution/DefaultMethodRegressionTests.java
index 2b89a4b..566780d 100644
--- a/langtools/test/tools/javac/defaultMethods/defaultMethodExecution/DefaultMethodRegressionTests.java
+++ b/langtools/test/tools/javac/defaultMethods/defaultMethodExecution/DefaultMethodRegressionTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -25,7 +25,7 @@
 
 /**
  * @test
- * @ignore 8004360
+ * @ignore 8007517: DefaultMethodRegressionTests.java fail in TL
  * @bug 8003639
  * @summary convert lambda testng tests to jtreg and add them
  * @run testng DefaultMethodRegressionTests
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java b/langtools/test/tools/javac/diags/examples/ArrayAndReceiver.java
similarity index 77%
copy from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
copy to langtools/test/tools/javac/diags/examples/ArrayAndReceiver.java
index 06196c2..fc15597 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
+++ b/langtools/test/tools/javac/diags/examples/ArrayAndReceiver.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,16 +21,11 @@
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
+// key: compiler.err.array.and.receiver
+// key: compiler.err.expected
+// key: compiler.err.expected3
+// key: compiler.err.illegal.start.of.type
 
-@GenerateNativeHeader
-public class TestClass2 {
-    byte b;
-    short s;
-    int i;
-    long l;
-    float f;
-    double d;
-    Object o;
-    String t;
+class ArrayAndReceiver {
+    void m(ArrayAndReceiver this[]) { }
 }
diff --git a/langtools/test/tools/javac/diags/examples/BadArgTypesInLambda.java b/langtools/test/tools/javac/diags/examples/BadArgTypesInLambda.java
index 1062a63..493c4c3 100644
--- a/langtools/test/tools/javac/diags/examples/BadArgTypesInLambda.java
+++ b/langtools/test/tools/javac/diags/examples/BadArgTypesInLambda.java
@@ -24,6 +24,9 @@
 // key: compiler.err.cant.apply.symbol
 // key: compiler.misc.no.conforming.assignment.exists
 // key: compiler.misc.bad.arg.types.in.lambda
+// key: compiler.err.prob.found.req
+// key: compiler.misc.inconvertible.types
+// options: -Xdiags:verbose
 
 class BadArgTypesInLambda {
     interface SAM {
diff --git a/hotspot/src/share/tools/launcher/jli_util.h b/langtools/test/tools/javac/diags/examples/CompressedDiags.java
similarity index 71%
copy from hotspot/src/share/tools/launcher/jli_util.h
copy to langtools/test/tools/javac/diags/examples/CompressedDiags.java
index 535f7c4..a71f735 100644
--- a/hotspot/src/share/tools/launcher/jli_util.h
+++ b/langtools/test/tools/javac/diags/examples/CompressedDiags.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -19,17 +19,21 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
-#ifndef _JLI_UTIL_H
-#define _JLI_UTIL_H
+// key: compiler.err.prob.found.req
+// key: compiler.misc.inconvertible.types
+// key: compiler.note.compressed.diags
+// key: compiler.note.note
+// key: compiler.misc.count.error
+// key: compiler.err.error
+// run: backdoor
 
-#include <stdlib.h>
+class CompressedDiags {
 
-void *JLI_MemAlloc(size_t size);
-void *JLI_MemRealloc(void *ptr, size_t size);
-char *JLI_StringDup(const char *s1);
-void  JLI_MemFree(void *ptr);
+    void m(String s) { }
 
-#endif  /* _JLI_UTIL_H */
+    void test() {
+        m(1);
+    }
+}
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java b/langtools/test/tools/javac/diags/examples/IncorrectConstructorReceiverName.java
similarity index 77%
copy from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
copy to langtools/test/tools/javac/diags/examples/IncorrectConstructorReceiverName.java
index 06196c2..21fd4d5 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
+++ b/langtools/test/tools/javac/diags/examples/IncorrectConstructorReceiverName.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,16 +21,10 @@
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
+// key: compiler.err.incorrect.constructor.receiver.name
 
-@GenerateNativeHeader
-public class TestClass2 {
-    byte b;
-    short s;
-    int i;
-    long l;
-    float f;
-    double d;
-    Object o;
-    String t;
+class IncorrectConstructorReceiverName {
+    class Inner {
+        Inner(IncorrectConstructorReceiverName this) { }
+    }
 }
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java b/langtools/test/tools/javac/diags/examples/IncorrectConstructorReceiverType.java
similarity index 77%
copy from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
copy to langtools/test/tools/javac/diags/examples/IncorrectConstructorReceiverType.java
index 06196c2..0bc2e79 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
+++ b/langtools/test/tools/javac/diags/examples/IncorrectConstructorReceiverType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,16 +21,10 @@
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
+// key: compiler.err.incorrect.constructor.receiver.type
 
-@GenerateNativeHeader
-public class TestClass2 {
-    byte b;
-    short s;
-    int i;
-    long l;
-    float f;
-    double d;
-    Object o;
-    String t;
+class IncorrectConstructorReceiverType {
+    class Inner {
+        Inner(Object IncorrectConstructorReceiverType.this) { }
+    }
 }
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java b/langtools/test/tools/javac/diags/examples/IncorrectReceiverName.java
similarity index 78%
rename from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
rename to langtools/test/tools/javac/diags/examples/IncorrectReceiverName.java
index 06196c2..32471ba 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
+++ b/langtools/test/tools/javac/diags/examples/IncorrectReceiverName.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -21,16 +21,10 @@
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
+// key: compiler.err.incorrect.receiver.name
 
-@GenerateNativeHeader
-public class TestClass2 {
-    byte b;
-    short s;
-    int i;
-    long l;
-    float f;
-    double d;
-    Object o;
-    String t;
+class IncorrectReceiverName {
+    class Inner {
+        void m(Inner IncorrectReceiverName.this) { }
+    }
 }
diff --git a/langtools/test/tools/javac/diags/examples/KindnameConstructor.java b/langtools/test/tools/javac/diags/examples/KindnameConstructor.java
index db7d39b..4b0f739 100644
--- a/langtools/test/tools/javac/diags/examples/KindnameConstructor.java
+++ b/langtools/test/tools/javac/diags/examples/KindnameConstructor.java
@@ -28,6 +28,7 @@
 // key: compiler.misc.inconvertible.types
 // key: compiler.misc.count.error
 // key: compiler.err.error
+// options: -Xdiags:verbose
 // run: backdoor
 
 class KindnameConstructor {
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java b/langtools/test/tools/javac/diags/examples/ProbFoundReqFragment.java
similarity index 66%
copy from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
copy to langtools/test/tools/javac/diags/examples/ProbFoundReqFragment.java
index 06196c2..4eaa88c 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
+++ b/langtools/test/tools/javac/diags/examples/ProbFoundReqFragment.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,16 +21,24 @@
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
+// key: compiler.err.prob.found.req
+// key: compiler.misc.prob.found.req
+// key: compiler.misc.inconvertible.types
+// key: compiler.misc.invalid.mref
+// key: compiler.misc.kindname.method
+// key: compiler.misc.count.error
+// key: compiler.err.error
+// run: backdoor
 
-@GenerateNativeHeader
-public class TestClass2 {
-    byte b;
-    short s;
-    int i;
-    long l;
-    float f;
-    double d;
-    Object o;
-    String t;
+class ProbFoundReqFragment {
+
+    interface I {
+        void g(int i);
+    }
+
+    void m(String s) { }
+
+    void test() {
+        I i = this::m;
+    }
 }
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java b/langtools/test/tools/javac/diags/examples/ReceiverParameterNotApplicableConstructor.java
similarity index 75%
copy from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
copy to langtools/test/tools/javac/diags/examples/ReceiverParameterNotApplicableConstructor.java
index 06196c2..7678b37 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
+++ b/langtools/test/tools/javac/diags/examples/ReceiverParameterNotApplicableConstructor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,16 +21,8 @@
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
+// key: compiler.err.receiver.parameter.not.applicable.constructor.toplevel.class
 
-@GenerateNativeHeader
-public class TestClass2 {
-    byte b;
-    short s;
-    int i;
-    long l;
-    float f;
-    double d;
-    Object o;
-    String t;
+class ReceiverParameterNotApplicableConstructor {
+    ReceiverParameterNotApplicableConstructor(ReceiverParameterNotApplicableConstructor this) { }
 }
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java b/langtools/test/tools/javac/diags/examples/VarargsAndReceiver.java
similarity index 77%
copy from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
copy to langtools/test/tools/javac/diags/examples/VarargsAndReceiver.java
index 06196c2..ae06042 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
+++ b/langtools/test/tools/javac/diags/examples/VarargsAndReceiver.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,16 +21,8 @@
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
+// key: compiler.err.varargs.and.receiver
 
-@GenerateNativeHeader
-public class TestClass2 {
-    byte b;
-    short s;
-    int i;
-    long l;
-    float f;
-    double d;
-    Object o;
-    String t;
+class VarargsAndReceiver {
+    void m(VarargsAndReceiver... this) { }
 }
diff --git a/langtools/test/tools/javac/doctree/DocTreePathScannerTest.java b/langtools/test/tools/javac/doctree/DocTreePathScannerTest.java
new file mode 100644
index 0000000..5261a0a
--- /dev/null
+++ b/langtools/test/tools/javac/doctree/DocTreePathScannerTest.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8009724
+ * @summary adding DocTreePath and DocTreePathScanner
+ */
+
+import com.sun.source.doctree.DocCommentTree;
+import com.sun.source.doctree.DocTree;
+import com.sun.source.doctree.DocTree.Kind;
+import com.sun.source.doctree.DocTreeVisitor;
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.DocTreePath;
+import com.sun.source.util.DocTreePathScanner;
+import com.sun.source.util.DocTreeScanner;
+import com.sun.source.util.DocTrees;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.TreePathScanner;
+import com.sun.tools.javac.api.JavacTool;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import javax.lang.model.element.Name;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+
+public class DocTreePathScannerTest {
+    public static void main(String... args) throws Exception {
+        DocTreePathScannerTest t = new DocTreePathScannerTest();
+        t.run();
+    }
+
+    void run() throws Exception {
+        List<File> files = new ArrayList<File>();
+        File testSrc = new File(System.getProperty("test.src"));
+        for (File f: testSrc.listFiles()) {
+            if (f.isFile() && f.getName().endsWith(".java"))
+                files.add(f);
+        }
+
+        JavacTool javac = JavacTool.create();
+        StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null);
+
+        Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(files);
+
+        JavacTask t = javac.getTask(null, fm, null, null, null, fos);
+        DocTrees trees = DocTrees.instance(t);
+
+        Iterable<? extends CompilationUnitTree> units = t.parse();
+
+        DeclScanner ds = new DeclScanner(trees);
+        for (CompilationUnitTree unit: units) {
+            ds.scan(unit, null);
+        }
+
+        if (errors > 0)
+            throw new Exception(errors + " errors occurred");
+    }
+
+    void error(String msg) {
+        System.err.println("Error: " + msg);
+        errors++;
+    }
+
+    int errors;
+
+    class DeclScanner extends TreePathScanner<Void, Void> {
+        DocTrees trees;
+        DocTreePathScanner<Void,Void> cs;
+
+        DeclScanner(DocTrees trees) {
+            this.trees = trees;
+            cs = new CommentPathScanner();
+        }
+
+        @Override
+        public Void visitClass(ClassTree tree, Void ignore) {
+            super.visitClass(tree, ignore);
+            visitDecl(tree, tree.getSimpleName());
+            return null;
+        }
+
+        @Override
+        public Void visitMethod(MethodTree tree, Void ignore) {
+            super.visitMethod(tree, ignore);
+            visitDecl(tree, tree.getName());
+            return null;
+        }
+
+        @Override
+        public Void visitVariable(VariableTree tree, Void ignore) {
+            super.visitVariable(tree, ignore);
+            visitDecl(tree, tree.getName());
+            return null;
+        }
+
+        void visitDecl(Tree tree, Name name) {
+            TreePath path = getCurrentPath();
+            DocCommentTree dc = trees.getDocCommentTree(path);
+            if (dc != null)
+                cs.scan(new DocTreePath(path, dc), null);
+        }
+    }
+
+    class CommentPathScanner extends DocTreePathScanner<Void, Void> {
+        CommentPathScanner() {}
+
+        @Override
+        public Void scan(final DocTree tree, Void ignore) {
+            if (tree != null) {
+                DocTree previous = null;
+                for (DocTree current : getCurrentPath()) {
+                    if (previous != null) {
+                        final List<DocTree> children = new ArrayList<>();
+                        current.accept(new DocTreeScanner<Void, Void>() {
+                            @Override public Void scan(DocTree node, Void p) {
+                                children.add(node);
+                                return null;
+                            }
+                        }, null);
+
+                        if (!children.contains(previous)) {
+                            error("Invalid DocTreePath for: " + tree);
+                        }
+                    }
+
+                    previous = current;
+                }
+            }
+            return super.scan(tree, ignore);
+        }
+    }
+
+}
diff --git a/langtools/test/tools/javac/doctree/ReferenceTest.java b/langtools/test/tools/javac/doctree/ReferenceTest.java
index ee987ec..944a132 100644
--- a/langtools/test/tools/javac/doctree/ReferenceTest.java
+++ b/langtools/test/tools/javac/doctree/ReferenceTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -36,6 +36,8 @@
 import com.sun.source.doctree.ReferenceTree;
 import com.sun.source.doctree.SeeTree;
 import com.sun.source.doctree.TextTree;
+import com.sun.source.util.DocTreePath;
+import com.sun.source.util.DocTreePathScanner;
 import com.sun.source.util.DocTreeScanner;
 import com.sun.source.util.DocTrees;
 import com.sun.source.util.TreePath;
@@ -125,7 +127,7 @@
         return true;
     }
 
-    class DocCommentScanner extends DocTreeScanner<Void, Void> {
+    class DocCommentScanner extends DocTreePathScanner<Void, Void> {
         TreePath path;
         DocCommentTree dc;
 
@@ -135,7 +137,7 @@
 
         void scan() {
             dc = trees.getDocCommentTree(path);
-            scan(dc, null);
+            scan(new DocTreePath(path, dc), null);
         }
 
         @Override
@@ -158,7 +160,7 @@
         void checkReference(ReferenceTree tree, List<? extends DocTree> label) {
             String sig = tree.getSignature();
 
-            Element found = trees.getElement(path, tree);
+            Element found = trees.getElement(new DocTreePath(getCurrentPath(), tree));
             if (found == null) {
                 System.err.println(sig + " NOT FOUND");
             } else {
diff --git a/langtools/test/tools/javac/generics/7034511/T7034511a.java b/langtools/test/tools/javac/generics/7034511/T7034511a.java
index 5a8709c..af1f5a9 100644
--- a/langtools/test/tools/javac/generics/7034511/T7034511a.java
+++ b/langtools/test/tools/javac/generics/7034511/T7034511a.java
@@ -1,11 +1,13 @@
 /*
  * @test /nodynamiccopyright/
- * @ignore backing out 7034511, see 7040883
+ * @ignore 7041019 Bogus type-variable substitution with array types with dependencies on accessibility check
  * @bug     7034511 7040883
  * @summary Loophole in typesafety
  * @compile/fail/ref=T7034511a.out -XDrawDiagnostics T7034511a.java
  */
 
+// backing out 7034511, see 7040883
+
 class T7034511a {
 
     interface A<T> {
diff --git a/langtools/test/tools/javac/generics/7034511/T7034511b.java b/langtools/test/tools/javac/generics/7034511/T7034511b.java
index de29aea..2adebca 100644
--- a/langtools/test/tools/javac/generics/7034511/T7034511b.java
+++ b/langtools/test/tools/javac/generics/7034511/T7034511b.java
@@ -1,11 +1,13 @@
 /*
  * @test /nodynamiccopyright/
- * @ignore backing out 7034511, see 7040883
+ * @ignore 7041019 Bogus type-variable substitution with array types with dependencies on accessibility check
  * @bug     7034511 7040883
  * @summary Loophole in typesafety
  * @compile/fail/ref=T7034511b.out -XDrawDiagnostics T7034511b.java
  */
 
+// backing out 7034511, see 7040883
+
 class T7034511b {
     static class MyList<E> {
         E toArray(E[] e) { return null; }
diff --git a/langtools/test/tools/javac/generics/OverrideBridge.java b/langtools/test/tools/javac/generics/OverrideBridge.java
index 43c1f5e..9c9af07 100644
--- a/langtools/test/tools/javac/generics/OverrideBridge.java
+++ b/langtools/test/tools/javac/generics/OverrideBridge.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,11 +24,13 @@
 /*
  * @test
  * @bug 6337171 6996415
- * @ignore fix has been disabled as a consequence of 6996415
+ * @ignore 6996758: Investigate better override bridges strategy
  * @summary  javac should create bridge methods when type variable bounds restricted
  * @run main OverrideBridge
  */
 
+// fix, and test, has been disabled as a consequence of 6996415
+
 import java.io.*;
 import java.net.URI;
 import java.util.ArrayList;
diff --git a/langtools/src/share/classes/javax/tools/annotation/GenerateNativeHeader.java b/langtools/test/tools/javac/lambda/LambdaInterfaceStaticField.java
similarity index 62%
rename from langtools/src/share/classes/javax/tools/annotation/GenerateNativeHeader.java
rename to langtools/test/tools/javac/lambda/LambdaInterfaceStaticField.java
index 327ada7..5a8bf2e 100644
--- a/langtools/src/share/classes/javax/tools/annotation/GenerateNativeHeader.java
+++ b/langtools/test/tools/javac/lambda/LambdaInterfaceStaticField.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,25 +23,16 @@
  * questions.
  */
 
-package javax.tools.annotation;
-
-import java.lang.annotation.*;
-import static java.lang.annotation.RetentionPolicy.*;
-import static java.lang.annotation.ElementType.*;
-
-/**
- * An annotation used to indicate that a native header file
- * should be generated for this class.
- *
- * Normally, the presence of native methods is a sufficient
- * indication of the need for a native header file.  However,
- * in some cases, a class may contain constants of interest to
- * native code, without containing any native methods.
- *
- * @since 1.8
+/*
+ * @test
+ * @bug 8006140
+ * @summary Javac NPE compiling Lambda expression on initialization expression of static field in interface
+ * @compile LambdaInterfaceStaticField.java
  */
-@Documented
-@Target(TYPE)
-@Retention(SOURCE)
-public @interface GenerateNativeHeader {
+
+interface LambdaInterfaceStaticField {
+  interface I {
+     int m();
+  }
+  public static final I fld = () -> 5;
 }
diff --git a/hotspot/src/share/tools/launcher/jli_util.h b/langtools/test/tools/javac/lambda/LambdaWithInterfaceSuper.java
similarity index 68%
copy from hotspot/src/share/tools/launcher/jli_util.h
copy to langtools/test/tools/javac/lambda/LambdaWithInterfaceSuper.java
index 535f7c4..c8f7727 100644
--- a/hotspot/src/share/tools/launcher/jli_util.h
+++ b/langtools/test/tools/javac/lambda/LambdaWithInterfaceSuper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -19,17 +19,25 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
-#ifndef _JLI_UTIL_H
-#define _JLI_UTIL_H
+/*
+ * @test
+ * @bug 8010006
+ * @summary NPE in javac with interface super in lambda
+ * @compile LambdaWithInterfaceSuper.java
+ */
 
-#include <stdlib.h>
+class LambdaWithInterfaceSuper {
 
-void *JLI_MemAlloc(size_t size);
-void *JLI_MemRealloc(void *ptr, size_t size);
-char *JLI_StringDup(const char *s1);
-void  JLI_MemFree(void *ptr);
+    interface Sup {
+        default void m() {}
+    }
 
-#endif  /* _JLI_UTIL_H */
+    interface I extends Sup {
+        default void m() {
+            Runnable r = ()-> { Sup.super.m(); };
+            r.run();
+       }
+    }
+}
diff --git a/langtools/test/tools/javac/lambda/MethodReference66.java b/langtools/test/tools/javac/lambda/MethodReference66.java
index 6f4b80c..6c6751c 100644
--- a/langtools/test/tools/javac/lambda/MethodReference66.java
+++ b/langtools/test/tools/javac/lambda/MethodReference66.java
@@ -24,6 +24,7 @@
 /*
  * @test
  * @bug 8009299
+ * @ignore 8013875: Incorrect vtable index being set during methodHandle creation for static
  * @summary Javac crashes when compiling method reference to static interface method
  * @run main/othervm -Xverify:none MethodReference66
  */
diff --git a/langtools/test/tools/javac/lambda/MethodReference67.java b/langtools/test/tools/javac/lambda/MethodReference67.java
new file mode 100644
index 0000000..7f98699
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/MethodReference67.java
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8012685
+ * @summary Spurious raw types warning when using unbound method references
+ * @compile/fail/ref=MethodReference67.out -Werror -Xlint:rawtypes -XDrawDiagnostics MethodReference67.java
+ */
+import java.util.*;
+
+class MethodReference67 {
+    interface Foo<X> {
+        void m(List<X> lx, X x);
+    }
+
+    void test() {
+        Foo<String> fs1 = List::add; //no raw warnings here!
+        Foo fs2 = List::add;
+    }
+}
diff --git a/langtools/test/tools/javac/lambda/MethodReference67.out b/langtools/test/tools/javac/lambda/MethodReference67.out
new file mode 100644
index 0000000..7d06e04
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/MethodReference67.out
@@ -0,0 +1,7 @@
+MethodReference67.java:16:9: compiler.warn.raw.class.use: MethodReference67.Foo, MethodReference67.Foo<X>
+MethodReference67.java:16:19: compiler.warn.raw.class.use: java.util.List, java.util.List<E>
+- compiler.err.warnings.and.werror
+- compiler.note.unchecked.filename: MethodReference67.java
+- compiler.note.unchecked.recompile
+1 error
+2 warnings
diff --git a/langtools/test/tools/javac/lambda/NoWarnOnImplicitParams.java b/langtools/test/tools/javac/lambda/NoWarnOnImplicitParams.java
new file mode 100644
index 0000000..39a1da5
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/NoWarnOnImplicitParams.java
@@ -0,0 +1,26 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8013222
+ * @summary Javac issues spurious raw type warnings when lambda has implicit parameter types
+ * @compile/fail/ref=NoWarnOnImplicitParams.out -Xlint:rawtypes -Werror -XDrawDiagnostics NoWarnOnImplicitParams.java
+ */
+import java.util.List;
+
+class NoWarnOnImplicitParams {
+
+    public void testRawMerge(List<String> ls) {
+        R12 r12_1 = l->"Foo";
+        R12 r12_2 = (List l)->"Foo";
+    }
+
+    interface R1 {
+        Object m(List<String> ls);
+    }
+
+    @SuppressWarnings("rawtypes")
+    interface R2 {
+        String m(List l);
+    }
+
+    interface R12 extends R1, R2 {}
+}
diff --git a/langtools/test/tools/javac/lambda/NoWarnOnImplicitParams.out b/langtools/test/tools/javac/lambda/NoWarnOnImplicitParams.out
new file mode 100644
index 0000000..684de0f
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/NoWarnOnImplicitParams.out
@@ -0,0 +1,4 @@
+NoWarnOnImplicitParams.java:13:22: compiler.warn.raw.class.use: java.util.List, java.util.List<E>
+- compiler.err.warnings.and.werror
+1 error
+1 warning
diff --git a/langtools/test/tools/javac/lambda/TargetType36.java b/langtools/test/tools/javac/lambda/TargetType36.java
index 54feffc..7740b57 100644
--- a/langtools/test/tools/javac/lambda/TargetType36.java
+++ b/langtools/test/tools/javac/lambda/TargetType36.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @ignore
+ * @ignore 8013404: Test awaits spec clarification
  * @bug 8003280
  * @summary Add lambda tests
  *  check that target type of cast is propagated to conditional subexpressions
diff --git a/langtools/test/tools/javac/lambda/TargetType53.java b/langtools/test/tools/javac/lambda/TargetType53.java
index 26c9887..6b0da2f 100644
--- a/langtools/test/tools/javac/lambda/TargetType53.java
+++ b/langtools/test/tools/javac/lambda/TargetType53.java
@@ -26,7 +26,7 @@
  * @bug 8007464
  * @summary Add graph inference support
  *          smoke test for graph inference
- * @ignore  awaits stream API: 800NNNN
+ * @ignore  8008682: Core stream API classes
  * @compile TargetType53.java
  */
 import java.util.*;
diff --git a/langtools/test/tools/javac/lambda/TargetType54.java b/langtools/test/tools/javac/lambda/TargetType54.java
index 0d73270..30bbf8a 100644
--- a/langtools/test/tools/javac/lambda/TargetType54.java
+++ b/langtools/test/tools/javac/lambda/TargetType54.java
@@ -26,7 +26,7 @@
  * @bug 8007464
  * @summary Add graph inference support
  *          smoke test for graph inference
- * @ignore  awaits stream API: 800NNNN
+ * @ignore  8008682: Core stream API classes
  * @compile TargetType54.java
  */
 import java.util.stream.*;
diff --git a/langtools/test/tools/javac/lambda/TargetType58.java b/langtools/test/tools/javac/lambda/TargetType58.java
index 4ba44a9..50a8d99 100644
--- a/langtools/test/tools/javac/lambda/TargetType58.java
+++ b/langtools/test/tools/javac/lambda/TargetType58.java
@@ -26,7 +26,7 @@
  * @bug 8007464
  * @summary Add graph inference support
  *          more smoke tests for graph inference
- * @ignore  awaits stream API: 800NNNN
+ * @ignore  8008682: Core stream API classes
  * @compile TargetType58.java
  */
 import java.util.*;
diff --git a/langtools/test/tools/javac/lambda/TargetType59.java b/langtools/test/tools/javac/lambda/TargetType59.java
index 64fc92e..1bae374 100644
--- a/langtools/test/tools/javac/lambda/TargetType59.java
+++ b/langtools/test/tools/javac/lambda/TargetType59.java
@@ -26,7 +26,7 @@
  * @bug 8007464
  * @summary Add graph inference support
  *          more smoke tests for graph inference
- * @ignore  awaits stream API: 800NNNN
+ * @ignore  8008682: Core stream API classes
  * @compile TargetType59.java
  */
 import java.util.*;
diff --git a/langtools/test/tools/javac/lambda/TargetType62.java b/langtools/test/tools/javac/lambda/TargetType62.java
index 49436b6..dec14bb 100644
--- a/langtools/test/tools/javac/lambda/TargetType62.java
+++ b/langtools/test/tools/javac/lambda/TargetType62.java
@@ -26,7 +26,7 @@
  * @bug 8007464
  * @summary Add graph inference support
  *          check that new wildcards inference strategy doesn't run into 7190296
- * @ignore  awaits stream API: 800NNNN
+ * @ignore  8008682: Core stream API classes
  * @compile TargetType62.java
  */
 import java.util.*;
diff --git a/langtools/test/tools/javac/lambda/TargetType66.out b/langtools/test/tools/javac/lambda/TargetType66.out
index b4f311f..b5c828d 100644
--- a/langtools/test/tools/javac/lambda/TargetType66.out
+++ b/langtools/test/tools/javac/lambda/TargetType66.out
@@ -1,4 +1,4 @@
 TargetType66.java:22:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66
-TargetType66.java:23:9: compiler.err.cant.apply.symbols: kindname.method, g, @578,{(compiler.misc.inapplicable.method: kindname.method, TargetType66, g(TargetType66.SAM1), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.arg.types.in.lambda: java.lang.String))),(compiler.misc.inapplicable.method: kindname.method, TargetType66, g(TargetType66.SAM2), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.arg.types.in.lambda: java.lang.Integer)))}
+TargetType66.java:23:9: compiler.err.cant.apply.symbols: kindname.method, g, @578,{(compiler.misc.inapplicable.method: kindname.method, TargetType66, g(TargetType66.SAM1), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.arg.types.in.lambda: java.lang.String, (compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Character))))),(compiler.misc.inapplicable.method: kindname.method, TargetType66, g(TargetType66.SAM2), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.arg.types.in.lambda: java.lang.Integer, (compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Integer, java.lang.Character)))))}
 TargetType66.java:24:30: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Character)
 3 errors
diff --git a/langtools/test/tools/javac/lambda/bytecode/TestLambdaBytecode.java b/langtools/test/tools/javac/lambda/bytecode/TestLambdaBytecode.java
index 38818f6..300f61c 100644
--- a/langtools/test/tools/javac/lambda/bytecode/TestLambdaBytecode.java
+++ b/langtools/test/tools/javac/lambda/bytecode/TestLambdaBytecode.java
@@ -306,7 +306,7 @@
     String makeIndyType(int id) {
         StringBuilder buf = new StringBuilder();
         buf.append("(");
-        if (!mk2.isStatic() || mk1.inInterface()) {
+        if (!mk2.isStatic()) {
             buf.append(String.format("LTest%d;", id));
         }
         buf.append(")Ljava/lang/Runnable;");
diff --git a/langtools/test/tools/javac/lambda/lambdaExecution/InInterface.java b/langtools/test/tools/javac/lambda/lambdaExecution/InInterface.java
index 778ee49..ca7dc27 100644
--- a/langtools/test/tools/javac/lambda/lambdaExecution/InInterface.java
+++ b/langtools/test/tools/javac/lambda/lambdaExecution/InInterface.java
@@ -26,6 +26,7 @@
 /**
  * @test
  * @bug 8003639
+ * @ignore 8013875: Incorrect vtable index being set during methodHandle creation for static
  * @summary convert lambda testng tests to jtreg and add them
  * @run testng InInterface
  */
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass3.java b/langtools/test/tools/javac/lambda/methodReference/TreeMakerParamsIsGoofy.java
similarity index 60%
copy from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass3.java
copy to langtools/test/tools/javac/lambda/methodReference/TreeMakerParamsIsGoofy.java
index fe2be5a..92f692b 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass3.java
+++ b/langtools/test/tools/javac/lambda/methodReference/TreeMakerParamsIsGoofy.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,34 +21,33 @@
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
+/**
+ * @test
+ * @bug 8014023
+ * @summary When a method reference to a local class constructor is contained
+ *          in a method whose number of parameters matches the number of
+ *          constructor parameters compilation fails
+ * @compile TreeMakerParamsIsGoofy.java
+ * @run main TreeMakerParamsIsGoofy
+ */
 
-@GenerateNativeHeader
-public class TestClass3 {
-    public int tc3;
+public class TreeMakerParamsIsGoofy {
 
-    public class Inner1 {
-        public int tc3i1;
+    interface III { }
 
-        public class Inner1A {
-            public int tc3i1i1a;
-        }
-
-        public class Inner1B {
-            public int tc3i1i1b;
-        }
+    interface UO {
+        III m(III x);
     }
 
-    public class Inner2 {
-        public int tc321;
-
-        public class Inner2A {
-            public int tc3i2i2a;
+    public static void main(String[] args) {
+        class BA implements III {
+            BA(III b) {
+            }
         }
 
-        public class Inner2B {
-            public int tc3i2i2b;
-        }
+        ts(BA::new);
+    }
+
+    static void ts(UO ba) {
     }
 }
-
diff --git a/langtools/test/tools/javac/lib/DPrinter.java b/langtools/test/tools/javac/lib/DPrinter.java
index 0e71f57..9f3e887 100644
--- a/langtools/test/tools/javac/lib/DPrinter.java
+++ b/langtools/test/tools/javac/lib/DPrinter.java
@@ -469,6 +469,7 @@
                     indent(+1);
                     printSymbol("tsym", type.tsym, Details.SUMMARY);
                     printObject("constValue", type.constValue(), Details.SUMMARY);
+                    printObject("annotations", type.getAnnotationMirrors(), Details.SUMMARY);
                     type.accept(typeVisitor, null);
                     indent(-1);
             }
diff --git a/langtools/test/tools/javac/multicatch/Pos11.java b/langtools/test/tools/javac/multicatch/Pos11.java
new file mode 100644
index 0000000..0d053d0
--- /dev/null
+++ b/langtools/test/tools/javac/multicatch/Pos11.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug     8013163
+ * @author  sogoel
+ * @summary Test multiple nested multi-catch blocks with Exception hierarchies
+ * @run main Pos11
+ */
+
+/*
+ * For this test, exception hierarchy used:
+ *
+ *           Throwable
+ *             /   \
+ *      Exception  Error
+ *       |    |      |
+ *       A    B      D
+ *            |
+ *            C
+ *            |
+ *            E
+ * As an exception is thrown within a nested try-catch block, outer catch blocks
+ * will catch an exception or its child exceptions, so the same exception can
+ * be caught and rethrown multiple times.
+ */
+
+public class Pos11 {
+
+    public static String results = "";
+    public static String sExpected = "-AB:A-AB:B-CD:C-AB:C-CD:D-Throwable:D-CD:E" +
+            "-AB:E-Exception:Exception-Throwable:Exception";
+
+    enum TestExceptions {
+        A("A"),
+        B("B"),
+        C("C"),
+        D("D"),
+        E("E"),
+        U("U");
+
+        String exType;
+        TestExceptions(String type) {
+            this.exType = type;
+        }
+    }
+
+    public static void main(String... args) {
+        Pos11 pos11 = new Pos11();
+        for(TestExceptions t : TestExceptions.values()) {
+            pos11.rethrower(t.exType);
+        }
+        if (results.compareTo(sExpected) != 0)
+            throw new RuntimeException("FAIL: final strings did not match:\n"
+                    + results + "!=\n" + sExpected);
+        System.out.println("PASS");
+    }
+
+    void rethrower(String T) {
+        try { /* try1 */
+            try { /* try2 */
+                try { /* try3 */
+                    try { /* try4 */
+                        switch (T) {
+                        case "A":
+                            throw new A();
+                        case "B":
+                            throw new B();
+                        case "C":
+                            throw new C();
+                        case "D":
+                            throw new D();
+                        case "E":
+                            throw new E();
+                        default:
+                            throw new Exception(
+                                    new Throwable());
+                        }
+                    } catch ( final C|D cd) {
+                        results=results.concat("-CD:" + cd.getClass().getSimpleName());
+                        throw cd;
+                    }
+                } catch (final A|B ab) {
+                    results=results.concat("-AB:" + ab.getClass().getSimpleName());
+                }
+            } catch (final Exception e ) {
+                results=results.concat("-Exception:" + e.getClass().getSimpleName());
+                throw e;
+            }
+        } catch (Throwable t) {
+            results=results.concat("-Throwable:" + t.getClass().getSimpleName());
+        }
+    }
+
+    // Test Exception
+    static class A extends Exception {}
+
+    // Test Exception
+    static class B extends Exception {}
+
+    // Test Exception
+    static class C extends B {}
+
+    // Not a descendant of Exception
+    static class D extends Error {}
+
+    // Test Exception
+    static class E extends C {}
+
+}
+
diff --git a/langtools/test/tools/javac/multicatch/Pos12.java b/langtools/test/tools/javac/multicatch/Pos12.java
new file mode 100644
index 0000000..7b39b66
--- /dev/null
+++ b/langtools/test/tools/javac/multicatch/Pos12.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug     8013163
+ * @author  sogoel
+ * @summary Child exception can be caught in a parents catch block but not sibling exceptions.
+ * @run main Pos12
+ */
+
+/*
+ * For this test:
+ *    RuntimeException
+ *    |
+ *    A
+ *   / \
+ *  Ab Ac
+ * This test throws an Ab and catches it as an A(parent).
+ * The exception, although catch as an A, is rethrown and eventually
+ * caught as an Ab. Before that it is NOT caught as an Ac.
+ */
+
+public class Pos12 {
+
+    public static void main(String... args) {
+        try {
+            new Pos12().test();
+        } catch (A exception) {
+            try {
+                try {
+                    throw exception; // used to throw A, now throws Ab
+                } catch (Ac cException) { // This should NOT catch sibling exception Ab
+                    throw new RuntimeException("FAIL: Should not be caught in catch Ac");
+                }
+            } catch (Ab | Ac bcException) {
+                if (bcException instanceof Ac) {
+                    throw new RuntimeException("FAIL: Sibling exception Ab not caught as expected");
+                } else if (bcException instanceof Ab) {
+                    System.out.println("PASS");
+                }
+            }
+        }
+    }
+
+    public void test() { throw new Ab(); }
+
+    static class A extends RuntimeException {}
+
+    // Test class
+    static class Ab extends A {}
+
+    // Test class
+    static class Ac extends A {}
+}
+
diff --git a/langtools/test/tools/javac/nativeHeaders/NativeHeaderTest.java b/langtools/test/tools/javac/nativeHeaders/NativeHeaderTest.java
index ecc79ea..a14c71e 100644
--- a/langtools/test/tools/javac/nativeHeaders/NativeHeaderTest.java
+++ b/langtools/test/tools/javac/nativeHeaders/NativeHeaderTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 7150368 8003412
+ * @bug 7150368 8003412 8000407
  * @summary javac should include basic ability to generate native headers
  */
 
@@ -125,17 +125,6 @@
     }
 
     @Test
-    void oldAnnoTest(RunKind rk, GenKind gk) throws Exception {
-        List<File> files = new ArrayList<File>();
-        files.add(createFile("p/C.java",
-                "@javax.tools.annotation.GenerateNativeHeader class C { }"));
-
-        Set<String> expect = createSet("C.h");
-
-        test(rk, gk, files, expect);
-    }
-
-    @Test
     void annoTest(RunKind rk, GenKind gk) throws Exception {
         List<File> files = new ArrayList<File>();
         files.add(createFile("p/C.java",
@@ -147,18 +136,6 @@
     }
 
     @Test
-    void oldAnnoNestedClassTest(RunKind rk, GenKind gk) throws Exception {
-        List<File> files = new ArrayList<File>();
-        files.add(createFile("p/C.java",
-                "class C { @javax.tools.annotation.GenerateNativeHeader class Inner { } }"));
-
-        Set<String> expect = createSet("C_Inner.h");
-        if (gk == GenKind.FULL) expect.add("C.h");
-
-        test(rk, gk, files, expect);
-    }
-
-    @Test
     void annoNestedClassTest(RunKind rk, GenKind gk) throws Exception {
         List<File> files = new ArrayList<File>();
         files.add(createFile("p/C.java",
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/CompareTest.java b/langtools/test/tools/javac/nativeHeaders/javahComparison/CompareTest.java
index 8e28752..a4a9ab6 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/CompareTest.java
+++ b/langtools/test/tools/javac/nativeHeaders/javahComparison/CompareTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 7150368 8003412
+ * @bug 7150368 8003412 8000407
  * @summary javac should include basic ability to generate native headers
  */
 
diff --git a/langtools/test/tools/javac/plugin/showtype/Test.java b/langtools/test/tools/javac/plugin/showtype/Test.java
index 553e4b4..b1a3b59 100644
--- a/langtools/test/tools/javac/plugin/showtype/Test.java
+++ b/langtools/test/tools/javac/plugin/showtype/Test.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -23,7 +23,7 @@
 
 /**
  *  @test
- *  @bug 8001098 8004961
+ *  @bug 8001098 8004961 8004082
  *  @summary Provide a simple light-weight "plug-in" mechanism for javac
  */
 
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedA1Test.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedA1Test.java
index 222cf01..8844cd1 100644
--- a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedA1Test.java
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedA1Test.java
@@ -22,13 +22,13 @@
  */
 
 /*
- * @ignore
  * @test
  * @bug     8004822
  * @author  mnunez
  * @summary Language model api test basics for repeating annotations
  * @library /tools/javac/lib
  * @library supportingAnnotations
+ * @ignore  8013407: test failures for repeating annotations
  * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
  * @compile -processor ElementRepAnnoTester -proc:only
  * MixRepeatableAndOfficialContainerInheritedA1Test.java
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB1Test.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB1Test.java
index 333b960..e2141da 100644
--- a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB1Test.java
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB1Test.java
@@ -22,13 +22,13 @@
  */
 
 /*
- * @ignore
  * @test
  * @bug     8004822
  * @author  mnunez
  * @summary Language model api test basics for repeating annotations
  * @library /tools/javac/lib
  * @library supportingAnnotations
+ * @ignore  8013407: test failures for repeating annotations
  * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
  * @compile -processor ElementRepAnnoTester -proc:only
  * MixRepeatableAndOfficialContainerInheritedB1Test.java
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB2Test.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB2Test.java
index 0197738..fb6efb4 100644
--- a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB2Test.java
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB2Test.java
@@ -22,13 +22,13 @@
  */
 
 /*
- * @ignore
  * @test
  * @bug     8004822
  * @author  mnunez
  * @summary Language model api test basics for repeating annotations
  * @library /tools/javac/lib
  * @library supportingAnnotations
+ * @ignore  8013407: test failures for repeating annotations
  * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
  * @compile -processor ElementRepAnnoTester -proc:only
  * MixRepeatableAndOfficialContainerInheritedB2Test.java
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideATest.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideATest.java
index df0d46a..395a2a6 100644
--- a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideATest.java
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideATest.java
@@ -22,13 +22,13 @@
  */
 
 /*
- * @ignore
  * @test
  * @bug     8004822
  * @author  mnunez
  * @summary Language model api test basics for repeating annotations
  * @library /tools/javac/lib
  * @library supportingAnnotations
+ * @ignore  8013407: test failures for repeating annotations
  * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
  * @compile -processor ElementRepAnnoTester -proc:only RepeatableOverrideATest.java
  */
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideBTest.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideBTest.java
index e9bd3ae..f16ec7a 100644
--- a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideBTest.java
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideBTest.java
@@ -22,13 +22,13 @@
  */
 
 /*
- * @ignore
  * @test
  * @bug     8004822
  * @author  mnunez
  * @summary Language model api test basics for repeating annotations
  * @library /tools/javac/lib
  * @library supportingAnnotations
+ * @ignore  8013407: test failures for repeating annotations
  * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
  * @compile -processor ElementRepAnnoTester -proc:only RepeatableOverrideBTest.java
  */
diff --git a/langtools/test/tools/javac/processing/model/type/BasicAnnoTests.java b/langtools/test/tools/javac/processing/model/type/BasicAnnoTests.java
new file mode 100644
index 0000000..0b0bd8e
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/type/BasicAnnoTests.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug     1234567
+ * @summary Annotations on types
+ * @library /tools/javac/lib
+ * @build JavacTestingAbstractProcessor DPrinter BasicAnnoTests
+ * @compile/process -processor BasicAnnoTests -proc:only BasicAnnoTests.java
+ */
+
+import java.io.PrintWriter;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.AnnotatedConstruct;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.type.WildcardType;
+import javax.tools.Diagnostic.Kind;
+
+import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.processing.JavacProcessingEnvironment;
+
+/**
+ * The test scans this file looking for test cases annotated with @Test.
+ */
+public class BasicAnnoTests extends JavacTestingAbstractProcessor {
+    DPrinter dprinter;
+    PrintWriter out;
+    boolean verbose = true;
+
+    @Override
+    public void init(ProcessingEnvironment pEnv) {
+        super.init(pEnv);
+        dprinter = new DPrinter(((JavacProcessingEnvironment) pEnv).getContext());
+        out = dprinter.out;
+    }
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        TestElementScanner s = new TestElementScanner();
+        for (Element e: roundEnv.getRootElements()) {
+            s.scan(e);
+        }
+        return true;
+    }
+
+    void error(Element e, String msg) {
+        messager.printMessage(Kind.ERROR, msg, e);
+        errors++;
+    }
+
+    int errors;
+
+    /**
+     * Scan an element looking for declarations annotated with @Test.
+     * Run a TestTypeScanner on the annotations that are found.
+     */
+    class TestElementScanner extends ElementScanner<Void,Void> {
+        public Void scan(Element elem, Void ignore) {
+            AnnotationMirror test = getAnnotation(elem, Test.class.getName().replace('$', '.'));
+            if (test != null) {
+                out.println("Test: " + elem + " " + test);
+                TestTypeScanner s = new TestTypeScanner(elem, test);
+                s.scan(elem.asType(), null);
+                if (getPosn(test) >= s.count)
+                    error(elem, "position " + getPosn(test) + " not found");
+                if (!s.found) {
+                    dprinter.printSymbol("element", (Symbol) elem);
+                    dprinter.printType("type", (Type) elem.asType());
+                }
+                out.println();
+            }
+            return super.scan(elem, ignore);
+        }
+    }
+
+    /**
+     * Scan the type of an element, looking for an annotation
+     * to match the expected annotation specified in the @Test annotation.
+     */
+    class TestTypeScanner extends TypeScanner<Void, Void> {
+        Element elem;
+        AnnotationMirror test;
+        int count = 0;
+        boolean found = false;
+
+        TestTypeScanner(Element elem, AnnotationMirror test) {
+            this.elem = elem;
+            this.test = test;
+        }
+
+        @Override
+        Void scan(TypeMirror t, Void ignore) {
+            if (t == null)
+                return DEFAULT_VALUE;
+            if (verbose)
+                out.println("scan " + count + ": " + t);
+            if (count == getPosn(test)) {
+                String annoType = getAnnoType(test);
+                AnnotationMirror anno = getAnnotation(t, annoType);
+                if (anno == null) {
+                    error(elem, "annotation not found on " + count + ": " + t);
+                } else {
+                    String v = getValue(anno, "value").toString();
+                    if (v.equals(getExpect(test))) {
+                        out.println("found " + anno + " as expected");
+                        found = true;
+                    } else {
+                        error(elem, "Unexpected value: " + v + ", expected: " + getExpect(test));
+                    }
+                }
+            }
+            count++;
+            return super.scan(t, ignore);
+        }
+    }
+
+    /** Get the position value from an @Test annotation mirror. */
+    static int getPosn(AnnotationMirror test) {
+        AnnotationValue v = getValue(test, "posn");
+        return (Integer) v.getValue();
+    }
+
+    /** Get the expect value from an @Test annotation mirror. */
+    static String getExpect(AnnotationMirror test) {
+        AnnotationValue v = getValue(test, "expect");
+        return (String) v.getValue();
+    }
+
+    /** Get the annoType value from an @Test annotation mirror. */
+    static String getAnnoType(AnnotationMirror test) {
+        AnnotationValue v = getValue(test, "annoType");
+        TypeMirror m = (TypeMirror) v.getValue();
+        return m.toString();
+    }
+
+    /**
+     * Get a specific annotation mirror from an annotated construct.
+     */
+    static AnnotationMirror getAnnotation(AnnotatedConstruct e, String name) {
+        for (AnnotationMirror m: e.getAnnotationMirrors()) {
+            TypeElement te = (TypeElement) m.getAnnotationType().asElement();
+            if (te.getQualifiedName().contentEquals(name)) {
+                return m;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Get a specific value from an annotation mirror.
+     */
+    static AnnotationValue getValue(AnnotationMirror anno, String name) {
+        Map<? extends ExecutableElement, ? extends AnnotationValue> map = anno.getElementValues();
+        for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> e: map.entrySet()) {
+            if (e.getKey().getSimpleName().contentEquals(name)) {
+                return e.getValue();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * The Language Model API does not provide a type scanner, so provide
+     * one sufficient for our needs.
+     */
+    static class TypeScanner<R, P> extends SimpleTypeVisitor<R, P> {
+        @Override
+        public R visitArray(ArrayType t, P p) {
+            scan(t.getComponentType(), p);
+            return super.visitArray(t, p);
+        }
+
+        @Override
+        public R visitExecutable(ExecutableType t, P p) {
+            scan(t.getReceiverType());
+            //out.println("  params: " + t.getParameterTypes());
+            scan(t.getParameterTypes(), p);
+            //out.println("  return: " + t.getReturnType());
+            scan(t.getReturnType(), p);
+            //out.println("  throws: " + t.getThrownTypes());
+            scan(t.getThrownTypes(), p);
+            return super.visitExecutable(t, p);
+        }
+
+        @Override
+        public R visitTypeVariable(TypeVariable t, P p) {
+            scan(t.getLowerBound(), p);
+            scan(t.getUpperBound(), p);
+            return super.visitTypeVariable(t, p);
+        }
+
+        @Override
+        public R visitWildcard(WildcardType t, P p) {
+            scan(t.getExtendsBound(), p);
+            scan(t.getSuperBound(), p);
+            return super.visitWildcard(t, p);
+        }
+
+        R scan(TypeMirror t) {
+            return scan(t, null);
+        }
+
+        R scan(TypeMirror t, P p) {
+            return (t == null) ? DEFAULT_VALUE : t.accept(this, p);
+        }
+
+        R scan(Iterable<? extends TypeMirror> iter, P p) {
+            if (iter == null)
+                return DEFAULT_VALUE;
+            R result = DEFAULT_VALUE;
+            for (TypeMirror t: iter)
+                result = scan(t, p);
+            return result;
+        }
+    }
+
+    /** Annotation to identify test cases. */
+    @interface Test {
+        /** Where to look for the annotation, expressed as a scan index. */
+        int posn();
+        /** The annotation to look for. */
+        Class<? extends Annotation> annoType();
+        /** The string representation of the annotation's value. */
+        String expect();
+    }
+
+    /** Type annotation to use in test cases. */
+    @Target(ElementType.TYPE_USE)
+    public @interface TA {
+        int value();
+    }
+
+    @Test(posn=0, annoType=TA.class, expect="1")
+    public @TA(1) int f1;
+
+    @Test(posn=0, annoType=TA.class, expect="2")
+    public int @TA(2) [] f2;
+
+    @Test(posn=1, annoType=TA.class, expect="3")
+    public @TA(3) int [] f3;
+
+    @Test(posn=1, annoType=TA.class, expect="4")
+    public int m1(@TA(4) float a) throws Exception { return 0; }
+
+    @Test(posn=2, annoType=TA.class, expect="5")
+    public @TA(5) int m2(float a) throws Exception { return 0; }
+
+    @Test(posn=3, annoType=TA.class, expect="6")
+    public int m3(float a) throws @TA(6) Exception { return 0; }
+}
diff --git a/langtools/test/tools/javac/profiles/ProfileOptionTest.java b/langtools/test/tools/javac/profiles/ProfileOptionTest.java
index 2fc55b2..eaae7d9 100644
--- a/langtools/test/tools/javac/profiles/ProfileOptionTest.java
+++ b/langtools/test/tools/javac/profiles/ProfileOptionTest.java
@@ -179,7 +179,7 @@
                 javax.xml.XMLConstants.class);
 
         init(Profile.COMPACT3,
-                javax.script.Bindings.class,
+                javax.sql.rowset.Predicate.class,
                 com.sun.security.auth.PolicyFile.class); // specifically included in 3
 
         init(Profile.DEFAULT,
diff --git a/langtools/test/tools/javac/tree/SourceTreeScannerTest.java b/langtools/test/tools/javac/tree/SourceTreeScannerTest.java
index a719202..e4cc3f8 100644
--- a/langtools/test/tools/javac/tree/SourceTreeScannerTest.java
+++ b/langtools/test/tools/javac/tree/SourceTreeScannerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/langtools/test/tools/javap/output/RepeatingTypeAnnotations.java b/langtools/test/tools/javap/output/RepeatingTypeAnnotations.java
index 706f9d9..f78bf12 100644
--- a/langtools/test/tools/javap/output/RepeatingTypeAnnotations.java
+++ b/langtools/test/tools/javap/output/RepeatingTypeAnnotations.java
@@ -121,280 +121,307 @@
      */
 
     @TestCase
-    @ignore // 8008082:missing type annotation for cast
     public static class TC1 extends RepeatingTypeAnnotations {
         public TC1() {
-            setSrc("    static String so = \"hello world\";",
+            setSrc(" /* TC1 */ ",
+                   "    static String so = \"hello world\";",
                    "    public @A @A @A Object o = (@A @A @A String) Test.so;");
             verify("RuntimeInvisibleTypeAnnotations",
                    "0: #25(#26=[@#27(),@#27(),@#27()]): FIELD",
-                   "1: #25(#26=[@#27(),@#27(),@#27()]): CAST, offset=5");
+                   "0: #25(#26=[@#27(),@#27(),@#27()]): CAST, offset=5, type_index=0");
         }
     }
 
     @TestCase
     public static class TC2 extends RepeatingTypeAnnotations {
         public TC2() {
-            setSrc("    static String so = \"hello world\";",
+            setSrc(" /* TC2 */ ",
+                   "    static String so = \"hello world\";",
                    "    public @A @B @A Object o = (@B @A @B String) Test.so;");
             verify("RuntimeInvisibleTypeAnnotations",
                    "0: #25(#26=[@#27(),@#27()]): FIELD",
                    "1: #28(): FIELD",
-                   "2: #29(#26=[@#28(),@#28()]): CAST, offset=5",
-                   "3: #27(): CAST, offset=5");
+                   "0: #36(#26=[@#28(),@#28()]): CAST, offset=5, type_index=0",
+                   "1: #27(): CAST, offset=5, type_index=0");
         }
     }
 
     @TestCase
     public static class TC3 extends RepeatingTypeAnnotations {
         public TC3() {
-            setSrc("    static String so = \"hello world\";",
+            setSrc(" /* TC3 */ ",
+                   "    static String so = \"hello world\";",
                    "    public @A @A @C Object o = (@B @C @B String) Test.so;");
-            verify("RuntimeInvisibleTypeAnnotations",
+            verify("RuntimeVisibleTypeAnnotations",
+                   "RuntimeInvisibleTypeAnnotations",
                    "0: #25(): FIELD",
-                   "1: #25(): CAST, offset=5",
-                   "RuntimeVisibleTypeAnnotations",
                    "0: #27(#28=[@#29(),@#29()]): FIELD",
-                   "1: #30(#28=[@#31(),@#31()]): CAST, offset=5");
+                   "0: #25(): CAST, offset=5, type_index=0",
+                   "0: #37(#28=[@#38(),@#38()]): CAST, offset=5, type_index=0");
         }
     }
 
     @TestCase
     public static class TC4 extends RepeatingTypeAnnotations {
         public TC4() {
-            setSrc("    static String so = \"hello world\";",
+            setSrc(" /* TC4 */ ",
+                   "    static String so = \"hello world\";",
                    "    public @A @B @C Object o = (@C @B @A String) Test.so;");
             verify("RuntimeInvisibleTypeAnnotations",
                    "RuntimeVisibleTypeAnnotations",
                    "0: #25(): FIELD",
-                   "1: #25(): CAST, offset=5",
                    "0: #27(): FIELD",
                    "1: #28(): FIELD",
-                   "2: #28(): CAST, offset=5",
-                   "3: #27(): CAST, offset=5");
+                   "0: #25(): CAST, offset=5, type_index=0",
+                   "0: #28(): CAST, offset=5, type_index=0",
+                   "1: #27(): CAST, offset=5, type_index=0");
         }
     }
 
     @TestCase
-    @ignore // 8008082:missing type annotation for cast
     public static class TC5 extends RepeatingTypeAnnotations {
         public TC5() {
-            setSrc("    static String so = \"hello world\";",
+            setSrc(" /* TC5 */ ",
+                   "    static String so = \"hello world\";",
                    "    public static @A @A @A Object o = (@B @B @B String) Test.so;");
             verify("RuntimeInvisibleTypeAnnotations",
                    "0: #25(#26=[@#27(),@#27(),@#27()]): FIELD",
-                   "1: #28(#26=[@#29(),@#29(),@#29()]): CAST, offset=5, type_index=0");
+                   "0: #36(#26=[@#37(),@#37(),@#37()]): CAST, offset=5, type_index=0");
         }
     }
 
     @TestCase
     public static class TC6 extends RepeatingTypeAnnotations {
         public TC6() {
-            setSrc("    static String so = \"hello world\";",
+            setSrc(" /* TC6 */ ",
+                   "    static String so = \"hello world\";",
                    "    public static @A @B @A Object o = (@B @A @B String) Test.so;");
             verify("RuntimeInvisibleTypeAnnotations",
                    "0: #25(#26=[@#27(),@#27()]): FIELD",
                    "1: #28(): FIELD",
-                   "2: #29(#26=[@#28(),@#28()]): CAST, offset=5",
-                   "3: #27(): CAST, offset=5");
+                   "0: #37(#26=[@#28(),@#28()]): CAST, offset=5, type_index=0",
+                   "1: #27(): CAST, offset=5, type_index=0");
         }
     }
 
     @TestCase
     public static class TC7 extends RepeatingTypeAnnotations {
         public TC7() {
-            setSrc("    static String so = \"hello world\";",
+            setSrc(" /* TC7 */ ",
+                   "    static String so = \"hello world\";",
                    "    public static @A @A @C Object o = (@B @C @B String) Test.so;");
-            verify("RuntimeInvisibleTypeAnnotations",
-                   "RuntimeVisibleTypeAnnotations",
+            verify("RuntimeVisibleTypeAnnotations",
+                   "RuntimeInvisibleTypeAnnotations",
                    "0: #25(): FIELD",
-                   "1: #25(): CAST, offset=5",
                    "0: #27(#28=[@#29(),@#29()]): FIELD",
-                   "1: #30(#28=[@#31(),@#31()]): CAST, offset=5");
+                   "0: #25(): CAST, offset=5, type_index=0",
+                   "0: #38(#28=[@#39(),@#39()]): CAST, offset=5, type_index=0");
         }
     }
 
     @TestCase
     public static class TC8 extends RepeatingTypeAnnotations {
         public TC8() {
-            setSrc("    static String so = \"hello world\";",
+            setSrc(" /* TC8 */ ",
+                   "    static String so = \"hello world\";",
                    "    public static @A @B @C Object o = (@C @B @A String) Test.so;");
-            verify("RuntimeInvisibleTypeAnnotations",
-                   "RuntimeVisibleTypeAnnotations",
+
+            verify("RuntimeVisibleTypeAnnotations",
+                   "RuntimeInvisibleTypeAnnotations",
                    "0: #25(): FIELD",
-                   "1: #25(): CAST, offset=5",
                    "0: #27(): FIELD",
                    "1: #28(): FIELD",
-                   "2: #28(): CAST, offset=5",
-                   "3: #27(): CAST, offset=5");
+                   "0: #25(): CAST, offset=5, type_index=0",
+                   "0: #28(): CAST, offset=5, type_index=0",
+                   "1: #27(): CAST, offset=5, type_index=0");
         }
     }
 
     @TestCase
-    @ignore // 8008082:missing type annotation for cast
     public static class TC9 extends RepeatingTypeAnnotations {
         public TC9() {
-            setSrc("    public Test(@A @A @A Object o, @A int i, long l) {",
+            setSrc(" /* TC9 */ ",
+                   "    public Test(@A @A @A Object o, @A int i, long l) {",
                    "        @A @A @A String ls = (@B @B @B String) o;",
                    "    }");
             verify("RuntimeInvisibleTypeAnnotations",
-                   "0: #34(#35=[@#36(),@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0",
-                   "1: #36(): METHOD_FORMAL_PARAMETER, param_index=1",
-                   "2: #37(#35=[@#38(),@#38(),@#38()]): CAST, offset=4, type_index=0",
-                   "3: #34(#35=[@#36(),@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}");
+                   "0: #34(#35=[@#36(),@#36(),@#36()]): CAST, offset=4, type_index=0",
+                   "1: #37(#35=[@#38(),@#38(),@#38()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
+                   "RuntimeInvisibleTypeAnnotations",
+                   "0: #37(#35=[@#38(),@#38(),@#38()]): METHOD_FORMAL_PARAMETER, param_index=0",
+                   "1: #38(): METHOD_FORMAL_PARAMETER, param_index=1");
         }
     }
 
     @TestCase
     public static class TC10 extends RepeatingTypeAnnotations {
         public TC10() {
-            setSrc("    public Test(@A @A @B Object o, @A @B int i, long l) {",
+            setSrc(" /* TC10 */ ",
+                   "    public Test(@A @A @B Object o, @A @B int i, long l) {",
                    "        @A @A @B String ls = (@B @A @B String) o;",
                    "    }");
-            verify("RuntimeInvisibleTypeAnnotations:",
-                   "0: #34(#35=[@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0",
-                   "1: #37(): METHOD_FORMAL_PARAMETER, param_index=0",
-                   "2: #36(): METHOD_FORMAL_PARAMETER, param_index=1",
-                   "3: #37(): METHOD_FORMAL_PARAMETER, param_index=1",
-                   "4: #38(#35=[@#37(),@#37()]): CAST, offset=4, type_index=0",
-                   "5: #36(): CAST, offset=4, type_index=0",
-                   "6: #34(#35=[@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
-                   "7: #37(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}");
+            verify("RuntimeInvisibleTypeAnnotations",
+                   "0: #34(#35=[@#36(),@#36()]): CAST, offset=4, type_index=0",
+                   "1: #37(): CAST, offset=4, type_index=0",
+                   "2: #38(#35=[@#37(),@#37()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
+                   "3: #36(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
+                   "RuntimeInvisibleTypeAnnotations",
+                   "0: #38(#35=[@#37(),@#37()]): METHOD_FORMAL_PARAMETER, param_index=0",
+                   "1: #36(): METHOD_FORMAL_PARAMETER, param_index=0",
+                   "2: #37(): METHOD_FORMAL_PARAMETER, param_index=1",
+                   "3: #36(): METHOD_FORMAL_PARAMETER, param_index=1");
         }
     }
 
     @TestCase
     public static class TC11 extends RepeatingTypeAnnotations {
         public TC11() {
-            setSrc("    public Test(@C @C @A Object o, @A @B int i, long l) {",
+            setSrc(" /* TC11 */ ",
+                   "    public Test(@C @C @A Object o, @A @B int i, long l) {",
                    "        @C @C @A String ls = (@A @A @C String) o;",
                    "    }");
-            verify("RuntimeInvisibleTypeAnnotations",
-                   "RuntimeVisibleTypeAnnotations",
-                   "0: #34(#35=[@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0",
-                   "1: #36(): CAST, offset=4",
-                   "2: #34(#35=[@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
-                   "0: #38(): METHOD_FORMAL_PARAMETER, param_index=0",
-                   "1: #38(): METHOD_FORMAL_PARAMETER, param_index=1",
-                   "2: #39(): METHOD_FORMAL_PARAMETER, param_index=1",
-                   "3: #40(#35=[@#38(),@#38()]): CAST, offset=4",
-                   "4: #38(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}");
+            verify("RuntimeVisibleTypeAnnotations",
+                   "RuntimeInvisibleTypeAnnotations",
+                   "0: #34(): CAST, offset=4, type_index=0",
+                   "1: #35(#36=[@#34(),@#34()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
+                   "0: #38(#36=[@#39(),@#39()]): CAST, offset=4, type_index=0",
+                   "1: #39(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
+                   "0: #35(#36=[@#34(),@#34()]): METHOD_FORMAL_PARAMETER, param_index=0",
+                   "0: #39(): METHOD_FORMAL_PARAMETER, param_index=0",
+                   "1: #39(): METHOD_FORMAL_PARAMETER, param_index=1",
+                   "2: #40(): METHOD_FORMAL_PARAMETER, param_index=1");
         }
     }
 
     @TestCase
     public static class TC12 extends RepeatingTypeAnnotations {
         public TC12() {
-            setSrc("    public Test(@A @B @C Object o, @A @C int i, long l) {",
+            setSrc(" /* TC12 */ ",
+                   "    public Test(@A @B @C Object o, @A @C int i, long l) {",
                    "        @A @B @C String ls = (@C @A @B String) o;",
                    "    }");
-            verify("RuntimeInvisibleTypeAnnotations",
-                   "RuntimeVisibleTypeAnnotations",
+            verify("RuntimeVisibleTypeAnnotations",
+                   "0: #34(): CAST, offset=4, type_index=0",
+                   "1: #34(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
+                   "RuntimeInvisibleTypeAnnotations",
+                   "0: #36(): CAST, offset=4, type_index=0",
+                   "1: #37(): CAST, offset=4, type_index=0",
+                   "2: #36(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
+                   "3: #37(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
                    "0: #34(): METHOD_FORMAL_PARAMETER, param_index=0",
                    "1: #34(): METHOD_FORMAL_PARAMETER, param_index=1",
-                   "2: #34(): CAST, offset=4",
-                   "3: #34(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
                    "0: #36(): METHOD_FORMAL_PARAMETER, param_index=0",
                    "1: #37(): METHOD_FORMAL_PARAMETER, param_index=0",
-                   "2: #36(): METHOD_FORMAL_PARAMETER, param_index=1",
-                   "3: #36(): CAST, offset=4",
-                   "4: #37(): CAST, offset=4",
-                   "5: #36(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
-                   "6: #37(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}");
+                   "2: #36(): METHOD_FORMAL_PARAMETER, param_index=1");
         }
     }
 
     @TestCase
-    @ignore // 8008082:missing type annotation for cast
     public static class TC13 extends RepeatingTypeAnnotations {
         public TC13() {
-            setSrc("    public @A @A @A String foo(@A @A @A Object o, @A int i, long l) {",
+            setSrc(" /* TC13 */ ",
+                   "    public @A @A @A String foo(@A @A @A Object o, @A int i, long l) {",
                    "        @A @A @A String ls = (@B @B @B String) o;",
                    "        return (@A @A @A String) o;",
                    "    }");
             verify("RuntimeInvisibleTypeAnnotations",
-                   "0: #36(#37=[@#38(),@#38(),@#38()]): METHOD_RETURN",
-                   "1: #36(#37=[@#38(),@#38(),@#38()]): METHOD_FORMAL_PARAMETER, param_index=0",
-                   "2: #38(): METHOD_FORMAL_PARAMETER, param_index=1",
-                   "3: #39(#37=[@#40(),@#40(),@#40()]): CAST, offset=0, type_index=0",
-                   "4: #36(#37=[@#38(),@#38(),@#38()]): CAST, offset=6, type_index=0",
-                   "5: #36(#37=[@#38(),@#38(),@#38()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}");
+                   "0: #36(#37=[@#38(),@#38(),@#38()]): CAST, offset=0, type_index=0",
+                   "1: #39(#37=[@#40(),@#40(),@#40()]): CAST, offset=6, type_index=0",
+                   "2: #39(#37=[@#40(),@#40(),@#40()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
+                    "RuntimeInvisibleTypeAnnotations",
+                   "0: #39(#37=[@#40(),@#40(),@#40()]): METHOD_RETURN",
+                   "1: #39(#37=[@#40(),@#40(),@#40()]): METHOD_FORMAL_PARAMETER, param_index=0",
+                   "2: #40(): METHOD_FORMAL_PARAMETER, param_index=1");
         }
     }
 
     @TestCase
     public static class TC14 extends RepeatingTypeAnnotations {
         public TC14() {
-            setSrc("    public @A @B @B String foo(@A @A @B Object o, @A @B int i, long l) {",
+            setSrc(" /* TC14 */ ",
+                   "    public @A @B @B String foo(@A @A @B Object o, @A @B int i, long l) {",
                    "        @A @A @B String ls = (@B @A @B String) o;",
                    "        return (@A @B @B String) o;",
                    "    }");
-            verify("RuntimeInvisibleTypeAnnotations",
-                    "0: #36(): METHOD_RETURN",
-                    "1: #37(#38=[@#39(),@#39()]): METHOD_RETURN",
-                    "2: #40(#38=[@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0",
-                    "3: #39(): METHOD_FORMAL_PARAMETER, param_index=0",
-                    "4: #36(): METHOD_FORMAL_PARAMETER, param_index=1",
-                    "5: #39(): METHOD_FORMAL_PARAMETER, param_index=1",
-                    "6: #37(#38=[@#39(),@#39()]): CAST, offset=0",
-                    "7: #36(): CAST, offset=0",
-                    "8: #36(): CAST, offset=6",
-                    "9: #37(#38=[@#39(),@#39()]): CAST, offset=6",
-                    "10: #40(#38=[@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
-                    "11: #39(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}");
+           verify(
+                    "RuntimeInvisibleTypeAnnotations:",
+                    "0: #36(#37=[@#38(),@#38()]): CAST, offset=0, type_index=0",
+                    "1: #39(): CAST, offset=0, type_index=0",
+                  "2: #39(): CAST, offset=6, type_index=0",
+                  "3: #36(#37=[@#38(),@#38()]): CAST, offset=6, type_index=0",
+                  "4: #40(#37=[@#39(),@#39()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
+                  "5: #38(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
+                    "RuntimeInvisibleTypeAnnotations:",
+                  "0: #39(): METHOD_RETURN",
+                  "1: #36(#37=[@#38(),@#38()]): METHOD_RETURN",
+                  "2: #40(#37=[@#39(),@#39()]): METHOD_FORMAL_PARAMETER, param_index=0",
+                  "3: #38(): METHOD_FORMAL_PARAMETER, param_index=0",
+                  "4: #39(): METHOD_FORMAL_PARAMETER, param_index=1",
+                    "5: #38(): METHOD_FORMAL_PARAMETER, param_index=1"
+                 );
         }
     }
 
     @TestCase
     public static class TC15 extends RepeatingTypeAnnotations {
         public TC15() {
-            setSrc("    public @A @A @C String foo(@C @C @A Object o, @A @B int i, long l) {",
+            setSrc(" /* TC15 */ ",
+                   "    public @A @A @C String foo(@C @C @A Object o, @A @B int i, long l) {",
                    "        @C @C @A String ls = (@A @A @C String) o;",
                    "        return (@C @B @B String) o;",
                    "    }");
-            verify("RuntimeInvisibleTypeAnnotations",
-                    "RuntimeVisibleTypeAnnotations",
-                    "0: #36(): METHOD_RETURN",
-                    "1: #37(#38=[@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0",
-                    "2: #36(): CAST, offset=0",
-                    "3: #36(): CAST, offset=6",
-                    "4: #37(#38=[@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
-                    "0: #40(#38=[@#41(),@#41()]): METHOD_RETURN",
-                    "1: #41(): METHOD_FORMAL_PARAMETER, param_index=0",
-                    "2: #41(): METHOD_FORMAL_PARAMETER, param_index=1",
-                    "3: #42(): METHOD_FORMAL_PARAMETER, param_index=1",
-                    "4: #40(#38=[@#41(),@#41()]): CAST, offset=0",
-                    "5: #43(#38=[@#42(),@#42()]): CAST, offset=6",
-                    "6: #41(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}");
+            verify(
+                    "RuntimeVisibleTypeAnnotations:",
+                    "0: #36(): CAST, offset=0, type_index=0",
+                   "1: #36(): CAST, offset=6, type_index=0",
+                   "2: #37(#38=[@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
+                    "RuntimeInvisibleTypeAnnotations:",
+                    "0: #40(#38=[@#41(),@#41()]): CAST, offset=0, type_index=0",
+                   "1: #42(#38=[@#43(),@#43()]): CAST, offset=6, type_index=0",
+                   "2: #41(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
+                    "RuntimeVisibleTypeAnnotations:",
+                   "0: #36(): METHOD_RETURN",
+                   "1: #37(#38=[@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0",
+                    "RuntimeInvisibleTypeAnnotations:",
+                   "0: #40(#38=[@#41(),@#41()]): METHOD_RETURN",
+                   "1: #41(): METHOD_FORMAL_PARAMETER, param_index=0",
+                   "2: #41(): METHOD_FORMAL_PARAMETER, param_index=1",
+                    "3: #43(): METHOD_FORMAL_PARAMETER, param_index=1"
+                    );
         }
     }
 
     @TestCase
     public static class TC16 extends RepeatingTypeAnnotations {
         public TC16() {
-            setSrc("    public @A @B @C String foo(@A @B @C Object o, @A @C int i, long l) {",
+            setSrc(" /* TC16 */ ",
+                   "    public @A @B @C String foo(@A @B @C Object o, @A @C int i, long l) {",
                    "        @A @B @C String ls = (@C @A @B String) o;",
                    "        return (@B @A @C String) o;",
                    "    }");
-            verify("RuntimeInvisibleTypeAnnotations",
-                   "RuntimeVisibleTypeAnnotations",
+            verify(
+                    "RuntimeVisibleTypeAnnotations:",
+                    "0: #36(): CAST, offset=0, type_index=0",
+                   "1: #36(): CAST, offset=6, type_index=0",
+                   "2: #36(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
+                    "RuntimeInvisibleTypeAnnotations:",
+                    "0: #38(): CAST, offset=0, type_index=0",
+                    "1: #39(): CAST, offset=0, type_index=0",
+                   "2: #39(): CAST, offset=6, type_index=0",
+                   "3: #38(): CAST, offset=6, type_index=0",
+                   "4: #38(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
+                   "5: #39(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
+                    "RuntimeVisibleTypeAnnotations:",
                    "0: #36(): METHOD_RETURN",
                    "1: #36(): METHOD_FORMAL_PARAMETER, param_index=0",
                    "2: #36(): METHOD_FORMAL_PARAMETER, param_index=1",
-                   "3: #36(): CAST, offset=0",
-                   "4: #36(): CAST, offset=6",
-                   "5: #36(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
+                    "RuntimeInvisibleTypeAnnotations:",
                    "0: #38(): METHOD_RETURN",
                    "1: #39(): METHOD_RETURN",
                    "2: #38(): METHOD_FORMAL_PARAMETER, param_index=0",
                    "3: #39(): METHOD_FORMAL_PARAMETER, param_index=0",
-                   "4: #38(): METHOD_FORMAL_PARAMETER, param_index=1",
-                   "5: #38(): CAST, offset=0",
-                   "6: #39(): CAST, offset=0",
-                   "7: #39(): CAST, offset=6",
-                   "8: #38(): CAST, offset=6",
-                   "9: #38(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
-                   "10: #39(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}");
+                    "4: #38(): METHOD_FORMAL_PARAMETER, param_index=1"
+                  );
         }
     }
 }
diff --git a/langtools/test/tools/javap/output/Tester.java b/langtools/test/tools/javap/output/Tester.java
index e0d4cb5..d6103c5 100644
--- a/langtools/test/tools/javap/output/Tester.java
+++ b/langtools/test/tools/javap/output/Tester.java
@@ -128,8 +128,8 @@
 
     /**
      * Individual test-cases failing due to product bugs, may temporarily
-     * be excluded by marking them like  this:
-     * @ignore // 1234567:bug synopsis
+     * be excluded by marking them like this, (where "at-" is replaced by "@")
+     * at-ignore // 1234567: bug synopsis
      */
     @Retention(RetentionPolicy.RUNTIME)
     @interface ignore { }
diff --git a/langtools/test/tools/javap/typeAnnotations/NewArray.java b/langtools/test/tools/javap/typeAnnotations/NewArray.java
index bcb25ef..b562ac5 100644
--- a/langtools/test/tools/javap/typeAnnotations/NewArray.java
+++ b/langtools/test/tools/javap/typeAnnotations/NewArray.java
@@ -27,10 +27,11 @@
 /*
  * @test NewArray
  * @bug 6843077
- * @summary test that all type annotations are present in the classfile
+ * @summary Test type annotations on local array are in method's code attribute.
  */
 
 public class NewArray {
+
     public static void main(String[] args) throws Exception {
         new NewArray().run();
     }
@@ -40,10 +41,6 @@
         File classFile = compileTestFile(javaFile);
 
         ClassFile cf = ClassFile.read(classFile);
-        test(cf);
-        for (Field f : cf.fields) {
-            test(cf, f);
-        }
         for (Method m: cf.methods) {
             test(cf, m);
         }
@@ -55,66 +52,34 @@
         System.out.println("PASSED");
     }
 
-    void test(ClassFile cf) {
-        test(cf, Attribute.RuntimeVisibleTypeAnnotations, true);
-        test(cf, Attribute.RuntimeInvisibleTypeAnnotations, false);
-    }
-
     void test(ClassFile cf, Method m) {
         test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
         test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
     }
 
-    void test(ClassFile cf, Field m) {
-        test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
-        test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
-    }
-
-    // test the result of Attributes.getIndex according to expectations
-    // encoded in the method's name
-    void test(ClassFile cf, String name, boolean visible) {
-        int index = cf.attributes.getIndex(cf.constant_pool, name);
-        if (index != -1) {
-            Attribute attr = cf.attributes.get(index);
-            assert attr instanceof RuntimeTypeAnnotations_attribute;
-            RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
-            all += tAttr.annotations.length;
-            if (visible)
-                visibles += tAttr.annotations.length;
-            else
-                invisibles += tAttr.annotations.length;
-        }
-    }
-
     // test the result of Attributes.getIndex according to expectations
     // encoded in the method's name
     void test(ClassFile cf, Method m, String name, boolean visible) {
-        int index = m.attributes.getIndex(cf.constant_pool, name);
-        if (index != -1) {
-            Attribute attr = m.attributes.get(index);
-            assert attr instanceof RuntimeTypeAnnotations_attribute;
-            RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
-            all += tAttr.annotations.length;
-            if (visible)
-                visibles += tAttr.annotations.length;
-            else
-                invisibles += tAttr.annotations.length;
-        }
-    }
+        Attribute attr = null;
+        Code_attribute cAttr = null;
+        RuntimeTypeAnnotations_attribute tAttr = null;
 
-    // test the result of Attributes.getIndex according to expectations
-    // encoded in the method's name
-    void test(ClassFile cf, Field m, String name, boolean visible) {
-        int index = m.attributes.getIndex(cf.constant_pool, name);
-        if (index != -1) {
-            Attribute attr = m.attributes.get(index);
-            assert attr instanceof RuntimeTypeAnnotations_attribute;
-            RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
-            all += tAttr.annotations.length;
-            if (visible)
-                visibles += tAttr.annotations.length;
-            else
-                invisibles += tAttr.annotations.length;
+        int index = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
+        if(index!= -1) {
+            attr = m.attributes.get(index);
+            assert attr instanceof Code_attribute;
+            cAttr = (Code_attribute)attr;
+            index = cAttr.attributes.getIndex(cf.constant_pool, name);
+            if(index!= -1) {
+                attr = cAttr.attributes.get(index);
+                assert attr instanceof RuntimeTypeAnnotations_attribute;
+                tAttr = (RuntimeTypeAnnotations_attribute)attr;
+                all += tAttr.annotations.length;
+                if (visible)
+                    visibles += tAttr.annotations.length;
+                else
+                    invisibles += tAttr.annotations.length;
+               }
         }
     }
 
@@ -124,14 +89,12 @@
         out.println("import java.lang.annotation.*;");
         out.println("import java.util.*;");
         out.println("class Test { ");
-        out.println("  @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})");
-        out.println("  @interface A { }");
-
-        out.println(" void test() {");
-        out.println("  Object a = new @A String @A [5] @A  [];");
-        out.println("  Object b = new @A String @A [5] @A [3];");
-        out.println("  Object c = new @A String @A [] @A [] {};");
-        out.println(" }");
+        out.println("  @Target(ElementType.TYPE_USE) @interface A { }");
+        out.println("  void test() {");
+        out.println("    Object a = new @A String @A [5] @A  [];");
+        out.println("    Object b = new @A String @A [5] @A [3];");
+        out.println("    Object c = new @A String @A [] @A [] {};");
+        out.println("  }");
         out.println("}");
 
         out.close();
diff --git a/langtools/test/tools/javap/typeAnnotations/Presence.java b/langtools/test/tools/javap/typeAnnotations/Presence.java
index 6ed8608..8dad8fc 100644
--- a/langtools/test/tools/javap/typeAnnotations/Presence.java
+++ b/langtools/test/tools/javap/typeAnnotations/Presence.java
@@ -91,17 +91,40 @@
     // test the result of Attributes.getIndex according to expectations
     // encoded in the method's name
     void test(ClassFile cf, Method m, String name, boolean visible) {
+        Attribute attr = null;
+        Code_attribute cAttr = null;
+        RuntimeTypeAnnotations_attribute tAttr = null;
+
+        // collect annotations attributes on method
         int index = m.attributes.getIndex(cf.constant_pool, name);
         if (index != -1) {
-            Attribute attr = m.attributes.get(index);
+            attr = m.attributes.get(index);
             assert attr instanceof RuntimeTypeAnnotations_attribute;
-            RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
+            tAttr = (RuntimeTypeAnnotations_attribute)attr;
             all += tAttr.annotations.length;
             if (visible)
                 visibles += tAttr.annotations.length;
             else
                 invisibles += tAttr.annotations.length;
         }
+        // collect annotations from method's code attribute
+        index = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
+        if(index!= -1) {
+            attr = m.attributes.get(index);
+            assert attr instanceof Code_attribute;
+            cAttr = (Code_attribute)attr;
+            index = cAttr.attributes.getIndex(cf.constant_pool, name);
+            if(index!= -1) {
+                attr = cAttr.attributes.get(index);
+                assert attr instanceof RuntimeTypeAnnotations_attribute;
+                tAttr = (RuntimeTypeAnnotations_attribute)attr;
+                all += tAttr.annotations.length;
+                if (visible)
+                    visibles += tAttr.annotations.length;
+                else
+                    invisibles += tAttr.annotations.length;
+               }
+        }
     }
 
     // test the result of Attributes.getIndex according to expectations
@@ -121,12 +144,12 @@
     }
 
     File writeTestFile() throws IOException {
-        File f = new File("Test.java");
+        File f = new File("TestPresence.java");
         PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
         out.println("import java.util.*;");
         out.println("import java.lang.annotation.*;");
 
-        out.println("class Test<@Test.A T extends @Test.A List<@Test.A String>> { ");
+        out.println("class TestPresence<@TestPresence.A T extends @TestPresence.A List<@TestPresence.A String>> { ");
         out.println("  @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})");
         out.println("  @interface A { }");
 
@@ -134,7 +157,7 @@
 
         out.println("  <@A TM extends @A List<@A String>>");
         out.println("  Map<@A String, @A List<@A String>>");
-        out.println("  method(@A Test<T> this, List<@A String> @A [] param1, String @A [] @A ... param2)");
+        out.println("  method(@A TestPresence<T> this, List<@A String> @A [] param1, String @A [] @A ... param2)");
         out.println("  throws @A Exception {");
         out.println("    @A String lc1 = null;");
         out.println("    @A List<@A String> lc2 = null;");
diff --git a/langtools/test/tools/javap/typeAnnotations/TypeCasts.java b/langtools/test/tools/javap/typeAnnotations/TypeCasts.java
index 589b91f..c9c3f92 100644
--- a/langtools/test/tools/javap/typeAnnotations/TypeCasts.java
+++ b/langtools/test/tools/javap/typeAnnotations/TypeCasts.java
@@ -41,10 +41,6 @@
         File classFile = compileTestFile(javaFile);
 
         ClassFile cf = ClassFile.read(classFile);
-        test(cf);
-        for (Field f : cf.fields) {
-            test(cf, f);
-        }
         for (Method m: cf.methods) {
             test(cf, m);
         }
@@ -56,68 +52,37 @@
         System.out.println("PASSED");
     }
 
-    void test(ClassFile cf) {
-        test(cf, Attribute.RuntimeVisibleTypeAnnotations, true);
-        test(cf, Attribute.RuntimeInvisibleTypeAnnotations, false);
-    }
-
     void test(ClassFile cf, Method m) {
         test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
         test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
     }
 
-    void test(ClassFile cf, Field m) {
-        test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
-        test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
-    }
-
-    // test the result of Attributes.getIndex according to expectations
-    // encoded in the method's name
-    void test(ClassFile cf, String name, boolean visible) {
-        int index = cf.attributes.getIndex(cf.constant_pool, name);
-        if (index != -1) {
-            Attribute attr = cf.attributes.get(index);
-            assert attr instanceof RuntimeTypeAnnotations_attribute;
-            RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
-            all += tAttr.annotations.length;
-            if (visible)
-                visibles += tAttr.annotations.length;
-            else
-                invisibles += tAttr.annotations.length;
-        }
-    }
 
     // test the result of Attributes.getIndex according to expectations
     // encoded in the method's name
     void test(ClassFile cf, Method m, String name, boolean visible) {
-        int index = m.attributes.getIndex(cf.constant_pool, name);
-        if (index != -1) {
-            Attribute attr = m.attributes.get(index);
-            assert attr instanceof RuntimeTypeAnnotations_attribute;
-            RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
-            all += tAttr.annotations.length;
-            if (visible)
-                visibles += tAttr.annotations.length;
-            else
-                invisibles += tAttr.annotations.length;
+        Attribute attr = null;
+        Code_attribute cAttr = null;
+
+        int index = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
+        if(index!= -1) {
+            attr = m.attributes.get(index);
+            assert attr instanceof Code_attribute;
+            cAttr = (Code_attribute)attr;
+            index = cAttr.attributes.getIndex(cf.constant_pool, name);
+            if(index!= -1) {
+                attr = cAttr.attributes.get(index);
+                assert attr instanceof RuntimeTypeAnnotations_attribute;
+                RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
+                all += tAttr.annotations.length;
+                if (visible)
+                    visibles += tAttr.annotations.length;
+                else
+                    invisibles += tAttr.annotations.length;
+               }
         }
     }
 
-    // test the result of Attributes.getIndex according to expectations
-    // encoded in the method's name
-    void test(ClassFile cf, Field m, String name, boolean visible) {
-        int index = m.attributes.getIndex(cf.constant_pool, name);
-        if (index != -1) {
-            Attribute attr = m.attributes.get(index);
-            assert attr instanceof RuntimeTypeAnnotations_attribute;
-            RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
-            all += tAttr.annotations.length;
-            if (visible)
-                visibles += tAttr.annotations.length;
-            else
-                invisibles += tAttr.annotations.length;
-        }
-    }
 
 
     File writeTestFile() throws IOException {
@@ -125,8 +90,7 @@
         PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
         out.println("import java.lang.annotation.*;");
         out.println("class Test { ");
-        out.println("  @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})");
-        out.println("  @interface A { }");
+        out.println("  @Target(ElementType.TYPE_USE) @interface A { }");
 
         out.println("  void emit() {");
         out.println("    Object o = null;");
diff --git a/nashorn/.hgignore b/nashorn/.hgignore
index d07a19d..56e01ba 100644
--- a/nashorn/.hgignore
+++ b/nashorn/.hgignore
@@ -8,6 +8,7 @@
 private.properties
 webrev/*
 webrev.zip
+.classpath
 *.class
 *.clazz
 *.log
diff --git a/nashorn/.hgtags b/nashorn/.hgtags
index 7b258b8..5cfb534 100644
--- a/nashorn/.hgtags
+++ b/nashorn/.hgtags
@@ -199,3 +199,4 @@
 774aeaa89bc15f4365e3c2fc36f6a3a0da70ba28 jdk8-b87
 40c107d1ae6f81a62e35dfe618b827897405e9b2 jdk8-b88
 45ce27fbe2720d80070095c0db7344ec41e2833d jdk8-b89
+67ca019e3713dd71c884d753de02fd0021981969 jdk8-b90
diff --git a/nashorn/bin/jjs b/nashorn/bin/jjs
index fe6665c..f89a07c 100644
--- a/nashorn/bin/jjs
+++ b/nashorn/bin/jjs
@@ -26,4 +26,4 @@
 
 [ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1;
 
-$JAVA_HOME/bin/java -server -XX:-TieredCompilation -Xms2G -Xmx2G -esa -ea -Djava.ext.dirs=`dirname $0`/../dist:$JAVA_HOME/jre/lib/ext -XX:+HeapDumpOnOutOfMemoryError -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -Dnashorn.debug=true jdk.nashorn.tools.Shell $*
+$JAVA_HOME/bin/java -server -XX:+TieredCompilation -Xms2G -Xmx2G -esa -ea -Djava.ext.dirs=`dirname $0`/../dist:$JAVA_HOME/jre/lib/ext -XX:+HeapDumpOnOutOfMemoryError -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -Dnashorn.debug=true jdk.nashorn.tools.Shell $*
diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties
index e2f39bb..2d66dfe 100644
--- a/nashorn/make/project.properties
+++ b/nashorn/make/project.properties
@@ -194,6 +194,8 @@
 test262-test-sys-prop.test.js.exclude.dir=\
     ${test262.suite.dir}/intl402/
 
+test262-test-sys-prop.test.failed.list.file=${build.dir}/test/failedTests
+
 # test262 test frameworks
 test262-test-sys-prop.test.js.framework=\
     -timezone=PST \
@@ -214,7 +216,7 @@
 
 #  -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMethods
 # add '-Dtest.js.outofprocess' to run each test in a new sub-process
-run.test.jvmargs.main=-server -Xmx${run.test.xmx} -XX:-TieredCompilation -ea -Dnashorn.debug=true -Dfile.encoding=UTF-8
+run.test.jvmargs.main=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -ea -Dnashorn.debug=true -Dfile.encoding=UTF-8
 #-XX:+HeapDumpOnOutOfMemoryError -XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M  
 run.test.jvmargs.octane.main=-Xms${run.test.xms} ${run.test.jvmargs.main}
 
diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java
index 197a6da..283e36e 100644
--- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java
@@ -78,7 +78,6 @@
         this(factory, DEFAULT_OPTIONS, appLoader);
     }
 
-    @SuppressWarnings("LeakingThisInConstructor")
     NashornScriptEngine(final NashornScriptEngineFactory factory, final String[] args, final ClassLoader appLoader) {
         this.factory = factory;
         final Options options = new Options("nashorn");
@@ -102,7 +101,7 @@
         });
 
         // create new global object
-        this.global =  createNashornGlobal();
+        this.global = createNashornGlobal();
         // set the default engine scope for the default context
         context.setBindings(new ScriptObjectMirror(global, global), ScriptContext.ENGINE_SCOPE);
 
diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java
index 1ca6dcd..c100541 100644
--- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java
@@ -31,7 +31,6 @@
 import javax.script.ScriptEngine;
 import javax.script.ScriptEngineFactory;
 import jdk.nashorn.internal.runtime.Version;
-import sun.reflect.Reflection;
 
 /**
  * JSR-223 compliant script engine factory for Nashorn. The engine answers for:
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
index 9b17c47..4e47892 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
@@ -29,11 +29,13 @@
 import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE;
 import static jdk.nashorn.internal.codegen.CompilerConstants.EXCEPTION_PREFIX;
 import static jdk.nashorn.internal.codegen.CompilerConstants.ITERATOR_PREFIX;
+import static jdk.nashorn.internal.codegen.CompilerConstants.LITERAL_PREFIX;
 import static jdk.nashorn.internal.codegen.CompilerConstants.RETURN;
 import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
 import static jdk.nashorn.internal.codegen.CompilerConstants.SWITCH_TAG_PREFIX;
 import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
 import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS;
+import static jdk.nashorn.internal.ir.Symbol.IS_CONSTANT;
 import static jdk.nashorn.internal.ir.Symbol.IS_FUNCTION_SELF;
 import static jdk.nashorn.internal.ir.Symbol.IS_GLOBAL;
 import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL;
@@ -73,8 +75,10 @@
 import jdk.nashorn.internal.ir.ReturnNode;
 import jdk.nashorn.internal.ir.RuntimeNode;
 import jdk.nashorn.internal.ir.RuntimeNode.Request;
+import jdk.nashorn.internal.ir.Statement;
 import jdk.nashorn.internal.ir.SwitchNode;
 import jdk.nashorn.internal.ir.Symbol;
+import jdk.nashorn.internal.ir.TemporarySymbols;
 import jdk.nashorn.internal.ir.TernaryNode;
 import jdk.nashorn.internal.ir.TryNode;
 import jdk.nashorn.internal.ir.UnaryNode;
@@ -90,7 +94,6 @@
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.Property;
 import jdk.nashorn.internal.runtime.PropertyMap;
-import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
 
 /**
@@ -129,13 +132,16 @@
     private static final DebugLogger LOG   = new DebugLogger("attr");
     private static final boolean     DEBUG = LOG.isEnabled();
 
+    private final TemporarySymbols temporarySymbols;
+
     /**
      * Constructor.
      */
-    Attr() {
-        localDefs = new ArrayDeque<>();
-        localUses = new ArrayDeque<>();
-        returnTypes = new ArrayDeque<>();
+    Attr(final TemporarySymbols temporarySymbols) {
+        this.temporarySymbols = temporarySymbols;
+        this.localDefs   = new ArrayDeque<>();
+        this.localUses   = new ArrayDeque<>();
+        this.returnTypes = new ArrayDeque<>();
     }
 
     @Override
@@ -150,67 +156,50 @@
 
     @Override
     public Node leaveAccessNode(final AccessNode accessNode) {
-        ensureSymbol(Type.OBJECT, accessNode);  //While Object type is assigned here, Access Specialization in FinalizeTypes may narrow this
-        end(accessNode);
-        return accessNode;
+        //While Object type is assigned here, Access Specialization in FinalizeTypes may narrow this, that
+        //is why we can't set the access node base to be an object here, that will ruin access specialization
+        //for example for a.x | 17.
+        return end(ensureSymbol(Type.OBJECT, accessNode));
     }
 
-    private void enterFunctionBody() {
+    private void initFunctionWideVariables(final FunctionNode functionNode, final Block body) {
+        initCompileConstant(CALLEE, body, IS_PARAM | IS_INTERNAL, FunctionNode.FUNCTION_TYPE);
+        initCompileConstant(THIS, body, IS_PARAM | IS_THIS, Type.OBJECT);
 
-        final FunctionNode functionNode = getLexicalContext().getCurrentFunction();
-        final Block body = getLexicalContext().getCurrentBlock();
-        initCallee(body);
-        initThis(body);
         if (functionNode.isVarArg()) {
-            initVarArg(body, functionNode.needsArguments());
+            initCompileConstant(VARARGS, body, IS_PARAM | IS_INTERNAL, Type.OBJECT_ARRAY);
+            if (functionNode.needsArguments()) {
+                initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL, Type.typeFor(ScriptObject.class));
+                addLocalDef(ARGUMENTS.symbolName());
+            }
         }
 
         initParameters(functionNode, body);
-        initScope(body);
-        initReturn(body);
+        initCompileConstant(SCOPE, body, IS_VAR | IS_INTERNAL, Type.typeFor(ScriptObject.class));
+        initCompileConstant(RETURN, body, IS_VAR | IS_INTERNAL, Type.OBJECT);
+    }
 
-        if (functionNode.isProgram()) {
-            initFromPropertyMap(body);
-        } else if(!functionNode.isDeclared()) {
-            // It's neither declared nor program - it's a function expression then; assign it a self-symbol.
 
-            if (functionNode.getSymbol() != null) {
-                // a temporary left over from an earlier pass when the function was lazy
-                assert functionNode.getSymbol().isTemp();
-                // remove it
-                functionNode.setSymbol(null);
-            }
-            final boolean anonymous = functionNode.isAnonymous();
-            final String name = anonymous ? null : functionNode.getIdent().getName();
-            if (anonymous || body.getExistingSymbol(name) != null) {
-                // The function is either anonymous, or another local identifier already trumps its name on entry:
-                // either it has the same name as one of its parameters, or is named "arguments" and also references the
-                // "arguments" identifier in its body.
-                ensureSymbol(functionNode, Type.typeFor(ScriptFunction.class), functionNode);
-            } else {
-                final Symbol selfSymbol = defineSymbol(body, name, IS_VAR | IS_FUNCTION_SELF, functionNode);
-                assert selfSymbol.isFunctionSelf();
-                newType(selfSymbol, Type.OBJECT);
-            }
-        }
-
-        /*
-         * This pushes all declarations (except for non-statements, i.e. for
-         * node temporaries) to the top of the function scope. This way we can
-         * get around problems like
-         *
-         * while (true) {
-         *   break;
-         *   if (true) {
-         *     var s;
-         *   }
-         * }
-         *
-         * to an arbitrary nesting depth.
-         *
-         * @see NASHORN-73
-         */
-
+    /**
+     * This pushes all declarations (except for non-statements, i.e. for
+     * node temporaries) to the top of the function scope. This way we can
+     * get around problems like
+     *
+     * while (true) {
+     *   break;
+     *   if (true) {
+     *     var s;
+     *   }
+     * }
+     *
+     * to an arbitrary nesting depth.
+     *
+     * see NASHORN-73
+     *
+     * @param functionNode the FunctionNode we are entering
+     * @param body the body of the FunctionNode we are entering
+     */
+    private void acceptDeclarations(final FunctionNode functionNode, final Block body) {
         // This visitor will assign symbol to all declared variables, except function declarations (which are taken care
         // in a separate step above) and "var" declarations in for loop initializers.
         body.accept(new NodeOperatorVisitor() {
@@ -220,27 +209,52 @@
             }
 
             @Override
-            public boolean enterVarNode(final VarNode varNode) {
-
+            public Node leaveVarNode(final VarNode varNode) {
                 // any declared symbols that aren't visited need to be typed as well, hence the list
-
                 if (varNode.isStatement()) {
-
-                    final IdentNode ident = varNode.getName();
-                    final Symbol symbol = defineSymbol(body, ident.getName(), IS_VAR, new IdentNode(ident));
+                    final IdentNode ident  = varNode.getName();
+                    final Symbol    symbol = defineSymbol(body, ident.getName(), IS_VAR);
                     functionNode.addDeclaredSymbol(symbol);
                     if (varNode.isFunctionDeclaration()) {
                         newType(symbol, FunctionNode.FUNCTION_TYPE);
                     }
+                    return varNode.setName((IdentNode)ident.setSymbol(getLexicalContext(), symbol));
                 }
-                return false;
+                return varNode;
             }
         });
     }
 
+    private void enterFunctionBody() {
+
+        final FunctionNode functionNode = getLexicalContext().getCurrentFunction();
+        final Block body = getLexicalContext().getCurrentBlock();
+
+        initFunctionWideVariables(functionNode, body);
+
+        if (functionNode.isProgram()) {
+            initFromPropertyMap(body);
+        } else if (!functionNode.isDeclared()) {
+            // It's neither declared nor program - it's a function expression then; assign it a self-symbol.
+            assert functionNode.getSymbol() == null;
+
+            final boolean anonymous = functionNode.isAnonymous();
+            final String  name      = anonymous ? null : functionNode.getIdent().getName();
+            if (!(anonymous || body.getExistingSymbol(name) != null)) {
+                assert !anonymous && name != null;
+                newType(defineSymbol(body, name, IS_VAR | IS_FUNCTION_SELF), Type.OBJECT);
+            }
+        }
+
+        acceptDeclarations(functionNode, body);
+    }
+
     @Override
     public boolean enterBlock(final Block block) {
         start(block);
+        //ensure that we don't use information from a previous compile. This is very ugly TODO
+        //the symbols in the block should really be stateless
+        block.clearSymbols();
 
         if (getLexicalContext().isFunctionBody()) {
             enterFunctionBody();
@@ -257,14 +271,13 @@
     }
 
     @Override
-    public Node leaveCallNode(final CallNode callNode) {
-        ensureSymbol(callNode.getType(), callNode);
-        return end(callNode);
+    public boolean enterCallNode(final CallNode callNode) {
+        return start(callNode);
     }
 
     @Override
-    public boolean enterCallNode(final CallNode callNode) {
-        return start(callNode);
+    public Node leaveCallNode(final CallNode callNode) {
+        return end(ensureSymbol(callNode.getType(), callNode));
     }
 
     @Override
@@ -275,23 +288,31 @@
         start(catchNode);
 
         // define block-local exception variable
-        final Symbol def = defineSymbol(block, exception.getName(), IS_VAR | IS_LET, exception);
+        final Symbol def = defineSymbol(block, exception.getName(), IS_VAR | IS_LET);
         newType(def, Type.OBJECT);
         addLocalDef(exception.getName());
 
         return true;
     }
 
+    @Override
+    public Node leaveCatchNode(final CatchNode catchNode) {
+        final IdentNode exception = catchNode.getException();
+        final Block  block        = getLexicalContext().getCurrentBlock();
+        final Symbol symbol       = findSymbol(block, exception.getName());
+        assert symbol != null;
+        return end(catchNode.setException((IdentNode)exception.setSymbol(getLexicalContext(), symbol)));
+    }
+
     /**
      * Declare the definition of a new symbol.
      *
      * @param name         Name of symbol.
      * @param symbolFlags  Symbol flags.
-     * @param node         Defining Node.
      *
      * @return Symbol for given name or null for redefinition.
      */
-    private Symbol defineSymbol(final Block block, final String name, final int symbolFlags, final Node node) {
+    private Symbol defineSymbol(final Block block, final String name, final int symbolFlags) {
         int    flags  = symbolFlags;
         Symbol symbol = findSymbol(block, name); // Locate symbol.
 
@@ -337,7 +358,7 @@
 
             // Create and add to appropriate block.
             symbol = new Symbol(name, flags);
-            symbolBlock.putSymbol(name, symbol);
+            symbolBlock.putSymbol(getLexicalContext(), symbol);
 
             if ((flags & Symbol.KINDMASK) != IS_GLOBAL) {
                 symbol.setNeedsSlot(true);
@@ -346,10 +367,6 @@
             symbol.setFlags(flags);
         }
 
-        if (node != null) {
-            node.setSymbol(symbol);
-        }
-
         return symbol;
     }
 
@@ -357,30 +374,22 @@
     public boolean enterFunctionNode(final FunctionNode functionNode) {
         start(functionNode, false);
 
+        if (functionNode.isLazy()) {
+            return false;
+        }
+
+        //an outermost function in our lexical context that is not a program (runScript)
+        //is possible - it is a function being compiled lazily
         if (functionNode.isDeclared()) {
             final Iterator<Block> blocks = getLexicalContext().getBlocks();
             if (blocks.hasNext()) {
-                defineSymbol(
-                    blocks.next(),
-                    functionNode.getIdent().getName(),
-                    IS_VAR,
-                    functionNode);
-            } else {
-                // Q: What's an outermost function in a lexical context that is not a program?
-                // A: It's a function being compiled lazily!
-                assert getLexicalContext().getOutermostFunction() == functionNode && !functionNode.isProgram();
+                defineSymbol(blocks.next(), functionNode.getIdent().getName(), IS_VAR);
             }
         }
 
-        if (functionNode.isLazy()) {
-            LOG.info("LAZY: ", functionNode.getName(), " => Promoting to OBJECT");
-            ensureSymbol(getLexicalContext().getCurrentFunction(), Type.OBJECT, functionNode);
-            end(functionNode);
-            return false;
-        }
-
         returnTypes.push(functionNode.getReturnType());
         pushLocalsFunction();
+
         return true;
     }
 
@@ -390,9 +399,30 @@
 
         final LexicalContext lc = getLexicalContext();
 
+        final Block body = newFunctionNode.getBody();
+
+        //look for this function in the parent block
+        if (functionNode.isDeclared()) {
+            final Iterator<Block> blocks = getLexicalContext().getBlocks();
+            if (blocks.hasNext()) {
+                newFunctionNode = (FunctionNode)newFunctionNode.setSymbol(lc, findSymbol(blocks.next(), functionNode.getIdent().getName()));
+            }
+        } else if (!functionNode.isProgram()) {
+            final boolean anonymous = functionNode.isAnonymous();
+            final String  name      = anonymous ? null : functionNode.getIdent().getName();
+            if (anonymous || body.getExistingSymbol(name) != null) {
+                newFunctionNode = (FunctionNode)ensureSymbol(lc, FunctionNode.FUNCTION_TYPE, newFunctionNode);
+            } else {
+                assert name != null;
+                final Symbol self = body.getExistingSymbol(name);
+                assert self != null && self.isFunctionSelf();
+                newFunctionNode = (FunctionNode)newFunctionNode.setSymbol(lc, body.getExistingSymbol(name));
+            }
+        }
+
         //unknown parameters are promoted to object type.
-        finalizeParameters(newFunctionNode);
-        finalizeTypes(newFunctionNode);
+        newFunctionNode = finalizeParameters(newFunctionNode);
+        newFunctionNode = finalizeTypes(newFunctionNode);
         for (final Symbol symbol : newFunctionNode.getDeclaredSymbols()) {
             if (symbol.getSymbolType().isUnknown()) {
                 symbol.setType(Type.OBJECT);
@@ -400,8 +430,6 @@
             }
         }
 
-        final Block body = newFunctionNode.getBody();
-
         if (newFunctionNode.hasLazyChildren()) {
             //the final body has already been assigned as we have left the function node block body by now
             objectifySymbols(body);
@@ -409,9 +437,9 @@
 
         if (body.getFlag(Block.NEEDS_SELF_SYMBOL)) {
             final IdentNode callee = compilerConstant(CALLEE);
-            final VarNode selfInit =
+            VarNode selfInit =
                 new VarNode(
-                    newFunctionNode.getSource(),
+                    newFunctionNode.getLineNumber(),
                     newFunctionNode.getToken(),
                     newFunctionNode.getFinish(),
                     newFunctionNode.getIdent(),
@@ -419,8 +447,7 @@
 
             LOG.info("Accepting self symbol init ", selfInit, " for ", newFunctionNode.getName());
 
-            final List<Node> newStatements = new ArrayList<>();
-            newStatements.add(selfInit);
+            final List<Statement> newStatements = new ArrayList<>();
             assert callee.getSymbol() != null && callee.getSymbol().hasSlot();
 
             final IdentNode name       = selfInit.getName();
@@ -428,9 +455,10 @@
 
             assert nameSymbol != null;
 
-            name.setSymbol(nameSymbol);
-            selfInit.setSymbol(nameSymbol);
+            selfInit = selfInit.setName((IdentNode)name.setSymbol(lc, nameSymbol));
+            selfInit = (VarNode)selfInit.setSymbol(lc, nameSymbol);
 
+            newStatements.add(selfInit);
             newStatements.addAll(body.getStatements());
             newFunctionNode = newFunctionNode.setBody(lc, body.setStatements(lc, newStatements));
         }
@@ -447,34 +475,32 @@
 
         end(newFunctionNode, false);
 
-        return newFunctionNode; //.setFlag(lc, lc.getFlags(functionNode));
+        return newFunctionNode;
     }
 
     @Override
     public Node leaveCONVERT(final UnaryNode unaryNode) {
         assert false : "There should be no convert operators in IR during Attribution";
-        end(unaryNode);
-        return unaryNode;
+        return end(unaryNode);
     }
 
     @Override
-    public boolean enterIdentNode(final IdentNode identNode) {
+    public Node leaveIdentNode(final IdentNode identNode) {
         final String name = identNode.getName();
 
         start(identNode);
 
+        final LexicalContext lc = getLexicalContext();
+
         if (identNode.isPropertyName()) {
             // assign a pseudo symbol to property name
             final Symbol pseudoSymbol = pseudoSymbol(name);
             LOG.info("IdentNode is property name -> assigning pseudo symbol ", pseudoSymbol);
             LOG.unindent();
-            identNode.setSymbol(pseudoSymbol);
-            return false;
+            return end(identNode.setSymbol(lc, pseudoSymbol));
         }
 
-        final LexicalContext lc        = getLexicalContext();
-        final Block          block     = lc.getCurrentBlock();
-        final Symbol         oldSymbol = identNode.getSymbol();
+        final Block block = lc.getCurrentBlock();
 
         Symbol symbol = findSymbol(block, name);
 
@@ -495,12 +521,11 @@
                 }
             }
 
-            identNode.setSymbol(symbol);
             // if symbol is non-local or we're in a with block, we need to put symbol in scope (if it isn't already)
             maybeForceScope(symbol);
         } else {
             LOG.info("No symbol exists. Declare undefined: ", symbol);
-            symbol = defineSymbol(block, name, IS_GLOBAL, identNode);
+            symbol = defineSymbol(block, name, IS_GLOBAL);
             // we have never seen this before, it can be undefined
             newType(symbol, Type.OBJECT); // TODO unknown -we have explicit casts anyway?
             symbol.setCanBeUndefined();
@@ -509,14 +534,12 @@
 
         setBlockScope(name, symbol);
 
-        if (symbol != oldSymbol && !identNode.isInitializedHere()) {
+        if (!identNode.isInitializedHere()) {
             symbol.increaseUseCount();
         }
         addLocalUse(identNode.getName());
 
-        end(identNode);
-
-        return false;
+        return end(identNode.setSymbol(lc, symbol));
     }
 
     /**
@@ -525,7 +548,7 @@
      * @param symbol the symbol that might be scoped
      */
     private void maybeForceScope(final Symbol symbol) {
-        if(!symbol.isScope() && symbolNeedsToBeScope(symbol)) {
+        if (!symbol.isScope() && symbolNeedsToBeScope(symbol)) {
             Symbol.setSymbolIsScope(getLexicalContext(), symbol);
         }
     }
@@ -612,11 +635,11 @@
     private Symbol findSymbol(final Block block, final String name) {
         // Search up block chain to locate symbol.
 
-        for(final Iterator<Block> blocks = getLexicalContext().getBlocks(block); blocks.hasNext();) {
+        for (final Iterator<Block> blocks = getLexicalContext().getBlocks(block); blocks.hasNext();) {
             // Find name.
             final Symbol symbol = blocks.next().getExistingSymbol(name);
             // If found then we are good.
-            if(symbol != null) {
+            if (symbol != null) {
                 return symbol;
             }
         }
@@ -625,39 +648,19 @@
 
     @Override
     public Node leaveIndexNode(final IndexNode indexNode) {
-        ensureSymbol(Type.OBJECT, indexNode); //TODO
-        return indexNode;
+        return end(ensureSymbol(Type.OBJECT, indexNode));
     }
 
     @SuppressWarnings("rawtypes")
     @Override
-    public boolean enterLiteralNode(final LiteralNode literalNode) {
-        try {
-            start(literalNode);
-            assert !literalNode.isTokenType(TokenType.THIS) : "tokentype for " + literalNode + " is this"; //guard against old dead code case. literal nodes should never inherit tokens
-
-            if (literalNode instanceof ArrayLiteralNode) {
-                final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode)literalNode;
-                final Node[]           array            = arrayLiteralNode.getValue();
-
-                for (int i = 0; i < array.length; i++) {
-                    final Node element = array[i];
-                    if (element != null) {
-                        array[i] = element.accept(this);
-                    }
-                }
-                arrayLiteralNode.analyze();
-                //array literal node now has an element type and all elements are attributed
-            } else {
-                assert !(literalNode.getValue() instanceof Node) : "literals with Node values not supported";
-            }
-
-            getLexicalContext().getCurrentFunction().newLiteral(literalNode);
-        } finally {
-            end(literalNode);
+    public Node leaveLiteralNode(final LiteralNode literalNode) {
+        assert !literalNode.isTokenType(TokenType.THIS) : "tokentype for " + literalNode + " is this"; //guard against old dead code case. literal nodes should never inherit tokens
+        assert literalNode instanceof ArrayLiteralNode || !(literalNode.getValue() instanceof Node) : "literals with Node values not supported";
+        final Symbol symbol = new Symbol(getLexicalContext().getCurrentFunction().uniqueName(LITERAL_PREFIX.symbolName()), IS_CONSTANT, literalNode.getType());
+        if (literalNode instanceof ArrayLiteralNode) {
+            ((ArrayLiteralNode)literalNode).analyze();
         }
-
-        return false;
+        return end(literalNode.setSymbol(getLexicalContext(), symbol));
     }
 
     @Override
@@ -667,18 +670,13 @@
 
     @Override
     public Node leaveObjectNode(final ObjectNode objectNode) {
-        ensureSymbol(Type.OBJECT, objectNode);
-        return end(objectNode);
+        return end(ensureSymbol(Type.OBJECT, objectNode));
     }
 
-    //TODO is this correct why not leave?
     @Override
-    public boolean enterPropertyNode(final PropertyNode propertyNode) {
+    public Node leavePropertyNode(final PropertyNode propertyNode) {
         // assign a pseudo symbol to property name, see NASHORN-710
-        start(propertyNode);
-        propertyNode.setSymbol(new Symbol(propertyNode.getKeyName(), 0, Type.OBJECT));
-        end(propertyNode);
-        return true;
+        return propertyNode.setSymbol(getLexicalContext(), new Symbol(propertyNode.getKeyName(), 0, Type.OBJECT));
     }
 
     @Override
@@ -763,12 +761,9 @@
         final IdentNode ident = varNode.getName();
         final String    name  = ident.getName();
 
-        final Symbol symbol = defineSymbol(getLexicalContext().getCurrentBlock(), name, IS_VAR, ident);
+        final Symbol symbol = defineSymbol(getLexicalContext().getCurrentBlock(), name, IS_VAR);
         assert symbol != null;
 
-        LOG.info("VarNode ", varNode, " set symbol ", symbol);
-        varNode.setSymbol(symbol);
-
         // NASHORN-467 - use before definition of vars - conservative
         if (isLocalUse(ident.getName())) {
             newType(symbol, Type.OBJECT);
@@ -780,22 +775,32 @@
 
     @Override
     public Node leaveVarNode(final VarNode varNode) {
-        final Node      init  = varNode.getInit();
-        final IdentNode ident = varNode.getName();
+        VarNode newVarNode = varNode;
+
+        final Node      init  = newVarNode.getInit();
+        final IdentNode ident = newVarNode.getName();
         final String    name  = ident.getName();
 
+        final LexicalContext lc = getLexicalContext();
+        final Symbol  symbol = findSymbol(lc.getCurrentBlock(), ident.getName());
+
         if (init == null) {
             // var x; with no init will be treated like a use of x by
-            // visit(IdentNode) unless we remove the name
-            // from the localdef list.
+            // leaveIdentNode unless we remove the name from the localdef list.
             removeLocalDef(name);
-            return varNode;
+            return end(newVarNode.setSymbol(lc, symbol));
         }
 
         addLocalDef(name);
 
-        final Symbol  symbol   = varNode.getSymbol();
-        final boolean isScript = getLexicalContext().getDefiningFunction(symbol).isProgram(); //see NASHORN-56
+        assert symbol != null;
+
+        final IdentNode newIdent = (IdentNode)ident.setSymbol(lc, symbol);
+
+        newVarNode = newVarNode.setName(newIdent);
+        newVarNode = (VarNode)newVarNode.setSymbol(lc, symbol);
+
+        final boolean isScript = lc.getDefiningFunction(symbol).isProgram(); //see NASHORN-56
         if ((init.getType().isNumeric() || init.getType().isBoolean()) && !isScript) {
             // Forbid integers as local vars for now as we have no way to treat them as undefined
             newType(symbol, init.getType());
@@ -803,36 +808,28 @@
             newType(symbol, Type.OBJECT);
         }
 
-        assert varNode.hasType() : varNode;
+        assert newVarNode.hasType() : newVarNode + " has no type";
 
-        end(varNode);
-
-        return varNode;
+        return end(newVarNode);
     }
 
     @Override
     public Node leaveADD(final UnaryNode unaryNode) {
-        ensureSymbol(arithType(), unaryNode);
-        end(unaryNode);
-        return unaryNode;
+        return end(ensureSymbol(arithType(), unaryNode));
     }
 
     @Override
     public Node leaveBIT_NOT(final UnaryNode unaryNode) {
-        ensureSymbol(Type.INT, unaryNode);
-        end(unaryNode);
-        return unaryNode;
+        return end(ensureSymbol(Type.INT, unaryNode));
     }
 
     @Override
     public Node leaveDECINC(final UnaryNode unaryNode) {
         // @see assignOffset
-        ensureAssignmentSlots(getLexicalContext().getCurrentFunction(), unaryNode.rhs());
+        final UnaryNode newUnaryNode = unaryNode.setRHS(ensureAssignmentSlots(unaryNode.rhs()));
         final Type type = arithType();
-        newType(unaryNode.rhs().getSymbol(), type);
-        ensureSymbol(type, unaryNode);
-        end(unaryNode);
-        return unaryNode;
+        newType(newUnaryNode.rhs().getSymbol(), type);
+        return end(ensureSymbol(type, newUnaryNode));
     }
 
     @Override
@@ -908,23 +905,24 @@
 
     @Override
     public Node leaveNEW(final UnaryNode unaryNode) {
-        ensureSymbol(Type.OBJECT, unaryNode);
-        end(unaryNode);
-        return unaryNode;
+        return end(ensureSymbol(Type.OBJECT, unaryNode));
     }
 
     @Override
     public Node leaveNOT(final UnaryNode unaryNode) {
-        ensureSymbol(Type.BOOLEAN, unaryNode);
-        end(unaryNode);
-        return unaryNode;
+        return end(ensureSymbol(Type.BOOLEAN, unaryNode));
     }
 
     private IdentNode compilerConstant(CompilerConstants cc) {
         final FunctionNode functionNode = getLexicalContext().getCurrentFunction();
-        final IdentNode node = new IdentNode(functionNode.getSource(), functionNode.getToken(), functionNode.getFinish(), cc.symbolName());
-        node.setSymbol(functionNode.compilerConstant(cc));
-        return node;
+        return (IdentNode)
+            new IdentNode(
+                functionNode.getToken(),
+                functionNode.getFinish(),
+                cc.symbolName()).
+                setSymbol(
+                    getLexicalContext(),
+                    functionNode.compilerConstant(cc));
     }
 
     @Override
@@ -952,15 +950,12 @@
 
     @Override
     public Node leaveRuntimeNode(final RuntimeNode runtimeNode) {
-        ensureSymbol(runtimeNode.getRequest().getReturnType(), runtimeNode);
-        return runtimeNode;
+        return end(ensureSymbol(runtimeNode.getRequest().getReturnType(), runtimeNode));
     }
 
     @Override
     public Node leaveSUB(final UnaryNode unaryNode) {
-        ensureSymbol(arithType(), unaryNode);
-        end(unaryNode);
-        return unaryNode;
+        return end(ensureSymbol(arithType(), unaryNode));
     }
 
     @Override
@@ -982,18 +977,16 @@
 
         ensureTypeNotUnknown(lhs);
         ensureTypeNotUnknown(rhs);
-        ensureSymbol(Type.widest(lhs.getType(), rhs.getType()), binaryNode);
-
-        end(binaryNode);
-
-        return binaryNode;
+        //even if we are adding two known types, this can overflow. i.e.
+        //int and number -> number.
+        //int and int are also number though.
+        //something and object is object
+        return end(ensureSymbol(Type.widest(arithType(), Type.widest(lhs.getType(), rhs.getType())), binaryNode));
     }
 
     @Override
     public Node leaveAND(final BinaryNode binaryNode) {
-        ensureSymbol(Type.OBJECT, binaryNode);
-        end(binaryNode);
-        return binaryNode;
+        return end(ensureSymbol(Type.OBJECT, binaryNode));
     }
 
     /**
@@ -1013,8 +1006,7 @@
             Symbol symbol = findSymbol(block, name);
 
             if (symbol == null) {
-                symbol = defineSymbol(block, name, IS_GLOBAL, ident);
-                binaryNode.setSymbol(symbol);
+                symbol = defineSymbol(block, name, IS_GLOBAL);
             } else {
                 maybeForceScope(symbol);
             }
@@ -1025,6 +1017,31 @@
         return true;
     }
 
+
+    /**
+     * This assign helper is called after an assignment, when all children of
+     * the assign has been processed. It fixes the types and recursively makes
+     * sure that everyhing has slots that should have them in the chain.
+     *
+     * @param binaryNode assignment node
+     */
+    private Node leaveAssignmentNode(final BinaryNode binaryNode) {
+        BinaryNode newBinaryNode = binaryNode;
+
+        final Node lhs = binaryNode.lhs();
+        final Node rhs = binaryNode.rhs();
+        final Type type;
+
+        if (rhs.getType().isNumeric()) {
+            type = Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType());
+        } else {
+            type = Type.OBJECT; //force lhs to be an object if not numeric assignment, e.g. strings too.
+        }
+
+        newType(lhs.getSymbol(), type);
+        return end(ensureSymbol(type, newBinaryNode));
+    }
+
     private boolean isLocal(FunctionNode function, Symbol symbol) {
         final FunctionNode definingFn = getLexicalContext().getDefiningFunction(symbol);
         // Temp symbols are not assigned to a block, so their defining fn is null; those can be assumed local
@@ -1173,14 +1190,12 @@
 
     @Override
     public Node leaveCOMMARIGHT(final BinaryNode binaryNode) {
-        ensureSymbol(binaryNode.rhs().getType(), binaryNode);
-        return binaryNode;
+        return end(ensureSymbol(binaryNode.rhs().getType(), binaryNode));
     }
 
     @Override
     public Node leaveCOMMALEFT(final BinaryNode binaryNode) {
-        ensureSymbol(binaryNode.lhs().getType(), binaryNode);
-        return binaryNode;
+        return end(ensureSymbol(binaryNode.lhs().getType(), binaryNode));
     }
 
     @Override
@@ -1189,15 +1204,10 @@
     }
 
     private Node leaveCmp(final BinaryNode binaryNode) {
-        final Node lhs = binaryNode.lhs();
-        final Node rhs = binaryNode.rhs();
+        ensureTypeNotUnknown(binaryNode.lhs());
+        ensureTypeNotUnknown(binaryNode.rhs());
 
-        ensureSymbol(Type.BOOLEAN, binaryNode);
-        ensureTypeNotUnknown(lhs);
-        ensureTypeNotUnknown(rhs);
-
-        end(binaryNode);
-        return binaryNode;
+        return end(ensureSymbol(Type.BOOLEAN, binaryNode));
     }
 
     private Node coerce(final BinaryNode binaryNode, final Type operandType, final Type destType) {
@@ -1207,11 +1217,9 @@
         // as, say, an int : function(x) { return x & 4711 }, and x is not defined in
         // the function. to make this work, uncomment the following two type inferences
         // and debug.
-
         //newType(binaryNode.lhs().getSymbol(), operandType);
         //newType(binaryNode.rhs().getSymbol(), operandType);
-        ensureSymbol(destType, binaryNode);
-        return binaryNode;
+        return ensureSymbol(destType, binaryNode);
     }
 
     private Node coerce(final BinaryNode binaryNode, final Type type) {
@@ -1295,9 +1303,7 @@
 
     @Override
     public Node leaveOR(final BinaryNode binaryNode) {
-        ensureSymbol(Type.OBJECT, binaryNode);
-        end(binaryNode);
-        return binaryNode;
+        return end(ensureSymbol(Type.OBJECT, binaryNode));
     }
 
     @Override
@@ -1346,50 +1352,13 @@
         ensureTypeNotUnknown(rhs);
 
         final Type type = Type.widest(lhs.getType(), rhs.getType());
-        ensureSymbol(type, ternaryNode);
-
-        end(ternaryNode);
-        assert ternaryNode.getSymbol() != null;
-
-        return ternaryNode;
+        return end(ensureSymbol(type, ternaryNode));
     }
 
-    private void initThis(final Block block) {
-        final Symbol thisSymbol = defineSymbol(block, THIS.symbolName(), IS_PARAM | IS_THIS, null);
-        newType(thisSymbol, Type.OBJECT);
-        thisSymbol.setNeedsSlot(true);
-    }
-
-    private void initScope(final Block block) {
-        final Symbol scopeSymbol = defineSymbol(block, SCOPE.symbolName(), IS_VAR | IS_INTERNAL, null);
-        newType(scopeSymbol, Type.typeFor(ScriptObject.class));
-        scopeSymbol.setNeedsSlot(true);
-    }
-
-    private void initReturn(final Block block) {
-        final Symbol returnSymbol = defineSymbol(block, RETURN.symbolName(), IS_VAR | IS_INTERNAL, null);
-        newType(returnSymbol, Type.OBJECT);
-        returnSymbol.setNeedsSlot(true);
-        //return symbol is always object as it's the __return__ thing. What returnType is is another matter though
-    }
-
-    private void initVarArg(final Block block, final boolean needsArguments) {
-        final Symbol varArgsSymbol = defineSymbol(block, VARARGS.symbolName(), IS_PARAM | IS_INTERNAL, null);
-        varArgsSymbol.setTypeOverride(Type.OBJECT_ARRAY);
-        varArgsSymbol.setNeedsSlot(true);
-
-        if (needsArguments) {
-            final Symbol    argumentsSymbol = defineSymbol(block, ARGUMENTS.symbolName(), IS_VAR | IS_INTERNAL, null);
-            newType(argumentsSymbol, Type.typeFor(ScriptObject.class));
-            argumentsSymbol.setNeedsSlot(true);
-            addLocalDef(ARGUMENTS.symbolName());
-        }
-    }
-
-    private void initCallee(final Block block) {
-        final Symbol calleeSymbol = defineSymbol(block, CALLEE.symbolName(), IS_PARAM | IS_INTERNAL, null);
-        newType(calleeSymbol, FunctionNode.FUNCTION_TYPE);
-        calleeSymbol.setNeedsSlot(true);
+    private void initCompileConstant(final CompilerConstants cc, final Block block, final int flags, final Type type) {
+        final Symbol symbol = defineSymbol(block, cc.symbolName(), flags);
+        newType(symbol, type);
+        symbol.setNeedsSlot(true);
     }
 
     /**
@@ -1399,19 +1368,26 @@
      * @param functionNode the function node
      */
     private void initParameters(final FunctionNode functionNode, final Block body) {
+        int pos = 0;
         for (final IdentNode param : functionNode.getParameters()) {
             addLocalDef(param.getName());
-            final Symbol paramSymbol = defineSymbol(body, param.getName(), IS_PARAM, param);
-            if (paramSymbol != null) {
-                final Type callSiteParamType = functionNode.getSpecializedType(param);
-                if (callSiteParamType != null) {
-                    LOG.info("Param ", paramSymbol, " has a callsite type ", callSiteParamType, ". Using that.");
-                }
-                newType(paramSymbol, callSiteParamType == null ? Type.UNKNOWN : callSiteParamType);
+
+            final Type callSiteParamType = functionNode.getHints().getParameterType(pos);
+            int flags = IS_PARAM;
+            if (callSiteParamType != null) {
+                LOG.info("Param ", param, " has a callsite type ", callSiteParamType, ". Using that.");
+                flags |= Symbol.IS_SPECIALIZED_PARAM;
             }
 
-            LOG.info("Initialized param ", paramSymbol);
+            final Symbol paramSymbol = defineSymbol(body, param.getName(), flags);
+            assert paramSymbol != null;
+
+            newType(paramSymbol, callSiteParamType == null ? Type.UNKNOWN : callSiteParamType);
+
+            LOG.info("Initialized param ", pos, "=", paramSymbol);
+            pos++;
         }
+
     }
 
     /**
@@ -1420,23 +1396,34 @@
      *
      * @param functionNode functionNode
      */
-    private static void finalizeParameters(final FunctionNode functionNode) {
+    private FunctionNode finalizeParameters(final FunctionNode functionNode) {
+        final List<IdentNode> newParams = new ArrayList<>();
         final boolean isVarArg = functionNode.isVarArg();
+        final int nparams = functionNode.getParameters().size();
 
-        for (final IdentNode ident : functionNode.getParameters()) {
-            final Symbol paramSymbol = ident.getSymbol();
+        int specialize = 0;
+        int pos = 0;
+        for (final IdentNode param : functionNode.getParameters()) {
+            final Symbol paramSymbol = functionNode.getBody().getExistingSymbol(param.getName());
+            assert paramSymbol != null;
+            assert paramSymbol.isParam();
+            newParams.add((IdentNode)param.setSymbol(getLexicalContext(), paramSymbol));
 
             assert paramSymbol != null;
-            Type type = functionNode.getSpecializedType(ident);
+            Type type = functionNode.getHints().getParameterType(pos);
             if (type == null) {
                 type = Type.OBJECT;
             }
 
             // if we know that a parameter is only used as a certain type throughout
             // this function, we can tell the runtime system that no matter what the
-            // call site is, use this information. TODO
-            if (!paramSymbol.getSymbolType().isObject()) {
-                LOG.finest("Parameter ", ident, " could profit from specialization to ", paramSymbol.getSymbolType());
+            // call site is, use this information:
+            // we also need more than half of the parameters to be specializable
+            // for the heuristic to be worth it, and we need more than one use of
+            // the parameter to consider it, i.e. function(x) { call(x); } doens't count
+            if (paramSymbol.getUseCount() > 1 && !paramSymbol.getSymbolType().isObject()) {
+                LOG.finest("Parameter ", param, " could profit from specialization to ", paramSymbol.getSymbolType());
+                specialize++;
             }
 
             newType(paramSymbol, Type.widest(type, paramSymbol.getSymbolType()));
@@ -1445,7 +1432,17 @@
             if (isVarArg) {
                 paramSymbol.setNeedsSlot(false);
             }
+
+            pos++;
         }
+
+        FunctionNode newFunctionNode = functionNode;
+
+        if (nparams == 0 || (specialize * 2) < nparams) {
+            newFunctionNode = newFunctionNode.clearSnapshot(getLexicalContext());
+        }
+
+        return newFunctionNode.setParameters(getLexicalContext(), newParams);
     }
 
     /**
@@ -1459,7 +1456,7 @@
 
         for (final Property property : map.getProperties()) {
             final String key    = property.getKey();
-            final Symbol symbol = defineSymbol(block, key, IS_GLOBAL, null);
+            final Symbol symbol = defineSymbol(block, key, IS_GLOBAL);
             newType(symbol, Type.OBJECT);
             LOG.info("Added global symbol from property map ", symbol);
         }
@@ -1498,7 +1495,7 @@
          * objects as parameters, for example +, but not *, which is known
          * to coerce types into doubles
          */
-        if (node.getType().isUnknown() || symbol.isParam()) {
+        if (node.getType().isUnknown() || (symbol.isParam() && !symbol.isSpecializedParam())) {
             newType(symbol, Type.OBJECT);
             symbol.setCanBeUndefined();
          }
@@ -1520,19 +1517,25 @@
      *
      * see NASHORN-258
      *
-     * @param functionNode   the current function node (has to be passed as it changes in the visitor below)
      * @param assignmentDest the destination node of the assignment, e.g. lhs for binary nodes
      */
-    private static void ensureAssignmentSlots(final FunctionNode functionNode, final Node assignmentDest) {
-        assignmentDest.accept(new NodeVisitor() {
+    private Node ensureAssignmentSlots(final Node assignmentDest) {
+        final LexicalContext attrLexicalContext = getLexicalContext();
+        return assignmentDest.accept(new NodeVisitor() {
             @Override
             public Node leaveIndexNode(final IndexNode indexNode) {
                 assert indexNode.getSymbol().isTemp();
                 final Node index = indexNode.getIndex();
                 //only temps can be set as needing slots. the others will self resolve
                 //it is illegal to take a scope var and force it to be a slot, that breaks
-                if (index.getSymbol().isTemp() && !index.getSymbol().isConstant()) {
-                     index.getSymbol().setNeedsSlot(true);
+                Symbol indexSymbol = index.getSymbol();
+                if (indexSymbol.isTemp() && !indexSymbol.isConstant() && !indexSymbol.hasSlot()) {
+                    if(indexSymbol.isShared()) {
+                        indexSymbol = temporarySymbols.createUnshared(indexSymbol);
+                    }
+                    indexSymbol.setNeedsSlot(true);
+                    attrLexicalContext.getCurrentBlock().putSymbol(attrLexicalContext, indexSymbol);
+                    return indexNode.setIndex(index.setSymbol(attrLexicalContext, indexSymbol));
                 }
                 return indexNode;
             }
@@ -1557,22 +1560,30 @@
      *
      * @param functionNode
      */
-    private static void finalizeTypes(final FunctionNode functionNode) {
+    private FunctionNode finalizeTypes(final FunctionNode functionNode) {
         final Set<Node> changed = new HashSet<>();
+        FunctionNode currentFunctionNode = functionNode;
         do {
             changed.clear();
-            functionNode.accept(new NodeVisitor() {
+            final FunctionNode newFunctionNode = (FunctionNode)currentFunctionNode.accept(new NodeVisitor() {
 
-                private void widen(final Node node, final Type to) {
+                private Node widen(final Node node, final Type to) {
                     if (node instanceof LiteralNode) {
-                        return;
+                        return node;
                     }
                     Type from = node.getType();
                     if (!Type.areEquivalent(from, to) && Type.widest(from, to) == to) {
-                        LOG.fine("Had to post pass widen '", node, "' " + Debug.id(node), " from ", node.getType(), " to ", to);
-                        newType(node.getSymbol(), to);
-                        changed.add(node);
+                        LOG.fine("Had to post pass widen '", node, "' ", Debug.id(node), " from ", node.getType(), " to ", to);
+                        Symbol symbol = node.getSymbol();
+                        if(symbol.isShared() && symbol.wouldChangeType(to)) {
+                            symbol = temporarySymbols.getTypedTemporarySymbol(to);
+                        }
+                        newType(symbol, to);
+                        final Node newNode = node.setSymbol(getLexicalContext(), symbol);
+                        changed.add(newNode);
+                        return newNode;
                     }
+                    return node;
                 }
 
                 @Override
@@ -1598,43 +1609,23 @@
                 @Override
                 public Node leaveBinaryNode(final BinaryNode binaryNode) {
                     final Type widest = Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType());
+                    BinaryNode newBinaryNode = binaryNode;
                     switch (binaryNode.tokenType()) {
                     default:
                         if (!binaryNode.isAssignment() || binaryNode.isSelfModifying()) {
                             break;
                         }
-                        widen(binaryNode.lhs(), widest);
+                        newBinaryNode = newBinaryNode.setLHS(widen(newBinaryNode.lhs(), widest));
                     case ADD:
-                        widen(binaryNode, widest);
-                        break;
+                        newBinaryNode = (BinaryNode)widen(newBinaryNode, widest);
                     }
-                    return binaryNode;
+                    return newBinaryNode;
                 }
             });
+            getLexicalContext().replace(currentFunctionNode, newFunctionNode);
+            currentFunctionNode = newFunctionNode;
         } while (!changed.isEmpty());
-    }
-
-    /**
-     * This assign helper is called after an assignment, when all children of
-     * the assign has been processed. It fixes the types and recursively makes
-     * sure that everyhing has slots that should have them in the chain.
-     *
-     * @param binaryNode assignment node
-     */
-    private Node leaveAssignmentNode(final BinaryNode binaryNode) {
-        final Node lhs = binaryNode.lhs();
-        final Node rhs = binaryNode.rhs();
-
-        final Type type;
-        if (rhs.getType().isNumeric()) {
-            type = Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType());
-        } else {
-            type = Type.OBJECT; //force lhs to be an object if not numeric assignment, e.g. strings too.
-        }
-        ensureSymbol(type, binaryNode);
-        newType(lhs.getSymbol(), type);
-        end(binaryNode);
-        return binaryNode;
+        return currentFunctionNode;
     }
 
     private Node leaveSelfModifyingAssignmentNode(final BinaryNode binaryNode) {
@@ -1646,25 +1637,18 @@
         final Node lhs = binaryNode.lhs();
 
         newType(lhs.getSymbol(), destType); //may not narrow if dest is already wider than destType
-        ensureSymbol(destType, binaryNode); //for OP= nodes, the node can carry a narrower types than its lhs rhs. This is perfectly fine
+//        ensureSymbol(destType, binaryNode); //for OP= nodes, the node can carry a narrower types than its lhs rhs. This is perfectly fine
 
-        ensureAssignmentSlots(getLexicalContext().getCurrentFunction(), binaryNode);
-
-        end(binaryNode);
-        return binaryNode;
+        return end(ensureSymbol(destType, ensureAssignmentSlots(binaryNode)));
     }
 
-    private Symbol ensureSymbol(final FunctionNode functionNode, final Type type, final Node node) {
-        LOG.info("New TEMPORARY added to ", functionNode.getName(), " type=", type);
-        return functionNode.ensureSymbol(getLexicalContext().getCurrentBlock(), type, node);
-    }
-
-    private Symbol ensureSymbol(final Type type, final Node node) {
-        return ensureSymbol(getLexicalContext().getCurrentFunction(), type, node);
+    private Node ensureSymbol(final Type type, final Node node) {
+        LOG.info("New TEMPORARY added to ", getLexicalContext().getCurrentFunction().getName(), " type=", type);
+        return ensureSymbol(getLexicalContext(), type, node);
     }
 
     private Symbol newInternal(final String name, final Type type) {
-        final Symbol iter = defineSymbol(getLexicalContext().getCurrentBlock(), name, IS_VAR | IS_INTERNAL, null);
+        final Symbol iter = defineSymbol(getLexicalContext().getCurrentBlock(), name, IS_VAR | IS_INTERNAL);
         iter.setType(type); // NASHORN-73
         return iter;
     }
@@ -1721,6 +1705,10 @@
         localUses.peek().add(name);
     }
 
+    private Node ensureSymbol(final LexicalContext lc, final Type type, final Node node) {
+        return temporarySymbols.ensureSymbol(lc, type, node);
+    }
+
     /**
      * Pessimistically promote all symbols in current function node to Object types
      * This is done when the function contains unevaluated black boxes such as
@@ -1731,8 +1719,7 @@
     private static void objectifySymbols(final Block body) {
         body.accept(new NodeVisitor() {
             private void toObject(final Block block) {
-                for (final Iterator<Symbol> iter = block.symbolIterator(); iter.hasNext();) {
-                    final Symbol symbol = iter.next();
+                for (final Symbol symbol : block.getSymbols()) {
                     if (!symbol.isTemp()) {
                         newType(symbol, Type.OBJECT);
                     }
@@ -1788,6 +1775,10 @@
     }
 
     private Node end(final Node node, final boolean printNode) {
+        if(node instanceof Statement) {
+            // If we're done with a statement, all temporaries can be reused.
+            temporarySymbols.reuse();
+        }
         if (DEBUG) {
             final StringBuilder sb = new StringBuilder();
 
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
index 5d4b8f9..1fae129 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
@@ -63,6 +63,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
+
 import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
 import jdk.nashorn.internal.codegen.CompilerConstants.Call;
 import jdk.nashorn.internal.codegen.RuntimeCallSite.SpecializedRuntimeNode;
@@ -88,7 +89,6 @@
 import jdk.nashorn.internal.ir.IndexNode;
 import jdk.nashorn.internal.ir.LexicalContext;
 import jdk.nashorn.internal.ir.LexicalContextNode;
-import jdk.nashorn.internal.ir.LineNumberNode;
 import jdk.nashorn.internal.ir.LiteralNode;
 import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
 import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit;
@@ -100,6 +100,7 @@
 import jdk.nashorn.internal.ir.RuntimeNode;
 import jdk.nashorn.internal.ir.RuntimeNode.Request;
 import jdk.nashorn.internal.ir.SplitNode;
+import jdk.nashorn.internal.ir.Statement;
 import jdk.nashorn.internal.ir.SwitchNode;
 import jdk.nashorn.internal.ir.Symbol;
 import jdk.nashorn.internal.ir.TernaryNode;
@@ -191,6 +192,8 @@
     /** Current compile unit */
     private CompileUnit unit;
 
+    private int lastLineNumber = -1;
+
     /** When should we stop caching regexp expressions in fields to limit bytecode size? */
     private static final int MAX_REGEX_FIELDS = 2 * 1024;
 
@@ -261,14 +264,15 @@
             return method.load(symbol);
         }
 
-        final String name = symbol.getName();
+        final String name   = symbol.getName();
+        final Source source = getLexicalContext().getCurrentFunction().getSource();
 
         if (CompilerConstants.__FILE__.name().equals(name)) {
-            return method.load(identNode.getSource().getName());
+            return method.load(source.getName());
         } else if (CompilerConstants.__DIR__.name().equals(name)) {
-            return method.load(identNode.getSource().getBase());
+            return method.load(source.getBase());
         } else if (CompilerConstants.__LINE__.name().equals(name)) {
-            return method.load(identNode.getSource().getLine(identNode.position())).convert(Type.OBJECT);
+            return method.load(source.getLine(identNode.position())).convert(Type.OBJECT);
         } else {
             assert identNode.getSymbol().isScope() : identNode + " is not in scope!";
 
@@ -568,8 +572,7 @@
      * @param block block containing symbols.
      */
     private void symbolInfo(final Block block) {
-        for (final Iterator<Symbol> iter = block.symbolIterator(); iter.hasNext(); ) {
-            final Symbol symbol = iter.next();
+        for (final Symbol symbol : block.getSymbols()) {
             if (symbol.hasSlot()) {
                 method.localVariable(symbol, block.getEntryLabel(), block.getBreakLabel());
             }
@@ -619,6 +622,8 @@
 
     @Override
     public boolean enterBreakNode(final BreakNode breakNode) {
+        lineNumber(breakNode);
+
         final BreakableNode breakFrom = getLexicalContext().getBreakable(breakNode.getLabel());
         for (int i = 0; i < getLexicalContext().getScopeNestingLevelTo(breakFrom); i++) {
             closeWith();
@@ -663,6 +668,8 @@
 
     @Override
     public boolean enterCallNode(final CallNode callNode) {
+        lineNumber(callNode);
+
         final List<Node>   args            = callNode.getArgs();
         final Node         function        = callNode.getFunction();
         final Block        currentBlock    = getLexicalContext().getCurrentBlock();
@@ -836,6 +843,8 @@
 
     @Override
     public boolean enterContinueNode(final ContinueNode continueNode) {
+        lineNumber(continueNode);
+
         final LoopNode continueTo = getLexicalContext().getContinueTo(continueNode.getLabel());
         for (int i = 0; i < getLexicalContext().getScopeNestingLevelTo(continueTo); i++) {
             closeWith();
@@ -847,11 +856,15 @@
 
     @Override
     public boolean enterEmptyNode(final EmptyNode emptyNode) {
+        lineNumber(emptyNode);
+
         return false;
     }
 
     @Override
     public boolean enterExecuteNode(final ExecuteNode executeNode) {
+        lineNumber(executeNode);
+
         final Node expression = executeNode.getExpression();
         expression.accept(this);
 
@@ -860,6 +873,8 @@
 
     @Override
     public boolean enterForNode(final ForNode forNode) {
+        lineNumber(forNode);
+
         final Node  test   = forNode.getTest();
         final Block body   = forNode.getBody();
         final Node  modify = forNode.getModify();
@@ -937,11 +952,10 @@
 
     private static int assignSlots(final Block block, final int firstSlot) {
         int nextSlot = firstSlot;
-        for (final Iterator<Symbol> iter = block.symbolIterator(); iter.hasNext(); ) {
-            final Symbol next = iter.next();
-            if (next.hasSlot()) {
-                next.setSlot(nextSlot);
-                nextSlot += next.slotCount();
+        for (final Symbol symbol : block.getSymbols()) {
+            if (symbol.hasSlot()) {
+                symbol.setSlot(nextSlot);
+                nextSlot += symbol.slotCount();
             }
         }
         return nextSlot;
@@ -1002,10 +1016,7 @@
 
             final boolean hasArguments = function.needsArguments();
 
-            final Iterator<Symbol> symbols = block.symbolIterator();
-
-            while (symbols.hasNext()) {
-                final Symbol symbol = symbols.next();
+            for (final Symbol symbol : block.getSymbols()) {
 
                 if (symbol.isInternal() || symbol.isThis() || symbol.isTemp()) {
                     continue;
@@ -1076,12 +1087,7 @@
                 }
             }
 
-            final Iterator<Symbol> iter = block.symbolIterator();
-            final List<Symbol> symbols = new ArrayList<>();
-            while (iter.hasNext()) {
-                symbols.add(iter.next());
-            }
-            initSymbols(symbols);
+            initSymbols(block.getSymbols());
         }
 
         // Debugging: print symbols? @see --print-symbols flag
@@ -1157,6 +1163,8 @@
 
     @Override
     public boolean enterIfNode(final IfNode ifNode) {
+        lineNumber(ifNode);
+
         final Node  test = ifNode.getTest();
         final Block pass = ifNode.getPass();
         final Block fail = ifNode.getFail();
@@ -1196,12 +1204,12 @@
         return false;
     }
 
-    @Override
-    public boolean enterLineNumberNode(final LineNumberNode lineNumberNode) {
-        final Label label = new Label((String)null);
-        method.label(label);
-        method.lineNumber(lineNumberNode.getLineNumber(), label);
-        return false;
+    private void lineNumber(final Statement statement) {
+        final int lineNumber = statement.getLineNumber();
+        if (lineNumber != lastLineNumber) {
+            method.lineNumber(statement.getLineNumber());
+        }
+        lastLineNumber = lineNumber;
     }
 
     /**
@@ -1533,6 +1541,8 @@
 
     @Override
     public boolean enterReturnNode(final ReturnNode returnNode) {
+        lineNumber(returnNode);
+
         method.registerReturn();
 
         final Type returnType = getLexicalContext().getCurrentFunction().getReturnType();
@@ -1742,6 +1752,8 @@
 
     @Override
     public boolean enterSplitNode(final SplitNode splitNode) {
+        lineNumber(splitNode);
+
         final CompileUnit splitCompileUnit = splitNode.getCompileUnit();
 
         final FunctionNode fn   = getLexicalContext().getCurrentFunction();
@@ -1885,6 +1897,8 @@
 
     @Override
     public boolean enterSwitchNode(final SwitchNode switchNode) {
+        lineNumber(switchNode);
+
         final Node           expression  = switchNode.getExpression();
         final Symbol         tag         = switchNode.getTag();
         final boolean        allInteger  = tag.getSymbolType().isInteger();
@@ -1967,7 +1981,6 @@
                 method.tableswitch(lo, hi, defaultLabel, table);
             } else {
                 final int[] ints = new int[size];
-
                 for (int i = 0; i < size; i++) {
                     ints[i] = values[i];
                 }
@@ -2013,10 +2026,13 @@
 
     @Override
     public boolean enterThrowNode(final ThrowNode throwNode) {
+        lineNumber(throwNode);
+
         method._new(ECMAException.class).dup();
 
+        final Source source     = getLexicalContext().getCurrentFunction().getSource();
+
         final Node   expression = throwNode.getExpression();
-        final Source source     = throwNode.getSource();
         final int    position   = throwNode.position();
         final int    line       = source.getLine(position);
         final int    column     = source.getColumn(position);
@@ -2036,6 +2052,8 @@
 
     @Override
     public boolean enterTryNode(final TryNode tryNode) {
+        lineNumber(tryNode);
+
         final Block       body        = tryNode.getBody();
         final List<Block> catchBlocks = tryNode.getCatchBlocks();
         final Symbol      symbol      = tryNode.getException();
@@ -2132,12 +2150,15 @@
 
     @Override
     public boolean enterVarNode(final VarNode varNode) {
+
         final Node init = varNode.getInit();
 
         if (init == null) {
             return false;
         }
 
+        lineNumber(varNode);
+
         final Symbol varSymbol = varNode.getSymbol();
         assert varSymbol != null : "variable node " + varNode + " requires a symbol";
 
@@ -2170,6 +2191,8 @@
 
     @Override
     public boolean enterWhileNode(final WhileNode whileNode) {
+        lineNumber(whileNode);
+
         final Node  test          = whileNode.getTest();
         final Block body          = whileNode.getBody();
         final Label breakLabel    = whileNode.getBreakLabel();
@@ -2192,7 +2215,7 @@
     }
 
     private void closeWith() {
-        if(method.hasScope()) {
+        if (method.hasScope()) {
             method.loadCompilerConstant(SCOPE);
             method.invoke(ScriptRuntime.CLOSE_WITH);
             method.storeCompilerConstant(SCOPE);
@@ -2235,7 +2258,7 @@
         // Always process body
         body.accept(this);
 
-        if(hasScope) {
+        if (hasScope) {
             // Ensure we always close the WithObject
             final Label endLabel   = new Label("with_end");
             final Label catchLabel = new Label("with_catch");
@@ -2364,7 +2387,6 @@
     public boolean enterDISCARD(final UnaryNode unaryNode) {
         final Node rhs = unaryNode.rhs();
 
-       // System.err.println("**** Enter discard " + unaryNode);
         discard.push(rhs);
         load(rhs);
 
@@ -2373,7 +2395,7 @@
             method.pop();
             discard.pop();
         }
-       // System.err.println("**** Leave discard " + unaryNode);
+
         return false;
     }
 
@@ -3019,12 +3041,12 @@
      * @param block the block we are in
      * @param ident identifier for block or function where applicable
      */
+    @SuppressWarnings("resource")
     private void printSymbols(final Block block, final String ident) {
         if (!compiler.getEnv()._print_symbols) {
             return;
         }
 
-        @SuppressWarnings("resource")
         final PrintWriter out = compiler.getEnv().getErr();
         out.println("[BLOCK in '" + ident + "']");
         if (!block.printSymbols(out)) {
@@ -3200,9 +3222,6 @@
                 return;
             }
 
-            //System.err.println("Store with out discard that shouldn't just return " + assignNode);
-            //new Throwable().printStackTrace();
-
             final Symbol symbol = assignNode.getSymbol();
             if (symbol.hasSlot()) {
                 method.dup().store(symbol);
@@ -3298,7 +3317,7 @@
         //    Such immediately-called functions are invoked using INVOKESTATIC (see enterFunctionNode() of the embedded
         //    visitor of enterCallNode() for details), and if they don't need a callee, they don't have it on their
         //    static method's parameter list.
-        if(lc.getOutermostFunction() == functionNode ||
+        if (lc.getOutermostFunction() == functionNode ||
                 (!functionNode.needsCallee()) && lc.isFunctionDefinedInCurrentCall(originalFunctionNode)) {
             return;
         }
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java
index 884a68b..bfc71cc 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java
@@ -21,6 +21,7 @@
 import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
 import jdk.nashorn.internal.ir.LexicalContext;
 import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.TemporarySymbols;
 import jdk.nashorn.internal.ir.debug.ASTWriter;
 import jdk.nashorn.internal.ir.debug.PrintVisitor;
 import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
@@ -42,7 +43,7 @@
      */
     LAZY_INITIALIZATION_PHASE(EnumSet.of(INITIALIZED, PARSED)) {
         @Override
-        FunctionNode transform(final Compiler compiler, final FunctionNode fn0) {
+        FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
 
             /*
              * For lazy compilation, we might be given a node previously marked
@@ -58,8 +59,7 @@
              * function from a trampoline
              */
 
-            final FunctionNode outermostFunctionNode = compiler.getFunctionNode();
-            assert outermostFunctionNode == fn0;
+            final FunctionNode outermostFunctionNode = fn;
 
             final Set<FunctionNode> neverLazy = new HashSet<>();
             final Set<FunctionNode> lazy      = new HashSet<>();
@@ -172,20 +172,31 @@
     ATTRIBUTION_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED, LOWERED)) {
         @Override
         FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
-            return (FunctionNode)initReturnTypes(fn).accept(new Attr());
+            final TemporarySymbols ts = compiler.getTemporarySymbols();
+            final FunctionNode newFunctionNode = (FunctionNode)enterAttr(fn, ts).accept(new Attr(ts));
+            if(compiler.getEnv()._print_mem_usage) {
+                Compiler.LOG.info("Attr temporary symbol count: " + ts.getTotalSymbolCount());
+            }
+            return newFunctionNode;
         }
 
         /**
          * Pessimistically set all lazy functions' return types to Object
+         * and the function symbols to object
          * @param functionNode node where to start iterating
          */
-        private FunctionNode initReturnTypes(final FunctionNode functionNode) {
+        private FunctionNode enterAttr(final FunctionNode functionNode, final TemporarySymbols ts) {
             return (FunctionNode)functionNode.accept(new NodeVisitor() {
                 @Override
                 public Node leaveFunctionNode(final FunctionNode node) {
-                    return node.isLazy() ?
-                           node.setReturnType(getLexicalContext(), Type.OBJECT) :
-                           node.setReturnType(getLexicalContext(), Type.UNKNOWN);
+                    final LexicalContext lc = getLexicalContext();
+                    if (node.isLazy()) {
+                        FunctionNode newNode = node.setReturnType(getLexicalContext(), Type.OBJECT);
+                        return ts.ensureSymbol(lc, Type.OBJECT, newNode);
+                    }
+                    //node may have a reference here that needs to be nulled if it was referred to by
+                    //its outer context, if it is lazy and not attributed
+                    return node.setReturnType(lc, Type.UNKNOWN).setSymbol(lc, null);
                 }
             });
         }
@@ -207,6 +218,7 @@
         FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
             final CompileUnit outermostCompileUnit = compiler.addCompileUnit(compiler.firstCompileUnitName());
 
+//            assert fn.isProgram() ;
             final FunctionNode newFunctionNode = new Splitter(compiler, fn, outermostCompileUnit).split(fn);
 
             assert newFunctionNode.getCompileUnit() == outermostCompileUnit : "fn.compileUnit (" + newFunctionNode.getCompileUnit() + ") != " + outermostCompileUnit;
@@ -216,15 +228,6 @@
                 compiler.setStrictMode(true);
             }
 
-            /*
-            newFunctionNode.accept(new NodeVisitor() {
-                @Override
-                public boolean enterFunctionNode(final FunctionNode functionNode) {
-                    assert functionNode.getCompileUnit() != null : functionNode.getName() + " " + Debug.id(functionNode) + " has no compile unit";
-                    return true;
-                }
-            });*/
-
             return newFunctionNode;
         }
 
@@ -252,7 +255,7 @@
         FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
             final ScriptEnvironment env = compiler.getEnv();
 
-            final FunctionNode newFunctionNode = (FunctionNode)fn.accept(new FinalizeTypes());
+            final FunctionNode newFunctionNode = (FunctionNode)fn.accept(new FinalizeTypes(compiler.getTemporarySymbols()));
 
             if (env._print_lower_ast) {
                 env.getErr().println(new ASTWriter(newFunctionNode));
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java
index b1e47d0..81a7618 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java
@@ -36,26 +36,32 @@
 import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
 import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS;
 
+import jdk.nashorn.internal.ir.TemporarySymbols;
+
 import java.io.File;
 import java.lang.reflect.Field;
 import java.security.AccessController;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.logging.Level;
-
 import jdk.internal.dynalink.support.NameCodec;
 import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
 import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.ir.FunctionNode;
 import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
+import jdk.nashorn.internal.ir.debug.ClassHistogramElement;
+import jdk.nashorn.internal.ir.debug.ObjectSizeCalculator;
 import jdk.nashorn.internal.runtime.CodeInstaller;
 import jdk.nashorn.internal.runtime.DebugLogger;
 import jdk.nashorn.internal.runtime.ScriptEnvironment;
@@ -77,6 +83,8 @@
     /** Name of the objects package */
     public static final String OBJECTS_PACKAGE = "jdk/nashorn/internal/objects";
 
+    private Source source;
+
     private final Map<String, byte[]> bytecode;
 
     private final Set<CompileUnit> compileUnits;
@@ -87,14 +95,14 @@
 
     private final ScriptEnvironment env;
 
-    private final String scriptName;
+    private String scriptName;
 
     private boolean strict;
 
-    private FunctionNode functionNode;
-
     private CodeInstaller<ScriptEnvironment> installer;
 
+    private final TemporarySymbols temporarySymbols = new TemporarySymbols();
+
     /** logger for compiler, trampolines, splits and related code generation events
      *  that affect classes */
     public static final DebugLogger LOG = new DebugLogger("compiler");
@@ -168,6 +176,41 @@
     }
 
     /**
+     * Environment information known to the compile, e.g. params
+     */
+    public static class Hints {
+        private final Type[] paramTypes;
+
+        /** singleton empty hints */
+        public static final Hints EMPTY = new Hints();
+
+        private Hints() {
+            this.paramTypes = null;
+        }
+
+        /**
+         * Constructor
+         * @param paramTypes known parameter types for this callsite
+         */
+        public Hints(final Type[] paramTypes) {
+            this.paramTypes = paramTypes;
+        }
+
+        /**
+         * Get the parameter type for this parameter position, or
+         * null if now known
+         * @param pos position
+         * @return parameter type for this callsite if known
+         */
+        public Type getParameterType(final int pos) {
+            if (paramTypes != null && pos < paramTypes.length) {
+                return paramTypes[pos];
+            }
+            return null;
+        }
+    }
+
+    /**
      * Standard (non-lazy) compilation, that basically will take an entire script
      * and JIT it at once. This can lead to long startup time and fewer type
      * specializations
@@ -207,21 +250,22 @@
      * @param strict       should this compilation use strict mode semantics
      */
     //TODO support an array of FunctionNodes for batch lazy compilation
-    Compiler(final ScriptEnvironment env, final CodeInstaller<ScriptEnvironment> installer, final FunctionNode functionNode, final CompilationSequence sequence, final boolean strict) {
+    Compiler(final ScriptEnvironment env, final CodeInstaller<ScriptEnvironment> installer, final CompilationSequence sequence, final boolean strict) {
         this.env           = env;
-        this.functionNode  = functionNode;
         this.sequence      = sequence;
         this.installer     = installer;
-        this.strict        = strict || functionNode.isStrict();
         this.constantData  = new ConstantData();
         this.compileUnits  = new HashSet<>();
         this.bytecode      = new HashMap<>();
+    }
 
+    private void initCompiler(final FunctionNode functionNode) {
+        this.strict        = strict || functionNode.isStrict();
         final StringBuilder sb = new StringBuilder();
         sb.append(functionNode.uniqueName(DEFAULT_SCRIPT_NAME.symbolName() + lazyTag(functionNode))).
                 append('$').
                 append(safeSourceName(functionNode.getSource()));
-
+        this.source = functionNode.getSource();
         this.scriptName = sb.toString();
     }
 
@@ -229,52 +273,79 @@
      * Constructor
      *
      * @param installer    code installer
-     * @param functionNode function node (in any available {@link CompilationState}) to compile
      * @param strict       should this compilation use strict mode semantics
      */
-    public Compiler(final CodeInstaller<ScriptEnvironment> installer, final FunctionNode functionNode, final boolean strict) {
-        this(installer.getOwner(), installer, functionNode, sequence(installer.getOwner()._lazy_compilation), strict);
+    public Compiler(final CodeInstaller<ScriptEnvironment> installer, final boolean strict) {
+        this(installer.getOwner(), installer, sequence(installer.getOwner()._lazy_compilation), strict);
     }
 
     /**
      * Constructor - compilation will use the same strict semantics as in script environment
      *
      * @param installer    code installer
-     * @param functionNode function node (in any available {@link CompilationState}) to compile
      */
-    public Compiler(final CodeInstaller<ScriptEnvironment> installer, final FunctionNode functionNode) {
-        this(installer.getOwner(), installer, functionNode, sequence(installer.getOwner()._lazy_compilation), installer.getOwner()._strict);
+    public Compiler(final CodeInstaller<ScriptEnvironment> installer) {
+        this(installer.getOwner(), installer, sequence(installer.getOwner()._lazy_compilation), installer.getOwner()._strict);
     }
 
     /**
      * Constructor - compilation needs no installer, but uses a script environment
      * Used in "compile only" scenarios
      * @param env a script environment
-     * @param functionNode functionNode to compile
      */
-    public Compiler(final ScriptEnvironment env, final FunctionNode functionNode) {
-        this(env, null, functionNode, sequence(env._lazy_compilation), env._strict);
+    public Compiler(final ScriptEnvironment env) {
+        this(env, null, sequence(env._lazy_compilation), env._strict);
+    }
+
+    private static void printMemoryUsage(final String phaseName, final FunctionNode functionNode) {
+        LOG.info(phaseName + " finished. Doing IR size calculation...");
+
+        final ObjectSizeCalculator osc = new ObjectSizeCalculator(ObjectSizeCalculator.getEffectiveMemoryLayoutSpecification());
+        osc.calculateObjectSize(functionNode);
+
+        final List<ClassHistogramElement> list = osc.getClassHistogram();
+
+        final StringBuilder sb = new StringBuilder();
+        final long totalSize = osc.calculateObjectSize(functionNode);
+        sb.append(phaseName).append(" Total size = ").append(totalSize / 1024 / 1024).append("MB");
+        LOG.info(sb);
+
+        Collections.sort(list, new Comparator<ClassHistogramElement>() {
+            @Override
+            public int compare(ClassHistogramElement o1, ClassHistogramElement o2) {
+                final long diff = o1.getBytes() - o2.getBytes();
+                if (diff < 0) {
+                    return 1;
+                } else if (diff > 0) {
+                    return -1;
+                } else {
+                    return 0;
+                }
+            }
+        });
+        for (final ClassHistogramElement e : list) {
+            final String line = String.format("    %-48s %10d bytes (%8d instances)", e.getClazz(), e.getBytes(), e.getInstances());
+            LOG.info(line);
+            if (e.getBytes() < totalSize / 200) {
+                LOG.info("    ...");
+                break; // never mind, so little memory anyway
+            }
+        }
     }
 
     /**
      * Execute the compilation this Compiler was created with
-     * @params param types if known, for specialization
+     * @param functionNode function node to compile from its current state
      * @throws CompilationException if something goes wrong
      * @return function node that results from code transforms
      */
-    public FunctionNode compile() throws CompilationException {
-        return compile(null);
-    }
+    public FunctionNode compile(final FunctionNode functionNode) throws CompilationException {
+        FunctionNode newFunctionNode = functionNode;
 
-    /**
-     * Execute the compilation this Compiler was created with
-     * @param paramTypes param types if known, for specialization
-     * @throws CompilationException if something goes wrong
-     * @return function node that results from code transforms
-     */
-    public FunctionNode compile(final Class<?> paramTypes) throws CompilationException {
+        initCompiler(newFunctionNode); //TODO move this state into functionnode?
+
         for (final String reservedName : RESERVED_NAMES) {
-            functionNode.uniqueName(reservedName);
+            newFunctionNode.uniqueName(reservedName);
         }
 
         final boolean fine = !LOG.levelAbove(Level.FINE);
@@ -283,7 +354,11 @@
         long time = 0L;
 
         for (final CompilationPhase phase : sequence) {
-            this.functionNode = phase.apply(this, functionNode);
+            newFunctionNode = phase.apply(this, newFunctionNode);
+
+            if (env._print_mem_usage) {
+                printMemoryUsage(phase.toString(), newFunctionNode);
+            }
 
             final long duration = Timing.isEnabled() ? (phase.getEndTime() - phase.getStartTime()) : 0L;
             time += duration;
@@ -293,7 +368,7 @@
 
                 sb.append(phase.toString()).
                     append(" done for function '").
-                    append(functionNode.getName()).
+                    append(newFunctionNode.getName()).
                     append('\'');
 
                 if (duration > 0L) {
@@ -309,7 +384,7 @@
         if (info) {
             final StringBuilder sb = new StringBuilder();
             sb.append("Compile job for '").
-                append(functionNode.getName()).
+                append(newFunctionNode.getName()).
                 append("' finished");
 
             if (time > 0L) {
@@ -321,7 +396,7 @@
             LOG.info(sb);
         }
 
-        return functionNode;
+        return newFunctionNode;
     }
 
     private Class<?> install(final String className, final byte[] code) {
@@ -330,7 +405,6 @@
         final Class<?> clazz = installer.install(Compiler.binaryName(className), code);
 
         try {
-            final Source   source    = getSource();
             final Object[] constants = getConstantData().toArray();
             // Need doPrivileged because these fields are private
             AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
@@ -355,9 +429,10 @@
 
     /**
      * Install compiled classes into a given loader
+     * @param functionNode function node to install - must be in {@link CompilationState#EMITTED} state
      * @return root script class - if there are several compile units they will also be installed
      */
-    public Class<?> install() {
+    public Class<?> install(final FunctionNode functionNode) {
         final long t0 = Timing.isEnabled() ? System.currentTimeMillis() : 0L;
 
         assert functionNode.hasState(CompilationState.EMITTED) : functionNode.getName() + " has no bytecode and cannot be installed";
@@ -430,10 +505,6 @@
         this.strict = strict;
     }
 
-    FunctionNode getFunctionNode() {
-        return functionNode;
-    }
-
     ConstantData getConstantData() {
         return constantData;
     }
@@ -442,8 +513,8 @@
         return installer;
     }
 
-    Source getSource() {
-        return functionNode.getSource();
+    TemporarySymbols getTemporarySymbols() {
+        return temporarySymbols;
     }
 
     void addClass(final String name, final byte[] code) {
@@ -496,7 +567,7 @@
     }
 
     private CompileUnit initCompileUnit(final String unitClassName, final long initialWeight) {
-        final ClassEmitter classEmitter = new ClassEmitter(env, functionNode.getSource().getName(), unitClassName, strict);
+        final ClassEmitter classEmitter = new ClassEmitter(env, source.getName(), unitClassName, strict);
         final CompileUnit  compileUnit  = new CompileUnit(unitClassName, classEmitter, initialWeight);
 
         classEmitter.begin();
@@ -550,6 +621,4 @@
         USE_INT_ARITH  =  Options.getBooleanProperty("nashorn.compiler.intarithmetic");
         assert !USE_INT_ARITH : "Integer arithmetic is not enabled";
     }
-
-
 }
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java b/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java
index dfc9198..6912534 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java
@@ -105,25 +105,25 @@
     ARGUMENTS("arguments", Object.class, 2),
 
     /** prefix for iterators for for (x in ...) */
-    ITERATOR_PREFIX(":iter"),
+    ITERATOR_PREFIX(":i"),
 
     /** prefix for tag variable used for switch evaluation */
-    SWITCH_TAG_PREFIX(":tag"),
+    SWITCH_TAG_PREFIX(":s"),
 
     /** prefix for all exceptions */
-    EXCEPTION_PREFIX(":exception"),
+    EXCEPTION_PREFIX(":e"),
 
     /** prefix for quick slots generated in Store */
-    QUICK_PREFIX(":quick"),
+    QUICK_PREFIX(":q"),
 
     /** prefix for temporary variables */
-    TEMP_PREFIX(":temp"),
+    TEMP_PREFIX(":t"),
 
     /** prefix for literals */
-    LITERAL_PREFIX(":lit"),
+    LITERAL_PREFIX(":l"),
 
     /** prefix for regexps */
-    REGEX_PREFIX(":regex"),
+    REGEX_PREFIX(":r"),
 
     /** "this" used in non-static Java methods; always in slot 0 */
     JAVA_THIS(null, 0),
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java b/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java
index 5f6a63d..e94dab7 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java
@@ -30,7 +30,6 @@
 
 import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.ir.AccessNode;
@@ -56,6 +55,7 @@
 import jdk.nashorn.internal.ir.RuntimeNode.Request;
 import jdk.nashorn.internal.ir.SwitchNode;
 import jdk.nashorn.internal.ir.Symbol;
+import jdk.nashorn.internal.ir.TemporarySymbols;
 import jdk.nashorn.internal.ir.TernaryNode;
 import jdk.nashorn.internal.ir.ThrowNode;
 import jdk.nashorn.internal.ir.TypeOverride;
@@ -88,7 +88,10 @@
 
     private static final DebugLogger LOG = new DebugLogger("finalize");
 
-    FinalizeTypes() {
+    private final TemporarySymbols temporarySymbols;
+
+    FinalizeTypes(final TemporarySymbols temporarySymbols) {
+        this.temporarySymbols = temporarySymbols;
     }
 
     @Override
@@ -228,21 +231,27 @@
         return leaveASSIGN(binaryNode);
     }
 
+    private boolean symbolIsInteger(Node node) {
+        final Symbol symbol = node.getSymbol();
+        assert symbol != null && symbol.getSymbolType().isInteger() : "int coercion expected: " + Debug.id(symbol) + " " + symbol + " " + getLexicalContext().getCurrentFunction().getSource();
+        return true;
+    }
+
     @Override
-    public Node leaveBIT_AND(BinaryNode binaryNode) {
-        assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isInteger() : "int coercion expected: " + binaryNode.getSymbol();
+    public Node leaveBIT_AND(final BinaryNode binaryNode) {
+        assert symbolIsInteger(binaryNode);
         return leaveBinary(binaryNode, Type.INT, Type.INT);
     }
 
     @Override
-    public Node leaveBIT_OR(BinaryNode binaryNode) {
-        assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isInteger() : "int coercion expected: " + binaryNode.getSymbol();
+    public Node leaveBIT_OR(final BinaryNode binaryNode) {
+        assert symbolIsInteger(binaryNode);
         return leaveBinary(binaryNode, Type.INT, Type.INT);
     }
 
     @Override
-    public Node leaveBIT_XOR(BinaryNode binaryNode) {
-        assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isInteger() : "int coercion expected: " + binaryNode.getSymbol();
+    public Node leaveBIT_XOR(final BinaryNode binaryNode) {
+        assert symbolIsInteger(binaryNode);
         return leaveBinary(binaryNode, Type.INT, Type.INT);
     }
 
@@ -252,8 +261,7 @@
         final BinaryNode newBinaryNode = binaryNode.setRHS(discard(binaryNode.rhs()));
         // AccessSpecializer - the type of lhs, which is the remaining value of this node may have changed
         // in that case, update the node type as well
-        propagateType(newBinaryNode, newBinaryNode.lhs().getType());
-        return newBinaryNode;
+        return propagateType(newBinaryNode, newBinaryNode.lhs().getType());
     }
 
     @Override
@@ -262,8 +270,7 @@
         final BinaryNode newBinaryNode = binaryNode.setLHS(discard(binaryNode.lhs()));
         // AccessSpecializer - the type of rhs, which is the remaining value of this node may have changed
         // in that case, update the node type as well
-        propagateType(newBinaryNode, newBinaryNode.rhs().getType());
-        return newBinaryNode;
+        return propagateType(newBinaryNode, newBinaryNode.rhs().getType());
     }
 
     @Override
@@ -354,13 +361,6 @@
         return true;
     }
 
-    /*
-    @Override
-    public Node leaveBlock(final Block block) {
-        final LexicalContext lc = getLexicalContext();
-        return block;//.setFlag(lc, lc.getFlags(block));
-    }*/
-
     @Override
     public Node leaveCatchNode(final CatchNode catchNode) {
         final Node exceptionCondition = catchNode.getExceptionCondition();
@@ -372,6 +372,7 @@
 
     @Override
     public Node leaveExecuteNode(final ExecuteNode executeNode) {
+        temporarySymbols.reuse();
         return executeNode.setExpression(discard(executeNode.getExpression()));
     }
 
@@ -497,8 +498,8 @@
 
     @Override
     public Node leaveVarNode(final VarNode varNode) {
-        final Node rhs = varNode.getInit();
-        if (rhs != null) {
+        final Node init = varNode.getInit();
+        if (init != null) {
             final SpecializedNode specialized = specialize(varNode);
             final VarNode specVarNode = (VarNode)specialized.node;
             Type destType = specialized.type;
@@ -506,8 +507,11 @@
                 destType = specVarNode.getType();
             }
             assert specVarNode.hasType() : specVarNode + " doesn't have a type";
-            return specVarNode.setInit(convert(rhs, destType));
+            final Node convertedInit = convert(init, destType);
+            temporarySymbols.reuse();
+            return specVarNode.setInit(convertedInit);
         }
+        temporarySymbols.reuse();
         return varNode;
     }
 
@@ -551,8 +555,7 @@
         final boolean        allVarsInScope = functionNode.allVarsInScope();
         final boolean        isVarArg       = functionNode.isVarArg();
 
-        for (final Iterator<Symbol> iter = block.symbolIterator(); iter.hasNext(); ) {
-            final Symbol symbol = iter.next();
+        for (final Symbol symbol : block.getSymbols()) {
             if (symbol.isInternal() || symbol.isThis() || symbol.isTemp()) {
                 continue;
             }
@@ -687,7 +690,7 @@
         }
     }
 
-    private static <T extends Node> SpecializedNode specialize(final Assignment<T> assignment) {
+    <T extends Node> SpecializedNode specialize(final Assignment<T> assignment) {
         final Node node = ((Node)assignment);
         final T lhs = assignment.getAssignmentDest();
         final Node rhs = assignment.getAssignmentSource();
@@ -709,9 +712,9 @@
         }
 
         final Node newNode = assignment.setAssignmentDest(setTypeOverride(lhs, to));
-        propagateType(newNode, to);
+        final Node typePropagatedNode = propagateType(newNode, to);
 
-        return new SpecializedNode(newNode, to);
+        return new SpecializedNode(typePropagatedNode, to);
     }
 
 
@@ -750,7 +753,7 @@
      * @param to      new type
      */
     @SuppressWarnings("unchecked")
-    private static <T extends Node> T setTypeOverride(final T node, final Type to) {
+    <T extends Node> T setTypeOverride(final T node, final Type to) {
         final Type from = node.getType();
         if (!node.getType().equals(to)) {
             LOG.info("Changing call override type for '", node, "' from ", node.getType(), " to ", to);
@@ -759,7 +762,7 @@
             }
         }
         LOG.info("Type override for lhs in '", node, "' => ", to);
-        return ((TypeOverride<T>)node).setType(to);
+        return ((TypeOverride<T>)node).setType(temporarySymbols, getLexicalContext(), to);
     }
 
     /**
@@ -782,7 +785,7 @@
     private Node convert(final Node node, final Type to) {
         assert !to.isUnknown() : "unknown type for " + node + " class=" + node.getClass();
         assert node != null : "node is null";
-        assert node.getSymbol() != null : "node " + node + " " + node.getClass() + " has no symbol! " + getLexicalContext().getCurrentFunction() + " " + node.getSource();
+        assert node.getSymbol() != null : "node " + node + " " + node.getClass() + " has no symbol! " + getLexicalContext().getCurrentFunction();
         assert node.tokenType() != TokenType.CONVERT : "assert convert in convert " + node + " in " + getLexicalContext().getCurrentFunction();
 
         final Type from = node.getType();
@@ -807,24 +810,22 @@
                 assert node instanceof TypeOverride;
                 return setTypeOverride(node, to);
             }
-            resultNode = new UnaryNode(node.getSource(), Token.recast(node.getToken(), TokenType.CONVERT), node);
+            resultNode = new UnaryNode(Token.recast(node.getToken(), TokenType.CONVERT), node);
         }
 
         LOG.info("CONVERT('", node, "', ", to, ") => '", resultNode, "'");
 
+        assert !node.isTerminal();
+
         final LexicalContext lc = getLexicalContext();
         //This is the only place in this file that can create new temporaries
         //FinalizeTypes may not introduce ANY node that is not a conversion.
-        lc.getCurrentFunction().ensureSymbol(lc.getCurrentBlock(), to, resultNode);
-
-        assert !node.isTerminal();
-
-        return resultNode;
+        return temporarySymbols.ensureSymbol(lc, to, resultNode);
     }
 
     private static Node discard(final Node node) {
         if (node.getSymbol() != null) {
-            final Node discard = new UnaryNode(node.getSource(), Token.recast(node.getToken(), TokenType.DISCARD), node);
+            final Node discard = new UnaryNode(Token.recast(node.getToken(), TokenType.DISCARD), node);
             //discard never has a symbol in the discard node - then it would be a nop
             assert !node.isTerminal();
             return discard;
@@ -847,12 +848,13 @@
      * @param node
      * @param to
      */
-    private static void propagateType(final Node node, final Type to) {
-        final Symbol symbol = node.getSymbol();
-        if (symbol.isTemp()) {
-            symbol.setTypeOverride(to);
+    private Node propagateType(final Node node, final Type to) {
+        Symbol symbol = node.getSymbol();
+        if (symbol.isTemp() && symbol.getSymbolType() != to) {
+            symbol = symbol.setTypeOverrideShared(to, temporarySymbols);
             LOG.info("Type override for temporary in '", node, "' => ", to);
         }
+        return node.setSymbol(getLexicalContext(), symbol);
     }
 
     /**
@@ -877,7 +879,7 @@
      * Whenever an explicit conversion is needed and the convertee is a literal, we can
      * just change the literal
      */
-    static class LiteralNodeConstantEvaluator extends FoldConstants.ConstantEvaluator<LiteralNode<?>> {
+    class LiteralNodeConstantEvaluator extends FoldConstants.ConstantEvaluator<LiteralNode<?>> {
         private final Type type;
 
         LiteralNodeConstantEvaluator(final LiteralNode<?> parent, final Type type) {
@@ -892,20 +894,20 @@
             LiteralNode<?> literalNode = null;
 
             if (type.isString()) {
-                literalNode = LiteralNode.newInstance(source, token, finish, JSType.toString(value));
+                literalNode = LiteralNode.newInstance(token, finish, JSType.toString(value));
             } else if (type.isBoolean()) {
-                literalNode = LiteralNode.newInstance(source, token, finish, JSType.toBoolean(value));
+                literalNode = LiteralNode.newInstance(token, finish, JSType.toBoolean(value));
             } else if (type.isInteger()) {
-                literalNode = LiteralNode.newInstance(source, token, finish, JSType.toInt32(value));
+                literalNode = LiteralNode.newInstance(token, finish, JSType.toInt32(value));
             } else if (type.isLong()) {
-                literalNode = LiteralNode.newInstance(source, token, finish, JSType.toLong(value));
+                literalNode = LiteralNode.newInstance(token, finish, JSType.toLong(value));
             } else if (type.isNumber() || parent.getType().isNumeric() && !parent.getType().isNumber()) {
-                literalNode = LiteralNode.newInstance(source, token, finish, JSType.toNumber(value));
+                literalNode = LiteralNode.newInstance(token, finish, JSType.toNumber(value));
             }
 
             if (literalNode != null) {
                 //inherit literal symbol for attr.
-                literalNode.setSymbol(parent.getSymbol());
+                literalNode = (LiteralNode<?>)literalNode.setSymbol(getLexicalContext(), parent.getSymbol());
             }
 
             return literalNode;
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java b/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java
index 03accb4..686c983 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java
@@ -41,7 +41,6 @@
 import jdk.nashorn.internal.runtime.DebugLogger;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * Simple constant folding pass, executed before IR is starting to be lowered.
@@ -89,7 +88,7 @@
         if (test instanceof LiteralNode) {
             final Block shortCut = ((LiteralNode<?>)test).isTrue() ? ifNode.getPass() : ifNode.getFail();
             if (shortCut != null) {
-                return new ExecuteNode(shortCut);
+                return new ExecuteNode(shortCut.getLineNumber(), shortCut.getToken(), shortCut.getFinish(), shortCut);
             }
             return new EmptyNode(ifNode);
         }
@@ -112,13 +111,11 @@
      */
     abstract static class ConstantEvaluator<T extends Node> {
         protected T            parent;
-        protected final Source source;
         protected final long   token;
         protected final int    finish;
 
         protected ConstantEvaluator(final T parent) {
             this.parent = parent;
-            this.source = parent.getSource();
             this.token  = parent.getToken();
             this.finish = parent.getFinish();
         }
@@ -152,23 +149,23 @@
             switch (parent.tokenType()) {
             case ADD:
                 if (rhsInteger) {
-                    literalNode = LiteralNode.newInstance(source, token, finish, rhs.getInt32());
+                    literalNode = LiteralNode.newInstance(token, finish, rhs.getInt32());
                 } else {
-                    literalNode = LiteralNode.newInstance(source, token, finish, rhs.getNumber());
+                    literalNode = LiteralNode.newInstance(token, finish, rhs.getNumber());
                 }
                 break;
             case SUB:
                 if (rhsInteger && rhs.getInt32() != 0) { // @see test/script/basic/minuszero.js
-                    literalNode = LiteralNode.newInstance(source, token, finish, -rhs.getInt32());
+                    literalNode = LiteralNode.newInstance(token, finish, -rhs.getInt32());
                 } else {
-                    literalNode = LiteralNode.newInstance(source, token, finish, -rhs.getNumber());
+                    literalNode = LiteralNode.newInstance(token, finish, -rhs.getNumber());
                 }
                 break;
             case NOT:
-                literalNode = LiteralNode.newInstance(source, token, finish, !rhs.getBoolean());
+                literalNode = LiteralNode.newInstance(token, finish, !rhs.getBoolean());
                 break;
             case BIT_NOT:
-                literalNode = LiteralNode.newInstance(source, token, finish, ~rhs.getInt32());
+                literalNode = LiteralNode.newInstance(token, finish, ~rhs.getInt32());
                 break;
             default:
                 return null;
@@ -234,7 +231,7 @@
                         break;
                     }
                     assert res instanceof CharSequence : res + " was not a CharSequence, it was a " + res.getClass();
-                    return LiteralNode.newInstance(source, token, finish, res.toString());
+                    return LiteralNode.newInstance(token, finish, res.toString());
                 }
                 return null;
             case MUL:
@@ -247,33 +244,33 @@
                 value = lhs.getNumber() - rhs.getNumber();
                 break;
             case SHR:
-                return LiteralNode.newInstance(source, token, finish, (lhs.getInt32() >>> rhs.getInt32()) & JSType.MAX_UINT);
+                return LiteralNode.newInstance(token, finish, (lhs.getInt32() >>> rhs.getInt32()) & JSType.MAX_UINT);
             case SAR:
-                return LiteralNode.newInstance(source, token, finish, lhs.getInt32() >> rhs.getInt32());
+                return LiteralNode.newInstance(token, finish, lhs.getInt32() >> rhs.getInt32());
             case SHL:
-                return LiteralNode.newInstance(source, token, finish, lhs.getInt32() << rhs.getInt32());
+                return LiteralNode.newInstance(token, finish, lhs.getInt32() << rhs.getInt32());
             case BIT_XOR:
-                return LiteralNode.newInstance(source, token, finish, lhs.getInt32() ^ rhs.getInt32());
+                return LiteralNode.newInstance(token, finish, lhs.getInt32() ^ rhs.getInt32());
             case BIT_AND:
-                return LiteralNode.newInstance(source, token, finish, lhs.getInt32() & rhs.getInt32());
+                return LiteralNode.newInstance(token, finish, lhs.getInt32() & rhs.getInt32());
             case BIT_OR:
-                return LiteralNode.newInstance(source, token, finish, lhs.getInt32() | rhs.getInt32());
+                return LiteralNode.newInstance(token, finish, lhs.getInt32() | rhs.getInt32());
             case GE:
-                return LiteralNode.newInstance(source, token, finish, ScriptRuntime.GE(lhs.getObject(), rhs.getObject()));
+                return LiteralNode.newInstance(token, finish, ScriptRuntime.GE(lhs.getObject(), rhs.getObject()));
             case LE:
-                return LiteralNode.newInstance(source, token, finish, ScriptRuntime.LE(lhs.getObject(), rhs.getObject()));
+                return LiteralNode.newInstance(token, finish, ScriptRuntime.LE(lhs.getObject(), rhs.getObject()));
             case GT:
-                return LiteralNode.newInstance(source, token, finish, ScriptRuntime.GT(lhs.getObject(), rhs.getObject()));
+                return LiteralNode.newInstance(token, finish, ScriptRuntime.GT(lhs.getObject(), rhs.getObject()));
             case LT:
-                return LiteralNode.newInstance(source, token, finish, ScriptRuntime.LT(lhs.getObject(), rhs.getObject()));
+                return LiteralNode.newInstance(token, finish, ScriptRuntime.LT(lhs.getObject(), rhs.getObject()));
             case NE:
-                return LiteralNode.newInstance(source, token, finish, ScriptRuntime.NE(lhs.getObject(), rhs.getObject()));
+                return LiteralNode.newInstance(token, finish, ScriptRuntime.NE(lhs.getObject(), rhs.getObject()));
             case NE_STRICT:
-                return LiteralNode.newInstance(source, token, finish, ScriptRuntime.NE_STRICT(lhs.getObject(), rhs.getObject()));
+                return LiteralNode.newInstance(token, finish, ScriptRuntime.NE_STRICT(lhs.getObject(), rhs.getObject()));
             case EQ:
-                return LiteralNode.newInstance(source, token, finish, ScriptRuntime.EQ(lhs.getObject(), rhs.getObject()));
+                return LiteralNode.newInstance(token, finish, ScriptRuntime.EQ(lhs.getObject(), rhs.getObject()));
             case EQ_STRICT:
-                return LiteralNode.newInstance(source, token, finish, ScriptRuntime.EQ_STRICT(lhs.getObject(), rhs.getObject()));
+                return LiteralNode.newInstance(token, finish, ScriptRuntime.EQ_STRICT(lhs.getObject(), rhs.getObject()));
             default:
                 return null;
             }
@@ -282,12 +279,12 @@
             isLong    &= value != 0.0 && JSType.isRepresentableAsLong(value);
 
             if (isInteger) {
-                return LiteralNode.newInstance(source, token, finish, JSType.toInt32(value));
+                return LiteralNode.newInstance(token, finish, JSType.toInt32(value));
             } else if (isLong) {
-                return LiteralNode.newInstance(source, token, finish, JSType.toLong(value));
+                return LiteralNode.newInstance(token, finish, JSType.toLong(value));
             }
 
-            return LiteralNode.newInstance(source, token, finish, value);
+            return LiteralNode.newInstance(token, finish, value);
         }
     }
 }
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Label.java b/nashorn/src/jdk/nashorn/internal/codegen/Label.java
index 9d28caa..be1e126 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/Label.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Label.java
@@ -24,9 +24,8 @@
  */
 package jdk.nashorn.internal.codegen;
 
-import java.util.ArrayDeque;
-
 import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.runtime.Debug;
 
 /**
  * Abstraction for labels, separating a label from the underlying
@@ -35,12 +34,87 @@
  *
  * see -Dnashorn.codegen.debug, --log=codegen
  */
-public class Label extends jdk.internal.org.objectweb.asm.Label {
+public final class Label {
+    //byte code generation evaluation type stack for consistency check
+    //and correct opcode selection. one per label as a label may be a
+    //join point
+    static final class Stack {
+        Type[] data = new Type[8];
+        int sp = 0;
+
+        Stack() {
+        }
+
+        private Stack(final Type[] type, final int sp) {
+            this();
+            this.data = new Type[type.length];
+            this.sp   = sp;
+            for (int i = 0; i < sp; i++) {
+                data[i] = type[i];
+            }
+        }
+
+        boolean isEmpty() {
+            return sp == 0;
+        }
+
+        int size() {
+            return sp;
+        }
+
+        boolean isEquivalentTo(final Stack other) {
+            if (sp != other.sp) {
+                return false;
+            }
+            for (int i = 0; i < sp; i++) {
+                if (!data[i].isEquivalentTo(other.data[i])) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        void clear() {
+            sp = 0;
+        }
+
+        void push(final Type type) {
+            if (data.length == sp) {
+                final Type[] newData = new Type[sp * 2];
+                for (int i = 0; i < sp; i++) {
+                    newData[i] = data[i];
+                }
+                data = newData;
+            }
+            data[sp++] = type;
+        }
+
+        Type peek() {
+            return peek(0);
+        }
+
+        Type peek(final int n) {
+            int pos = sp - 1 - n;
+            return pos < 0 ? null : data[pos];
+        }
+
+        Type pop() {
+            return data[--sp];
+        }
+
+        Stack copy() {
+            return new Stack(data, sp);
+        }
+    }
+
     /** Name of this label */
     private final String name;
 
     /** Type stack at this label */
-    private ArrayDeque<Type> stack;
+    private Label.Stack stack;
+
+    /** ASM representation of this label */
+    private jdk.internal.org.objectweb.asm.Label label;
 
     /**
      * Constructor
@@ -62,22 +136,24 @@
         this.name = label.name;
     }
 
-    ArrayDeque<Type> getStack() {
+
+    jdk.internal.org.objectweb.asm.Label getLabel() {
+        if (this.label == null) {
+            this.label = new jdk.internal.org.objectweb.asm.Label();
+        }
+        return label;
+    }
+
+    Label.Stack getStack() {
         return stack;
     }
 
-    void setStack(final ArrayDeque<Type> stack) {
+    void setStack(final Label.Stack stack) {
         this.stack = stack;
     }
 
     @Override
     public String toString() {
-        final StringBuilder sb = new StringBuilder();
-        String s = super.toString();
-        s = s.substring(1, s.length());
-        sb.append(name).append('_').append(Long.toHexString(Long.parseLong(s)));
-
-        return sb.toString();
+        return name + '_' + Debug.id(this);
     }
 }
-
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java
index d6209e4..23e91b6 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java
@@ -32,6 +32,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+
 import jdk.nashorn.internal.ir.BaseNode;
 import jdk.nashorn.internal.ir.BinaryNode;
 import jdk.nashorn.internal.ir.Block;
@@ -49,16 +50,15 @@
 import jdk.nashorn.internal.ir.IfNode;
 import jdk.nashorn.internal.ir.LabelNode;
 import jdk.nashorn.internal.ir.LexicalContext;
-import jdk.nashorn.internal.ir.LineNumberNode;
 import jdk.nashorn.internal.ir.LiteralNode;
 import jdk.nashorn.internal.ir.LoopNode;
 import jdk.nashorn.internal.ir.Node;
 import jdk.nashorn.internal.ir.ReturnNode;
+import jdk.nashorn.internal.ir.Statement;
 import jdk.nashorn.internal.ir.SwitchNode;
 import jdk.nashorn.internal.ir.Symbol;
 import jdk.nashorn.internal.ir.ThrowNode;
 import jdk.nashorn.internal.ir.TryNode;
-import jdk.nashorn.internal.ir.UnaryNode;
 import jdk.nashorn.internal.ir.VarNode;
 import jdk.nashorn.internal.ir.WhileNode;
 import jdk.nashorn.internal.ir.WithNode;
@@ -93,21 +93,25 @@
         super(new BlockLexicalContext() {
 
             @Override
-            public List<Node> popStatements() {
-                List<Node> newStatements = new ArrayList<>();
+            public List<Statement> popStatements() {
+                final List<Statement> newStatements = new ArrayList<>();
                 boolean terminated = false;
 
-                final List<Node> statements = super.popStatements();
-                for (final Node statement : statements) {
+                final List<Statement> statements = super.popStatements();
+                for (final Statement statement : statements) {
                     if (!terminated) {
                         newStatements.add(statement);
-                        if (statement.isTerminal()) {
+                        if (statement.isTerminal() || statement instanceof BreakNode || statement instanceof ContinueNode) { //TODO hasGoto? But some Loops are hasGoto too - why?
                             terminated = true;
                         }
                     } else {
-                        if (statement instanceof VarNode) {
-                            newStatements.add(((VarNode)statement).setInit(null));
-                        }
+                        statement.accept(new NodeVisitor() {
+                            @Override
+                            public boolean enterVarNode(final VarNode varNode) {
+                                newStatements.add(varNode.setInit(null));
+                                return false;
+                            }
+                        });
                     }
                 }
                 return newStatements;
@@ -118,8 +122,9 @@
     @Override
     public boolean enterBlock(final Block block) {
         final LexicalContext lc = getLexicalContext();
-        if (lc.isFunctionBody() && lc.getCurrentFunction().isProgram() && !lc.getCurrentFunction().hasDeclaredFunctions()) {
-            new ExecuteNode(block.getSource(), block.getToken(), block.getFinish(), LiteralNode.newInstance(block, ScriptRuntime.UNDEFINED)).accept(this);
+        final FunctionNode   function = lc.getCurrentFunction();
+        if (lc.isFunctionBody() && function.isProgram() && !function.hasDeclaredFunctions()) {
+            new ExecuteNode(block.getLineNumber(), block.getToken(), block.getFinish(), LiteralNode.newInstance(block, ScriptRuntime.UNDEFINED)).accept(this);
         }
         return true;
     }
@@ -131,20 +136,20 @@
 
         final BlockLexicalContext lc = (BlockLexicalContext)getLexicalContext();
 
-        Node last = lc.getLastStatement();
+        Statement last = lc.getLastStatement();
 
         if (lc.isFunctionBody()) {
             final FunctionNode currentFunction = getLexicalContext().getCurrentFunction();
             final boolean isProgram = currentFunction.isProgram();
             final ReturnNode returnNode = new ReturnNode(
-                currentFunction.getSource(),
+                last == null ? block.getLineNumber() : last.getLineNumber(), //TODO?
                 currentFunction.getToken(),
                 currentFunction.getFinish(),
                 isProgram ?
                     compilerConstant(RETURN) :
                     LiteralNode.newInstance(block, ScriptRuntime.UNDEFINED));
 
-            last = returnNode.accept(this);
+            last = (Statement)returnNode.accept(this);
         }
 
         if (last != null && last.isTerminal()) {
@@ -193,7 +198,6 @@
                 if (!isInternalExpression(expr) && !isEvalResultAssignment(expr)) {
                     node = executeNode.setExpression(
                         new BinaryNode(
-                            executeNode.getSource(),
                             Token.recast(
                                 executeNode.getToken(),
                                 TokenType.ASSIGN),
@@ -240,12 +244,6 @@
     }
 
     @Override
-    public boolean enterLineNumberNode(final LineNumberNode lineNumberNode) {
-        addStatement(lineNumberNode); // don't put it in lastStatement cache
-        return false;
-    }
-
-    @Override
     public Node leaveReturnNode(final ReturnNode returnNode) {
         addStatement(returnNode); //ReturnNodes are always terminal, marked as such in constructor
         return returnNode;
@@ -272,10 +270,10 @@
         });
     }
 
-    private static List<Node> copyFinally(final Block finallyBody) {
-        final List<Node> newStatements = new ArrayList<>();
-        for (final Node statement : finallyBody.getStatements()) {
-            newStatements.add(ensureUniqueLabelsIn(statement));
+    private static List<Statement> copyFinally(final Block finallyBody) {
+        final List<Statement> newStatements = new ArrayList<>();
+        for (final Statement statement : finallyBody.getStatements()) {
+            newStatements.add((Statement)ensureUniqueLabelsIn(statement));
             if (statement.hasTerminalFlags()) {
                 return newStatements;
             }
@@ -284,17 +282,17 @@
     }
 
     private Block catchAllBlock(final TryNode tryNode) {
-        final Source source = tryNode.getSource();
-        final long   token  = tryNode.getToken();
-        final int    finish = tryNode.getFinish();
+        final int  lineNumber = tryNode.getLineNumber();
+        final long token      = tryNode.getToken();
+        final int  finish     = tryNode.getFinish();
 
-        final IdentNode exception = new IdentNode(source, token, finish, getLexicalContext().getCurrentFunction().uniqueName("catch_all"));
+        final IdentNode exception = new IdentNode(token, finish, getLexicalContext().getCurrentFunction().uniqueName("catch_all"));
 
-        final Block catchBody = new Block(source, token, finish, new ThrowNode(source, token, finish, new IdentNode(exception))).
+        final Block catchBody = new Block(lineNumber, token, finish, new ThrowNode(lineNumber, token, finish, new IdentNode(exception))).
                 setIsTerminal(getLexicalContext(), true); //ends with throw, so terminal
 
-        final CatchNode catchAllNode  = new CatchNode(source, token, finish, new IdentNode(exception), null, catchBody);
-        final Block     catchAllBlock = new Block(source, token, finish, catchAllNode);
+        final CatchNode catchAllNode  = new CatchNode(lineNumber, token, finish, new IdentNode(exception), null, catchBody);
+        final Block     catchAllBlock = new Block(lineNumber, token, finish, catchAllNode);
 
         //catchallblock -> catchallnode (catchnode) -> exception -> throw
 
@@ -303,10 +301,10 @@
 
     private IdentNode compilerConstant(final CompilerConstants cc) {
         final FunctionNode functionNode = getLexicalContext().getCurrentFunction();
-        return new IdentNode(functionNode.getSource(), functionNode.getToken(), functionNode.getFinish(), cc.symbolName());
+        return new IdentNode(functionNode.getToken(), functionNode.getFinish(), cc.symbolName());
     }
 
-    private static boolean isTerminal(final List<Node> statements) {
+    private static boolean isTerminal(final List<Statement> statements) {
         return !statements.isEmpty() && statements.get(statements.size() - 1).hasTerminalFlags();
     }
 
@@ -318,8 +316,7 @@
      * @return new try node after splicing finally code (same if nop)
      */
     private Node spliceFinally(final TryNode tryNode, final List<ThrowNode> rethrows, final Block finallyBody) {
-        final Source source = tryNode.getSource();
-        final int    finish = tryNode.getFinish();
+        final int finish = tryNode.getFinish();
 
         assert tryNode.getFinallyBody() == null;
 
@@ -341,11 +338,11 @@
             @Override
             public Node leaveThrowNode(final ThrowNode throwNode) {
                 if (rethrows.contains(throwNode)) {
-                    final List<Node> newStatements = copyFinally(finallyBody);
+                    final List<Statement> newStatements = copyFinally(finallyBody);
                     if (!isTerminal(newStatements)) {
                         newStatements.add(throwNode);
                     }
-                    return new Block(source, throwNode.getToken(), throwNode.getFinish(), newStatements);
+                    return new Block(throwNode.getLineNumber(), throwNode.getToken(), throwNode.getFinish(), newStatements);
                 }
                 return throwNode;
             }
@@ -363,14 +360,14 @@
             @Override
             public Node leaveReturnNode(final ReturnNode returnNode) {
                 final Node  expr  = returnNode.getExpression();
-                final List<Node> newStatements = new ArrayList<>();
+                final List<Statement> newStatements = new ArrayList<>();
 
                 final Node resultNode;
                 if (expr != null) {
                     //we need to evaluate the result of the return in case it is complex while
                     //still in the try block, store it in a result value and return it afterwards
                     resultNode = new IdentNode(Lower.this.compilerConstant(RETURN));
-                    newStatements.add(new ExecuteNode(new BinaryNode(source, Token.recast(returnNode.getToken(), TokenType.ASSIGN), resultNode, expr)));
+                    newStatements.add(new ExecuteNode(returnNode.getLineNumber(), returnNode.getToken(), returnNode.getFinish(), new BinaryNode(Token.recast(returnNode.getToken(), TokenType.ASSIGN), resultNode, expr)));
                 } else {
                     resultNode = null;
                 }
@@ -380,16 +377,16 @@
                     newStatements.add(expr == null ? returnNode : returnNode.setExpression(resultNode));
                 }
 
-                return new ExecuteNode(new Block(source, returnNode.getToken(), getLexicalContext().getCurrentBlock().getFinish(), newStatements));
+                return new ExecuteNode(returnNode.getLineNumber(), returnNode.getToken(), returnNode.getFinish(), new Block(returnNode.getLineNumber(), returnNode.getToken(), getLexicalContext().getCurrentBlock().getFinish(), newStatements));
             }
 
-            private Node copy(final Node endpoint, final Node targetNode) {
+            private Node copy(final Statement endpoint, final Node targetNode) {
                 if (!insideTry.contains(targetNode)) {
-                    final List<Node> newStatements = copyFinally(finallyBody);
+                    final List<Statement> newStatements = copyFinally(finallyBody);
                     if (!isTerminal(newStatements)) {
                         newStatements.add(endpoint);
                     }
-                    return new ExecuteNode(new Block(source, endpoint.getToken(), finish, newStatements));
+                    return new ExecuteNode(endpoint.getLineNumber(), endpoint.getToken(), endpoint.getFinish(), new Block(endpoint.getLineNumber(), endpoint.getToken(), finish, newStatements));
                 }
                 return endpoint;
             }
@@ -397,7 +394,7 @@
 
         addStatement(newTryNode);
         for (final Node statement : finallyBody.getStatements()) {
-            addStatement(statement);
+            addStatement((Statement)statement);
         }
 
         return newTryNode;
@@ -451,7 +448,7 @@
         if (tryNode.getCatchBlocks().isEmpty()) {
             newTryNode = tryNode.setFinallyBody(null);
         } else {
-            Block outerBody = new Block(tryNode.getSource(), tryNode.getToken(), tryNode.getFinish(), new ArrayList<Node>(Arrays.asList(tryNode.setFinallyBody(null))));
+            Block outerBody = new Block(tryNode.getLineNumber(), tryNode.getToken(), tryNode.getFinish(), new ArrayList<Statement>(Arrays.asList(tryNode.setFinallyBody(null))));
             newTryNode = tryNode.setBody(outerBody).setCatchBlocks(null);
         }
 
@@ -468,19 +465,19 @@
     public Node leaveVarNode(final VarNode varNode) {
         addStatement(varNode);
         if (varNode.getFlag(VarNode.IS_LAST_FUNCTION_DECLARATION) && getLexicalContext().getCurrentFunction().isProgram()) {
-            new ExecuteNode(varNode.getSource(), varNode.getToken(), varNode.getFinish(), new IdentNode(varNode.getName())).accept(this);
+            new ExecuteNode(varNode.getLineNumber(), varNode.getToken(), varNode.getFinish(), new IdentNode(varNode.getName())).accept(this);
         }
         return varNode;
     }
 
     @Override
     public Node leaveWhileNode(final WhileNode whileNode) {
-        final Node test = whileNode.getTest();
+        final Node test  = whileNode.getTest();
         final Block body = whileNode.getBody();
 
         if (conservativeAlwaysTrue(test)) {
             //turn it into a for node without a test.
-            final ForNode forNode = (ForNode)new ForNode(whileNode.getSource(), whileNode.getToken(), whileNode.getFinish(), null, null, body, null, ForNode.IS_FOR).accept(this);
+            final ForNode forNode = (ForNode)new ForNode(whileNode.getLineNumber(), whileNode.getToken(), whileNode.getFinish(), null, null, body, null, ForNode.IS_FOR).accept(this);
             getLexicalContext().replace(whileNode, forNode);
             return forNode;
         }
@@ -493,16 +490,6 @@
         return addStatement(withNode);
     }
 
-    @Override
-    public Node leaveDELETE(final UnaryNode unaryNode) {
-        final Node rhs = unaryNode.rhs();
-        if (rhs instanceof IdentNode || rhs instanceof BaseNode) {
-            return unaryNode;
-        }
-        addStatement(new ExecuteNode(rhs));
-        return LiteralNode.newInstance(unaryNode, true);
-    }
-
     /**
      * Given a function node that is a callee in a CallNode, replace it with
      * the appropriate marker function. This is used by {@link CodeGenerator}
@@ -525,11 +512,12 @@
      * @param node a node
      * @return eval location
      */
-    private static String evalLocation(final IdentNode node) {
+    private String evalLocation(final IdentNode node) {
+        final Source source = getLexicalContext().getCurrentFunction().getSource();
         return new StringBuilder().
-            append(node.getSource().getName()).
+            append(source.getName()).
             append('#').
-            append(node.getSource().getLine(node.position())).
+            append(source.getLine(node.position())).
             append("<eval>").
             toString();
     }
@@ -618,7 +606,7 @@
     }
 
 
-    private Node addStatement(final Node statement) {
+    private Node addStatement(final Statement statement) {
         ((BlockLexicalContext)getLexicalContext()).appendStatement(statement);
         return statement;
     }
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java b/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java
index 00f3f80..153e036 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java
@@ -65,10 +65,12 @@
      * Constructs a property map based on a set of fields.
      *
      * @param hasArguments does the created object have an "arguments" property
+     * @param fieldCount    Number of fields in use.
+     * @param fieldMaximum Number of fields available.
      *
      * @return New map populated with accessor properties.
      */
-    PropertyMap makeMap(final boolean hasArguments) {
+    PropertyMap makeMap(final boolean hasArguments, final int fieldCount, final int fieldMaximum) {
         final List<Property> properties = new ArrayList<>();
 
         assert keys != null;
@@ -82,7 +84,7 @@
             }
         }
 
-        return PropertyMap.newMap(structure, properties);
+        return PropertyMap.newMap(structure, properties, fieldCount, fieldMaximum);
     }
 
     /**
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java
index 4fbb57a..c156c86 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java
@@ -67,10 +67,9 @@
 
 import java.io.PrintStream;
 import java.lang.reflect.Array;
-import java.util.ArrayDeque;
 import java.util.EnumSet;
-import java.util.Iterator;
 import java.util.List;
+
 import jdk.internal.dynalink.support.NameCodec;
 import jdk.internal.org.objectweb.asm.Handle;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
@@ -114,7 +113,7 @@
     private final MethodVisitor method;
 
     /** Current type stack for current evaluation */
-    private ArrayDeque<Type> stack;
+    private Label.Stack stack;
 
     /** Parent classEmitter representing the class of this method */
     private final ClassEmitter classEmitter;
@@ -189,7 +188,7 @@
     @Override
     public void begin() {
         classEmitter.beginMethod(this);
-        stack = new ArrayDeque<>();
+        newStack();
         method.visitCode();
     }
 
@@ -205,6 +204,10 @@
         classEmitter.endMethod(this);
     }
 
+    private void newStack() {
+        stack = new Label.Stack();
+    }
+
     @Override
     public String toString() {
         return "methodEmitter: " + (functionNode == null ? method : functionNode.getName()).toString() + ' ' + Debug.id(this);
@@ -288,11 +291,7 @@
      * @return the type at position "pos" on the stack
      */
     final Type peekType(final int pos) {
-        final Iterator<Type> iter = stack.iterator();
-        for (int i = 0; i < pos; i++) {
-            iter.next();
-        }
-        return iter.next();
+        return stack.peek(pos);
     }
 
     /**
@@ -484,7 +483,7 @@
             name = THIS_DEBUGGER.symbolName();
         }
 
-        method.visitLocalVariable(name, symbol.getSymbolType().getDescriptor(), null, start, end, symbol.getSlot());
+        method.visitLocalVariable(name, symbol.getSymbolType().getDescriptor(), null, start.getLabel(), end.getLabel(), symbol.getSlot());
     }
 
     /**
@@ -509,17 +508,6 @@
     }
 
     /**
-     * Associate a variable with a given range
-     *
-     * @param name  name of the variable
-     * @param start start
-     * @param end   end
-     */
-    void markerVariable(final String name, final Label start, final Label end) {
-        method.visitLocalVariable(name, Type.OBJECT.getDescriptor(), null, start, end, 0);
-    }
-
-    /**
      * Pops two integer types from the stack, performs a bitwise and and pushes
      * the result
      *
@@ -626,7 +614,7 @@
      * @param typeDescriptor type descriptor for exception
      */
     void _try(final Label entry, final Label exit, final Label recovery, final String typeDescriptor) {
-        method.visitTryCatchBlock(entry, exit, recovery, typeDescriptor);
+        method.visitTryCatchBlock(entry.getLabel(), exit.getLabel(), recovery.getLabel(), typeDescriptor);
     }
 
     /**
@@ -638,7 +626,7 @@
      * @param clazz    exception class
      */
     void _try(final Label entry, final Label exit, final Label recovery, final Class<?> clazz) {
-        method.visitTryCatchBlock(entry, exit, recovery, CompilerConstants.className(clazz));
+        method.visitTryCatchBlock(entry.getLabel(), exit.getLabel(), recovery.getLabel(), CompilerConstants.className(clazz));
     }
 
     /**
@@ -871,7 +859,7 @@
     }
 
     private boolean isThisSlot(final int slot) {
-        if(functionNode == null) {
+        if (functionNode == null) {
             return slot == CompilerConstants.JAVA_THIS.slot();
         }
         final int thisSlot = compilerConstant(THIS).getSlot();
@@ -915,7 +903,6 @@
             dup();
             return this;
         }
-        debug("load compiler constant ", symbol);
         return load(symbol);
     }
 
@@ -1228,6 +1215,14 @@
         return invoke(INVOKEINTERFACE, className, methodName, methodDescriptor, true);
     }
 
+    static jdk.internal.org.objectweb.asm.Label[] getLabels(final Label... table) {
+        final jdk.internal.org.objectweb.asm.Label[] internalLabels = new jdk.internal.org.objectweb.asm.Label[table.length];
+        for (int i = 0; i < table.length; i++) {
+            internalLabels[i] = table[i].getLabel();
+        }
+        return internalLabels;
+    }
+
     /**
      * Generate a lookup switch, popping the switch value from the stack
      *
@@ -1235,10 +1230,10 @@
      * @param values       case values for the table
      * @param table        default label
      */
-    void lookupswitch(final Label defaultLabel, final int[] values, final Label[] table) {
+    void lookupswitch(final Label defaultLabel, final int[] values, final Label... table) {//Collection<Label> table) {
         debug("lookupswitch", peekType());
         popType(Type.INT);
-        method.visitLookupSwitchInsn(defaultLabel, values, table);
+        method.visitLookupSwitchInsn(defaultLabel.getLabel(), values, getLabels(table));
     }
 
     /**
@@ -1248,10 +1243,10 @@
      * @param defaultLabel  default label
      * @param table         label table
      */
-    void tableswitch(final int lo, final int hi, final Label defaultLabel, final Label[] table) {
+    void tableswitch(final int lo, final int hi, final Label defaultLabel, final Label... table) {
         debug("tableswitch", peekType());
         popType(Type.INT);
-        method.visitTableSwitchInsn(lo, hi, defaultLabel, table);
+        method.visitTableSwitchInsn(lo, hi, defaultLabel.getLabel(), getLabels(table));
     }
 
     /**
@@ -1358,7 +1353,7 @@
             popType();
         }
         mergeStackTo(label);
-        method.visitJumpInsn(opcode, label);
+        method.visitJumpInsn(opcode, label.getLabel());
     }
 
     /**
@@ -1487,9 +1482,9 @@
      * @param label destination label
      */
     void _goto(final Label label) {
-        debug("goto", label);
+        //debug("goto", label);
         jump(GOTO, label, 0);
-        stack = null;
+        stack = null; //whoever reaches the point after us provides the stack, because we don't
     }
 
     /**
@@ -1500,38 +1495,31 @@
      *
      * @return true if stacks are equivalent, false otherwise
      */
-    private boolean stacksEquivalent(final ArrayDeque<Type> s0, final ArrayDeque<Type> s1) {
-        if (s0.size() != s1.size()) {
-            debug("different stack sizes", s0, s1);
-            return false;
-        }
-
-        final Type[] s0a = s0.toArray(new Type[s0.size()]);
-        final Type[] s1a = s1.toArray(new Type[s1.size()]);
-        for (int i = 0; i < s0.size(); i++) {
-            if (!s0a[i].isEquivalentTo(s1a[i])) {
-                debug("different stack element", s0a[i], s1a[i]);
-                return false;
-            }
-        }
-
-        return true;
-    }
-
     /**
      * A join in control flow - helper function that makes sure all entry stacks
      * discovered for the join point so far are equivalent
-     * @param label
+     *
+     * MergeStack: we are about to enter a label. If its stack, label.getStack() is null
+     * we have never been here before. Then we are expected to carry a stack with us.
+     *
+     * @param label label
      */
     private void mergeStackTo(final Label label) {
-        final ArrayDeque<Type> labelStack = label.getStack();
-        //debug(labelStack == null ? " >> Control flow - first visit ", label : " >> Control flow - JOIN with ", labelStack, " at ", label);
+        //sometimes we can do a merge stack without having a stack - i.e. when jumping ahead to dead code
+        //see NASHORN-73. So far we had been saved by the line number nodes. This should have been fixed
+        //by Lower removing everything after an unconditionally executed terminating statement OR a break
+        //or continue in a block. Previously code left over after breaks and continues was still there
+        //and caused bytecode to be generated - which crashed on stack not being there, as the merge
+        //was not in fact preceeded by a visit. Furthermore, this led to ASM putting out its NOP NOP NOP
+        //ATHROW sequences instead of no code being generated at all. This should now be fixed.
+        assert stack != null : label + " entered with no stack. deadcode that remains?";
+
+        final Label.Stack labelStack = label.getStack();
         if (labelStack == null) {
-            assert stack != null;
-            label.setStack(stack.clone());
+            label.setStack(stack.copy());
             return;
         }
-        assert stacksEquivalent(stack, labelStack) : "stacks " + stack + " is not equivalent with " + labelStack + " at join point";
+        assert stack.isEquivalentTo(labelStack) : "stacks " + stack + " is not equivalent with " + labelStack + " at join point";
     }
 
     /**
@@ -1548,14 +1536,14 @@
         if (stack == null) {
             stack = label.getStack();
             if (stack == null) {
-                stack = new ArrayDeque<>(); //we don't have a stack at this point.
+                newStack();
             }
         }
         debug_label(label);
 
         mergeStackTo(label); //we have to merge our stack to whatever is in the label
 
-        method.visitLabel(label);
+        method.visitLabel(label.getLabel());
     }
 
     /**
@@ -1675,11 +1663,10 @@
      * @return array of Types
      */
     protected Type[] getTypesFromStack(final int count) {
-        final Iterator<Type> iter  = stack.iterator();
-        final Type[]         types = new Type[count];
-
+        final Type[] types = new Type[count];
+        int pos = 0;
         for (int i = count - 1; i >= 0; i--) {
-            types[i] = iter.next();
+            types[i] = stack.peek(pos++);
         }
 
         return types;
@@ -1695,11 +1682,11 @@
      * @return function signature for stack contents
      */
     private String getDynamicSignature(final Type returnType, final int argCount) {
-        final Iterator<Type> iter       = stack.iterator();
         final Type[]         paramTypes = new Type[argCount];
 
+        int pos = 0;
         for (int i = argCount - 1; i >= 0; i--) {
-            paramTypes[i] = iter.next();
+            paramTypes[i] = stack.peek(pos++);
         }
         final String descriptor = Type.getMethodDescriptor(returnType, paramTypes);
         for (int i = 0; i < argCount; i++) {
@@ -2018,8 +2005,13 @@
      * @param line  line number
      * @param label label
      */
-    void lineNumber(final int line, final Label label) {
-        method.visitLineNumber(line, label);
+    void lineNumber(final int line) {
+        if (env._debug_lines) {
+            debug_label("[LINE]", line);
+            final jdk.internal.org.objectweb.asm.Label l = new jdk.internal.org.objectweb.asm.Label();
+            method.visitLabel(l);
+            method.visitLineNumber(line, l);
+        }
     }
 
     /*
@@ -2116,12 +2108,12 @@
                 pad--;
             }
 
-            if (!stack.isEmpty()) {
+            if (stack != null && !stack.isEmpty()) {
                 sb.append("{");
                 sb.append(stack.size());
                 sb.append(":");
-                for (final Iterator<Type> iter = stack.iterator(); iter.hasNext();) {
-                    final Type t = iter.next();
+                for (int pos = 0; pos < stack.size(); pos++) {
+                    final Type t = stack.peek(pos);
 
                     if (t == Type.SCOPE) {
                         sb.append("scope");
@@ -2147,7 +2139,7 @@
                         sb.append(t.getDescriptor());
                     }
 
-                    if (iter.hasNext()) {
+                    if (pos + 1 < stack.size()) {
                         sb.append(' ');
                     }
                 }
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java
index b751452..172c103 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java
@@ -69,6 +69,16 @@
     static final String SCOPE_MARKER = "P";
 
     /**
+     * Minimum number of extra fields in an object.
+     */
+    static final int FIELD_PADDING  = 4;
+
+    /**
+     * Rounding when calculating the number of fields.
+     */
+    static final int FIELD_ROUNDING = 4;
+
+    /**
      * Debug field logger
      * Should we print debugging information for fields when they are generated and getters/setters are called?
      */
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java b/nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java
index a9c494c..b0e5a77 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java
@@ -26,6 +26,7 @@
 package jdk.nashorn.internal.codegen;
 
 import java.util.List;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.FIELD_PADDING;
 import jdk.nashorn.internal.ir.Symbol;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.PropertyMap;
@@ -50,6 +51,7 @@
     private   final boolean       isScope;
     private   final boolean       hasArguments;
     private         int           fieldCount;
+    private         int           paddedFieldCount;
     private         int           paramCount;
     private         String        fieldObjectClassName;
     private         Class<?>      fieldObjectClass;
@@ -88,6 +90,8 @@
                 }
             }
         }
+
+        paddedFieldCount = fieldCount + FIELD_PADDING;
     }
 
     /**
@@ -96,7 +100,7 @@
     private void findClass() {
         fieldObjectClassName = isScope() ?
             ObjectClassGenerator.getClassName(fieldCount, paramCount) :
-            ObjectClassGenerator.getClassName(fieldCount);
+            ObjectClassGenerator.getClassName(paddedFieldCount);
 
         try {
             this.fieldObjectClass = Context.forStructureClass(Compiler.binaryName(fieldObjectClassName));
@@ -125,11 +129,7 @@
      * @return the newly created property map
      */
     protected PropertyMap makeMap() {
-        if (keys.isEmpty()) { //empty map
-            propertyMap = PropertyMap.newMap(fieldObjectClass);
-        } else {
-            propertyMap = newMapCreator(fieldObjectClass).makeMap(hasArguments());
-        }
+        propertyMap = newMapCreator(fieldObjectClass).makeMap(hasArguments(), fieldCount, paddedFieldCount);
         return propertyMap;
     }
 
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java b/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java
index f482e4d..f18f686 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java
@@ -31,6 +31,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+
 import jdk.nashorn.internal.ir.Block;
 import jdk.nashorn.internal.ir.FunctionNode;
 import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
@@ -40,9 +41,9 @@
 import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit;
 import jdk.nashorn.internal.ir.Node;
 import jdk.nashorn.internal.ir.SplitNode;
+import jdk.nashorn.internal.ir.Statement;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
 import jdk.nashorn.internal.runtime.DebugLogger;
-import jdk.nashorn.internal.runtime.Source;
 import jdk.nashorn.internal.runtime.options.Options;
 
 /**
@@ -75,7 +76,7 @@
      */
     public Splitter(final Compiler compiler, final FunctionNode functionNode, final CompileUnit outermostCompileUnit) {
         this.compiler             = compiler;
-        this.outermost = functionNode;
+        this.outermost            = functionNode;
         this.outermostCompileUnit = outermostCompileUnit;
     }
 
@@ -95,7 +96,7 @@
         final LexicalContext lc = getLexicalContext();
 
         long weight = WeighNodes.weigh(functionNode);
-        final boolean top = compiler.getFunctionNode() == outermost;
+        final boolean top = fn.isProgram(); //compiler.getFunctionNode() == outermost;
 
         if (weight >= SPLIT_THRESHOLD) {
             LOG.finest("Splitting '", functionNode.getName(), "' as its weight ", weight, " exceeds split threshold ", SPLIT_THRESHOLD);
@@ -127,18 +128,18 @@
         final List<FunctionNode> dc = directChildren(functionNode);
 
         final Block newBody = (Block)body.accept(new NodeVisitor() {
-                @Override
-                public boolean enterFunctionNode(final FunctionNode nestedFunction) {
-                    return dc.contains(nestedFunction);
-                }
+            @Override
+            public boolean enterFunctionNode(final FunctionNode nestedFunction) {
+                return dc.contains(nestedFunction);
+            }
 
-                @Override
-                public Node leaveFunctionNode(final FunctionNode nestedFunction) {
-                    FunctionNode split = new Splitter(compiler, nestedFunction, outermostCompileUnit).split(nestedFunction);
-                    getLexicalContext().replace(nestedFunction, split);
-                    return split;
-                }
-            });
+            @Override
+            public Node leaveFunctionNode(final FunctionNode nestedFunction) {
+                FunctionNode split = new Splitter(compiler, nestedFunction, outermostCompileUnit).split(nestedFunction);
+                getLexicalContext().replace(nestedFunction, split);
+                return split;
+            }
+        });
         functionNode = functionNode.setBody(lc, newBody);
 
         assert functionNode.getCompileUnit() != null;
@@ -182,11 +183,11 @@
     private Block splitBlock(final Block block, final FunctionNode function) {
         getLexicalContext().setFlag(getLexicalContext().getCurrentFunction(), FunctionNode.IS_SPLIT);
 
-        final List<Node> splits = new ArrayList<>();
-        List<Node> statements = new ArrayList<>();
+        final List<Statement> splits = new ArrayList<>();
+        List<Statement> statements = new ArrayList<>();
         long statementsWeight = 0;
 
-        for (final Node statement : block.getStatements()) {
+        for (final Statement statement : block.getStatements()) {
             final long weight = WeighNodes.weigh(statement, weightCache);
 
             if (statementsWeight + weight >= SPLIT_THRESHOLD || statement.isTerminal()) {
@@ -220,15 +221,15 @@
      *
      * @return New split node.
      */
-    private SplitNode createBlockSplitNode(final Block parent, final FunctionNode function, final List<Node> statements, final long weight) {
-        final Source source = parent.getSource();
-        final long   token  = parent.getToken();
-        final int    finish = parent.getFinish();
-        final String name   = function.uniqueName(SPLIT_PREFIX.symbolName());
+    private SplitNode createBlockSplitNode(final Block parent, final FunctionNode function, final List<Statement> statements, final long weight) {
+        final int    lineNumber = parent.getLineNumber();
+        final long   token      = parent.getToken();
+        final int    finish     = parent.getFinish();
+        final String name       = function.uniqueName(SPLIT_PREFIX.symbolName());
 
-        final Block newBlock = new Block(source, token, finish, statements);
+        final Block newBlock = new Block(lineNumber, token, finish, statements);
 
-        return new SplitNode(name, newBlock, compiler.findUnit(weight + WeighNodes.FUNCTION_WEIGHT));
+        return new SplitNode(lineNumber, name, newBlock, compiler.findUnit(weight + WeighNodes.FUNCTION_WEIGHT));
     }
 
     @Override
@@ -273,7 +274,9 @@
             return literal;
         }
 
-        getLexicalContext().setFlag(getLexicalContext().getCurrentFunction(), FunctionNode.IS_SPLIT);
+        final FunctionNode functionNode = getLexicalContext().getCurrentFunction();
+
+        getLexicalContext().setFlag(functionNode, FunctionNode.IS_SPLIT);
 
         if (literal instanceof ArrayLiteralNode) {
             final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode) literal;
diff --git a/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java b/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java
index 2f739bf..28b09a6 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java
@@ -28,7 +28,6 @@
 import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation of a property access (period operator.)
@@ -41,14 +40,13 @@
     /**
      * Constructor
      *
-     * @param source    source code
      * @param token     token
      * @param finish    finish
      * @param base      base node
      * @param property  property
      */
-    public AccessNode(final Source source, final long token, final int finish, final Node base, final IdentNode property) {
-        super(source, token, finish, base, false, false);
+    public AccessNode(final long token, final int finish, final Node base, final IdentNode property) {
+        super(token, finish, base, false, false);
         this.property = property.setIsPropertyName();
     }
 
@@ -121,10 +119,10 @@
     }
 
     @Override
-    public AccessNode setType(final Type type) {
+    public AccessNode setType(final TemporarySymbols ts, final LexicalContext lc, final Type type) {
         logTypeChange(type);
-        getSymbol().setTypeOverride(type); //always a temp so this is fine.
-        return new AccessNode(this, base, property.setType(type), isFunction(), hasCallSiteType());
+        final AccessNode newAccessNode = (AccessNode)setSymbol(lc, getSymbol().setTypeOverrideShared(type, ts));
+        return new AccessNode(newAccessNode, base, property.setType(ts, lc, type), isFunction(), hasCallSiteType());
     }
 
     @Override
diff --git a/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java b/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java
index 5e5bfb1..a1b7c0e 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java
@@ -29,7 +29,6 @@
 import jdk.nashorn.internal.codegen.ObjectClassGenerator;
 import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.ir.annotations.Immutable;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR base for accessing/indexing nodes.
@@ -50,15 +49,14 @@
     /**
      * Constructor
      *
-     * @param source source code
      * @param token  token
      * @param finish finish
      * @param base   base node
      * @param isFunction is this a function
      * @param hasCallSiteType does this access have a callsite type
      */
-    public BaseNode(final Source source, final long token, final int finish, final Node base, final boolean isFunction, final boolean hasCallSiteType) {
-        super(source, token, base.getStart(), finish);
+    public BaseNode(final long token, final int finish, final Node base, final boolean isFunction, final boolean hasCallSiteType) {
+        super(token, base.getStart(), finish);
         this.base            = base;
         this.isFunction      = isFunction;
         this.hasCallSiteType = hasCallSiteType;
diff --git a/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java b/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java
index 28df8ed..61454fe 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java
@@ -29,7 +29,6 @@
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
 import jdk.nashorn.internal.parser.TokenType;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * BinaryNode nodes represent two operand operations.
@@ -44,13 +43,12 @@
     /**
      * Constructor
      *
-     * @param source source code
      * @param token  token
      * @param lhs    left hand side
      * @param rhs    right hand side
      */
-    public BinaryNode(final Source source, final long token, final Node lhs, final Node rhs) {
-        super(source, token, lhs.getStart(), rhs.getFinish());
+    public BinaryNode(final long token, final Node lhs, final Node rhs) {
+        super(token, lhs.getStart(), rhs.getFinish());
         this.lhs   = lhs;
         this.rhs   = rhs;
     }
diff --git a/nashorn/src/jdk/nashorn/internal/ir/Block.java b/nashorn/src/jdk/nashorn/internal/ir/Block.java
index 48b9ed6..a0fa937 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/Block.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/Block.java
@@ -30,14 +30,12 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import jdk.nashorn.internal.codegen.Label;
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation for a list of statements and functions. All provides the
@@ -46,7 +44,7 @@
 @Immutable
 public class Block extends BreakableNode implements Flags<Block> {
     /** List of statements */
-    protected final List<Node> statements;
+    protected final List<Statement> statements;
 
     /** Symbol table - keys must be returned in the order they were put in. */
     protected final Map<String, Symbol> symbols;
@@ -78,13 +76,13 @@
     /**
      * Constructor
      *
-     * @param source     source code
+     * @param lineNumber line number
      * @param token      token
      * @param finish     finish
      * @param statements statements
      */
-    public Block(final Source source, final long token, final int finish, final Node... statements) {
-        super(source, token, finish, new Label("block_break"));
+    public Block(final int lineNumber, final long token, final int finish, final Statement... statements) {
+        super(lineNumber, token, finish, new Label("block_break"));
 
         this.statements = Arrays.asList(statements);
         this.symbols    = new LinkedHashMap<>();
@@ -95,27 +93,35 @@
     /**
      * Constructor
      *
-     * @param source     source code
+     * @param lineNumber line number
      * @param token      token
      * @param finish     finish
      * @param statements statements
      */
-    public Block(final Source source, final long token, final int finish, final List<Node> statements) {
-        this(source, token, finish, statements.toArray(new Node[statements.size()]));
+    public Block(final int lineNumber, final long token, final int finish, final List<Statement> statements) {
+        this(lineNumber, token, finish, statements.toArray(new Statement[statements.size()]));
     }
 
-    private Block(final Block block, final int finish, final List<Node> statements, final int flags) {
+    private Block(final Block block, final int finish, final List<Statement> statements, final int flags, final Map<String, Symbol> symbols) {
         super(block);
         this.statements = statements;
         this.flags      = flags;
-        this.symbols    = block.symbols; //todo - symbols have no dependencies on any IR node and can as far as we understand it be shallow copied now
+        this.symbols    = new LinkedHashMap<>(symbols); //todo - symbols have no dependencies on any IR node and can as far as we understand it be shallow copied now
         this.entryLabel = new Label(block.entryLabel);
-        this.finish = finish;
+        this.finish     = finish;
+    }
+
+    /**
+     * Clear the symbols in a block
+     * TODO: make this immutable
+     */
+    public void clearSymbols() {
+        symbols.clear();
     }
 
     @Override
     public Node ensureUniqueLabels(final LexicalContext lc) {
-        return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags));
+        return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags, symbols));
     }
 
     /**
@@ -127,7 +133,7 @@
     @Override
     public Node accept(final LexicalContext lc, final NodeVisitor visitor) {
         if (visitor.enterBlock(this)) {
-            return visitor.leaveBlock(setStatements(lc, Node.accept(visitor, Node.class, statements)));
+            return visitor.leaveBlock(setStatements(lc, Node.accept(visitor, Statement.class, statements)));
         }
 
         return this;
@@ -137,15 +143,15 @@
      * Get an iterator for all the symbols defined in this block
      * @return symbol iterator
      */
-    public Iterator<Symbol> symbolIterator() {
-        return symbols.values().iterator();
+    public List<Symbol> getSymbols() {
+        return Collections.unmodifiableList(new ArrayList<>(symbols.values()));
     }
 
     /**
      * Retrieves an existing symbol defined in the current block.
      * @param name the name of the symbol
      * @return an existing symbol with the specified name defined in the current block, or null if this block doesn't
-     * define a symbol with this name.
+     * define a symbol with this name.T
      */
     public Symbol getExistingSymbol(final String name) {
         return symbols.get(name);
@@ -222,7 +228,7 @@
      *
      * @return a list of statements
      */
-    public List<Node> getStatements() {
+    public List<Statement> getStatements() {
         return Collections.unmodifiableList(statements);
     }
 
@@ -233,7 +239,7 @@
      * @param statements new statement list
      * @return new block if statements changed, identity of statements == block.statements
      */
-    public Block setStatements(final LexicalContext lc, final List<Node> statements) {
+    public Block setStatements(final LexicalContext lc, final List<Statement> statements) {
         if (this.statements == statements) {
             return this;
         }
@@ -241,17 +247,17 @@
         if (!statements.isEmpty()) {
             lastFinish = statements.get(statements.size() - 1).getFinish();
         }
-        return Node.replaceInLexicalContext(lc, this, new Block(this, Math.max(finish, lastFinish), statements, flags));
+        return Node.replaceInLexicalContext(lc, this, new Block(this, Math.max(finish, lastFinish), statements, flags, symbols));
     }
 
     /**
      * Add or overwrite an existing symbol in the block
      *
-     * @param name   name of symbol
+     * @param lc     get lexical context
      * @param symbol symbol
      */
-    public void putSymbol(final String name, final Symbol symbol) {
-        symbols.put(name, symbol);
+    public void putSymbol(final LexicalContext lc, final Symbol symbol) {
+        symbols.put(symbol.getName(), symbol);
     }
 
     /**
@@ -268,7 +274,7 @@
         if (this.flags == flags) {
             return this;
         }
-        return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags));
+        return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags, symbols));
     }
 
     @Override
@@ -296,7 +302,7 @@
             return this;
         }
 
-        return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags | NEEDS_SCOPE));
+        return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags | NEEDS_SCOPE, symbols));
     }
 
     /**
@@ -306,13 +312,11 @@
      * @return next slot
      */
     public int nextSlot() {
-        final Iterator<Symbol> iter = symbolIterator();
         int next = 0;
-        while (iter.hasNext()) {
-        final Symbol symbol = iter.next();
-        if (symbol.hasSlot()) {
-            next += symbol.slotCount();
-        }
+        for (final Symbol symbol : getSymbols()) {
+            if (symbol.hasSlot()) {
+                next += symbol.slotCount();
+            }
         }
         return next;
     }
diff --git a/nashorn/src/jdk/nashorn/internal/ir/BlockLexicalContext.java b/nashorn/src/jdk/nashorn/internal/ir/BlockLexicalContext.java
index 38186f56..71c80a6 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/BlockLexicalContext.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/BlockLexicalContext.java
@@ -41,16 +41,16 @@
 public class BlockLexicalContext extends LexicalContext {
     /** statement stack, each block on the lexical context maintains one of these, which is
      *  committed to the block on pop */
-    private Deque<List<Node>> sstack = new ArrayDeque<>();
+    private Deque<List<Statement>> sstack = new ArrayDeque<>();
 
     /** Last non debug statement emitted in this context */
-    protected Node lastStatement;
+    protected Statement lastStatement;
 
     @Override
     public <T extends LexicalContextNode> T push(final T node) {
         T pushed = super.push(node);
         if (node instanceof Block) {
-            sstack.push(new ArrayList<Node>());
+            sstack.push(new ArrayList<Statement>());
         }
         return pushed;
     }
@@ -59,16 +59,16 @@
      * Get the statement list from the stack, possibly filtered
      * @return statement list
      */
-    protected List<Node> popStatements() {
+    protected List<Statement> popStatements() {
         return sstack.pop();
     }
 
-    @Override
     @SuppressWarnings("unchecked")
+    @Override
     public <T extends LexicalContextNode> T pop(final T node) {
         T expected = node;
         if (node instanceof Block) {
-            final List<Node> newStatements = popStatements();
+            final List<Statement> newStatements = popStatements();
             expected = (T)((Block)node).setStatements(this, newStatements);
             if (!sstack.isEmpty()) {
                 lastStatement = lastStatement(sstack.peek());
@@ -81,12 +81,10 @@
      * Append a statement to the block being generated
      * @param statement statement to add
      */
-    public void appendStatement(final Node statement) {
+    public void appendStatement(final Statement statement) {
         assert statement != null;
         sstack.peek().add(statement);
-        if (!statement.isDebug()) {
-            lastStatement = statement;
-        }
+        lastStatement = statement;
     }
 
     /**
@@ -94,26 +92,24 @@
      * @param statement statement to prepend
      * @return the prepended statement
      */
-    public Node prependStatement(final Node statement) {
+    public Node prependStatement(final Statement statement) {
         assert statement != null;
         sstack.peek().add(0, statement);
         return statement;
     }
 
     /**
-     * Get the last (non debug) statement that was emitted into a block
+     * Get the last statement that was emitted into a block
      * @return the last statement emitted
      */
-    public Node getLastStatement() {
+    public Statement getLastStatement() {
         return lastStatement;
     }
 
-    private static Node lastStatement(final List<Node> statements) {
-        for (final ListIterator<Node> iter = statements.listIterator(statements.size()); iter.hasPrevious(); ) {
-            final Node node = iter.previous();
-            if (!node.isDebug()) {
-                return node;
-            }
+    private static Statement lastStatement(final List<Statement> statements) {
+        for (final ListIterator<Statement> iter = statements.listIterator(statements.size()); iter.hasPrevious(); ) {
+            final Statement node = iter.previous();
+            return node;
         }
         return null;
     }
diff --git a/nashorn/src/jdk/nashorn/internal/ir/BreakNode.java b/nashorn/src/jdk/nashorn/internal/ir/BreakNode.java
index f0966b4..f1b9cb9 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/BreakNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/BreakNode.java
@@ -27,26 +27,25 @@
 
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation for {@code break} statements.
  */
 @Immutable
-public final class BreakNode extends Node {
+public final class BreakNode extends Statement {
 
     private final IdentNode label;
 
     /**
      * Constructor
      *
-     * @param source source code
-     * @param token  token
-     * @param finish finish
-     * @param label  label for break or null if none
+     * @param lineNumber line number
+     * @param token      token
+     * @param finish     finish
+     * @param label      label for break or null if none
      */
-    public BreakNode(final Source source, final long token, final int finish, final IdentNode label) {
-        super(source, token, finish);
+    public BreakNode(final int lineNumber, final long token, final int finish, final IdentNode label) {
+        super(lineNumber, token, finish);
         this.label = label;
     }
 
diff --git a/nashorn/src/jdk/nashorn/internal/ir/BreakableNode.java b/nashorn/src/jdk/nashorn/internal/ir/BreakableNode.java
index 3662bfa..ea07cb4 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/BreakableNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/BreakableNode.java
@@ -30,7 +30,6 @@
 
 import jdk.nashorn.internal.codegen.Label;
 import jdk.nashorn.internal.ir.annotations.Immutable;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * This class represents a node from which control flow can execute
@@ -45,13 +44,13 @@
     /**
      * Constructor
      *
-     * @param source     source code
+     * @param lineNumber line number
      * @param token      token
      * @param finish     finish
      * @param breakLabel break label
      */
-    protected BreakableNode(final Source source, final long token, final int finish, final Label breakLabel) {
-        super(source, token, finish);
+    protected BreakableNode(final int lineNumber, final long token, final int finish, final Label breakLabel) {
+        super(lineNumber, token, finish);
         this.breakLabel = breakLabel;
     }
 
diff --git a/nashorn/src/jdk/nashorn/internal/ir/CallNode.java b/nashorn/src/jdk/nashorn/internal/ir/CallNode.java
index 9a730aa..46cf458 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/CallNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/CallNode.java
@@ -31,7 +31,6 @@
 import jdk.nashorn.internal.ir.annotations.Ignore;
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation for a function call.
@@ -137,14 +136,14 @@
     /**
      * Constructors
      *
-     * @param source   the source
-     * @param token    token
-     * @param finish   finish
-     * @param function the function to call
-     * @param args     args to the call
+     * @param lineNumber line number
+     * @param token      token
+     * @param finish     finish
+     * @param function   the function to call
+     * @param args       args to the call
      */
-    public CallNode(final Source source, final long token, final int finish, final Node function, final List<Node> args) {
-        super(source, token, finish);
+    public CallNode(final int lineNumber, final long token, final int finish, final Node function, final List<Node> args) {
+        super(lineNumber, token, finish);
 
         this.function = function;
         this.args     = args;
@@ -171,7 +170,7 @@
     }
 
     @Override
-    public CallNode setType(final Type type) {
+    public CallNode setType(final TemporarySymbols ts, final LexicalContext lc, final Type type) {
         if (this.type == type) {
             return this;
         }
@@ -201,7 +200,7 @@
                     setFunction(function.accept(visitor)).
                     setArgs(Node.accept(visitor, Node.class, args)).
                     setFlags(flags).
-                    setType(type).
+                    setType(null, lc, type).
                     setEvalArgs(evalArgs == null ?
                             null :
                             evalArgs.setCode(evalArgs.getCode().accept(visitor)).
diff --git a/nashorn/src/jdk/nashorn/internal/ir/CaseNode.java b/nashorn/src/jdk/nashorn/internal/ir/CaseNode.java
index 237536c..8a438f8 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/CaseNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/CaseNode.java
@@ -28,7 +28,6 @@
 import jdk.nashorn.internal.codegen.Label;
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation of CASE clause.
@@ -48,14 +47,13 @@
     /**
      * Constructors
      *
-     * @param source   the source
      * @param token    token
      * @param finish   finish
      * @param test     case test node, can be any node in JavaScript
      * @param body     case body
      */
-    public CaseNode(final Source source, final long token, final int finish, final Node test, final Block body) {
-        super(source, token, finish);
+    public CaseNode(final long token, final int finish, final Node test, final Block body) {
+        super(token, finish);
 
         this.test  = test;
         this.body  = body;
diff --git a/nashorn/src/jdk/nashorn/internal/ir/CatchNode.java b/nashorn/src/jdk/nashorn/internal/ir/CatchNode.java
index 5e1b411..c455149 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/CatchNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/CatchNode.java
@@ -27,13 +27,12 @@
 
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation of a catch clause.
  */
 @Immutable
-public final class CatchNode extends Node {
+public final class CatchNode extends Statement {
     /** Exception identifier. */
     private final IdentNode exception;
 
@@ -46,16 +45,15 @@
     /**
      * Constructors
      *
-     * @param source             the source
+     * @param lineNumber         lineNumber
      * @param token              token
      * @param finish             finish
      * @param exception          variable name of exception
      * @param exceptionCondition exception condition
      * @param body               catch body
      */
-    public CatchNode(final Source source, final long token, final int finish, final IdentNode exception, final Node exceptionCondition, final Block body) {
-        super(source, token, finish);
-
+    public CatchNode(final int lineNumber, final long token, final int finish, final IdentNode exception, final Node exceptionCondition, final Block body) {
+        super(lineNumber, token, finish);
         this.exception          = exception;
         this.exceptionCondition = exceptionCondition;
         this.body               = body;
@@ -63,7 +61,6 @@
 
     private CatchNode(final CatchNode catchNode, final IdentNode exception, final Node exceptionCondition, final Block body) {
         super(catchNode);
-
         this.exception          = exception;
         this.exceptionCondition = exceptionCondition;
         this.body               = body;
@@ -138,7 +135,12 @@
         return body;
     }
 
-    private CatchNode setException(final IdentNode exception) {
+    /**
+     * Resets the exception of a catch block
+     * @param exception new exception
+     * @return new catch node if changed, same otherwise
+     */
+    public CatchNode setException(final IdentNode exception) {
         if (this.exception == exception) {
             return this;
         }
diff --git a/nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java b/nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java
index c8cc309..c82813b 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java
@@ -27,26 +27,25 @@
 
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation for CONTINUE statements.
  */
 @Immutable
-public class ContinueNode extends Node {
+public class ContinueNode extends Statement {
 
     private IdentNode label;
 
     /**
      * Constructor
      *
-     * @param source source code
-     * @param token  token
-     * @param finish finish
-     * @param label  label for break or null if none
+     * @param lineNumber line number
+     * @param token      token
+     * @param finish     finish
+     * @param label      label for break or null if none
      */
-    public ContinueNode(final Source source, final long token, final int finish, final IdentNode label) {
-        super(source, token, finish);
+    public ContinueNode(final int lineNumber, final long token, final int finish, final IdentNode label) {
+        super(lineNumber, token, finish);
         this.label = label;
     }
 
diff --git a/nashorn/src/jdk/nashorn/internal/ir/EmptyNode.java b/nashorn/src/jdk/nashorn/internal/ir/EmptyNode.java
index 6751612..9f53a60 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/EmptyNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/EmptyNode.java
@@ -27,32 +27,31 @@
 
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation for an empty statement.
  */
 @Immutable
-public final class EmptyNode extends Node {
+public final class EmptyNode extends Statement {
 
     /**
      * Constructor
      *
      * @param node node to wrap
      */
-    public EmptyNode(final Node node) {
+    public EmptyNode(final Statement node) {
         super(node);
     }
 
     /**
      * Constructor
      *
-     * @param source     the source
+     * @param lineNumber line number
      * @param token      token
      * @param finish     finish
      */
-    public EmptyNode(final Source source, final long token, final int finish) {
-        super(source, token, finish);
+    public EmptyNode(final int lineNumber, final long token, final int finish) {
+        super(lineNumber, token, finish);
     }
 
 
diff --git a/nashorn/src/jdk/nashorn/internal/ir/ExecuteNode.java b/nashorn/src/jdk/nashorn/internal/ir/ExecuteNode.java
index f6dd7d1..300254d 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/ExecuteNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/ExecuteNode.java
@@ -27,7 +27,6 @@
 
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation for executing bare expressions. Basically, an expression
@@ -35,20 +34,20 @@
  * statements being added to the IR
  */
 @Immutable
-public final class ExecuteNode extends Node {
+public final class ExecuteNode extends Statement {
     /** Expression to execute. */
     private final Node expression;
 
     /**
      * Constructor
      *
-     * @param source     the source
+     * @param lineNumber line number
      * @param token      token
      * @param finish     finish
      * @param expression the expression to execute
      */
-    public ExecuteNode(final Source source, final long token, final int finish, final Node expression) {
-        super(source, token, finish);
+    public ExecuteNode(final int lineNumber, final long token, final int finish, final Node expression) {
+        super(lineNumber, token, finish);
         this.expression = expression;
     }
 
@@ -57,16 +56,6 @@
         this.expression = expression;
     }
 
-    /**
-     * Constructor
-     *
-     * @param expression an expression to wrap, from which source, tokens and finish are also inherited
-     */
-    public ExecuteNode(final Node expression) {
-        super(expression.getSource(), expression.getToken(), expression.getFinish());
-        this.expression = expression;
-    }
-
     @Override
     public boolean isTerminal() {
         return expression.isTerminal();
diff --git a/nashorn/src/jdk/nashorn/internal/ir/ForNode.java b/nashorn/src/jdk/nashorn/internal/ir/ForNode.java
index 057b846..3d0ea36 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/ForNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/ForNode.java
@@ -27,7 +27,6 @@
 
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representing a FOR statement.
@@ -57,17 +56,17 @@
     /**
      * Constructor
      *
-     * @param source the source
-     * @param token  token
-     * @param finish finish
-     * @param init   init
-     * @param test   test
-     * @param body   body
-     * @param modify modify
-     * @param flags  flags
+     * @param lineNumber line number
+     * @param token      token
+     * @param finish     finish
+     * @param init       initialization expression
+     * @param test       test
+     * @param body       body
+     * @param modify     modify
+     * @param flags      flags
      */
-    public ForNode(final Source source, final long token, final int finish, final Node init, final Node test, final Block body, final Node modify, final int flags) {
-        super(source, token, finish, test, body, false);
+    public ForNode(final int lineNumber, final long token, final int finish, final Node init, final Node test, final Block body, final Node modify, final int flags) {
+        super(lineNumber, token, finish, test, body, false);
         this.init   = init;
         this.modify = modify;
         this.flags  = flags;
diff --git a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java
index 60fe64f..2b6d19b 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java
@@ -25,16 +25,12 @@
 
 package jdk.nashorn.internal.ir;
 
-import static jdk.nashorn.internal.codegen.CompilerConstants.LITERAL_PREFIX;
-import static jdk.nashorn.internal.codegen.CompilerConstants.TEMP_PREFIX;
-import static jdk.nashorn.internal.ir.Symbol.IS_CONSTANT;
-import static jdk.nashorn.internal.ir.Symbol.IS_TEMP;
-
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+
 import jdk.nashorn.internal.codegen.CompileUnit;
 import jdk.nashorn.internal.codegen.Compiler;
 import jdk.nashorn.internal.codegen.CompilerConstants;
@@ -90,11 +86,17 @@
         /** method has been emitted to bytecode */
         EMITTED
     }
+    /** Source of entity. */
+    private final Source source;
 
     /** External function identifier. */
     @Ignore
     private final IdentNode ident;
 
+    /** Parsed version of functionNode */
+    @Ignore
+    private final FunctionNode snapshot;
+
     /** The body of the function node */
     private final Block body;
 
@@ -127,6 +129,9 @@
     @Ignore
     private final EnumSet<CompilationState> compilationState;
 
+    @Ignore
+    private final Compiler.Hints hints;
+
     /** Function flags. */
     private final int flags;
 
@@ -176,6 +181,9 @@
     /** Does this function have nested declarations? */
     public static final int HAS_FUNCTION_DECLARATIONS   = 1 << 13;
 
+    /** Can this function be specialized? */
+    public static final int CAN_SPECIALIZE              = 1 << 14;
+
     /** Does this function or any nested functions contain an eval? */
     private static final int HAS_DEEP_EVAL = HAS_EVAL | HAS_NESTED_EVAL;
 
@@ -196,6 +204,7 @@
      * Constructor
      *
      * @param source     the source
+     * @param lineNumber line number
      * @param token      token
      * @param finish     finish
      * @param firstToken first token of the funtion node (including the function declaration)
@@ -208,6 +217,7 @@
      */
     public FunctionNode(
         final Source source,
+        final int lineNumber,
         final long token,
         final int finish,
         final long firstToken,
@@ -217,39 +227,56 @@
         final List<IdentNode> parameters,
         final FunctionNode.Kind kind,
         final int flags) {
-        super(source, token, finish);
+        super(lineNumber, token, finish);
 
-        this.ident             = ident;
-        this.name              = name;
-        this.kind              = kind;
-        this.parameters        = parameters;
-        this.firstToken        = firstToken;
-        this.lastToken         = token;
-        this.namespace         = namespace;
-        this.compilationState  = EnumSet.of(CompilationState.INITIALIZED);
-        this.declaredSymbols   = new HashSet<>();
-        this.flags             = flags;
-        this.compileUnit       = null;
-        this.body              = null;
+        this.source           = source;
+        this.ident            = ident;
+        this.name             = name;
+        this.kind             = kind;
+        this.parameters       = parameters;
+        this.firstToken       = firstToken;
+        this.lastToken        = token;
+        this.namespace        = namespace;
+        this.compilationState = EnumSet.of(CompilationState.INITIALIZED);
+        this.declaredSymbols  = new HashSet<>();
+        this.flags            = flags;
+        this.compileUnit      = null;
+        this.body             = null;
+        this.snapshot         = null;
+        this.hints            = null;
     }
 
-    private FunctionNode(final FunctionNode functionNode, final long lastToken, final int flags, final Type returnType, final CompileUnit compileUnit, final EnumSet<CompilationState> compilationState, final Block body) {
+    private FunctionNode(
+        final FunctionNode functionNode,
+        final long lastToken,
+        final int flags,
+        final Type returnType,
+        final CompileUnit compileUnit,
+        final EnumSet<CompilationState> compilationState,
+        final Block body,
+        final List<IdentNode> parameters,
+        final FunctionNode snapshot,
+        final Compiler.Hints hints) {
         super(functionNode);
-        this.flags = flags;
-        this.returnType = returnType;
-        this.compileUnit = compileUnit;
-        this.lastToken = lastToken;
+
+        this.flags            = flags;
+        this.returnType       = returnType;
+        this.compileUnit      = compileUnit;
+        this.lastToken        = lastToken;
         this.compilationState = compilationState;
-        this.body  = body;
+        this.body             = body;
+        this.parameters       = parameters;
+        this.snapshot         = snapshot;
+        this.hints            = hints;
 
         // the fields below never change - they are final and assigned in constructor
-        this.name = functionNode.name;
-        this.ident = functionNode.ident;
-        this.namespace = functionNode.namespace;
+        this.source          = functionNode.source;
+        this.name            = functionNode.name;
+        this.ident           = functionNode.ident;
+        this.namespace       = functionNode.namespace;
         this.declaredSymbols = functionNode.declaredSymbols;
-        this.kind  = functionNode.kind;
-        this.parameters = functionNode.parameters;
-        this.firstToken = functionNode.firstToken;
+        this.kind            = functionNode.kind;
+        this.firstToken      = functionNode.firstToken;
     }
 
     @Override
@@ -261,6 +288,61 @@
     }
 
     /**
+     * Get the source for this function
+     * @return the source
+     */
+    public Source getSource() {
+        return source;
+    }
+
+    /**
+     * Get the version of this function node's code as it looked upon construction
+     * i.e typically parsed and nothing else
+     * @return initial version of function node
+     */
+    public FunctionNode getSnapshot() {
+        return snapshot;
+    }
+
+    /**
+     * Throw away the snapshot, if any, to save memory. Used when heuristic
+     * determines that a method is not worth specializing
+     *
+     * @param lc lexical context
+     * @return new function node if a snapshot was present, now with snapsnot null
+     */
+    public FunctionNode clearSnapshot(final LexicalContext lc) {
+        if (this.snapshot == null) {
+            return this;
+        }
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body, parameters, null, hints));
+    }
+
+    /**
+     * Take a snapshot of this function node at a given point in time
+     * and store it in the function node
+     * @param lc lexical context
+     * @return function node
+     */
+    public FunctionNode snapshot(final LexicalContext lc) {
+        if (this.snapshot == this) {
+            return this;
+        }
+        if (isProgram() || parameters.isEmpty()) {
+            return this; //never specialize anything that won't be recompiled
+        }
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body, parameters, this, hints));
+    }
+
+    /**
+     * Can this function node be regenerated with more specific type args?
+     * @return true if specialization is possible
+     */
+    public boolean canSpecialize() {
+        return getFlag(CAN_SPECIALIZE);
+    }
+
+    /**
      * Get the compilation state of this function
      * @return the compilation state
      */
@@ -307,7 +389,28 @@
         }
         final EnumSet<CompilationState> newState = EnumSet.copyOf(this.compilationState);
         newState.add(state);
-        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, newState, body));
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, newState, body, parameters, snapshot, hints));
+    }
+
+    /**
+     * Get any compiler hints that may associated with the function
+     * @return compiler hints
+     */
+    public Compiler.Hints getHints() {
+        return this.hints == null ? Compiler.Hints.EMPTY : hints;
+    }
+
+    /**
+     * Set compiler hints for this function
+     * @param lc    lexical context
+     * @param hints compiler hints
+     * @return new function if hints changed
+     */
+    public FunctionNode setHints(final LexicalContext lc, final Compiler.Hints hints) {
+        if (this.hints == hints) {
+            return this;
+        }
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
     }
 
     /**
@@ -319,20 +422,6 @@
         return namespace.uniqueName(base);
     }
 
-    /**
-     * Create a virtual symbol for a literal.
-     *
-     * @param literalNode Primary node to use symbol.
-     *
-     * @return Symbol used.
-     */
-    public Symbol newLiteral(final LiteralNode<?> literalNode) {
-        final String uname = uniqueName(LITERAL_PREFIX.symbolName());
-        final Symbol symbol = new Symbol(uname, IS_CONSTANT, literalNode.getType());
-        literalNode.setSymbol(symbol);
-
-        return symbol;
-    }
 
     @Override
     public void toString(final StringBuilder sb) {
@@ -374,7 +463,7 @@
         if (this.flags == flags) {
             return this;
         }
-        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body));
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
     }
 
     @Override
@@ -483,7 +572,7 @@
         if(this.body == body) {
             return this;
         }
-        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body));
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
     }
 
     /**
@@ -551,7 +640,7 @@
         if (this.lastToken == lastToken) {
             return this;
         }
-        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body));
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
     }
 
     /**
@@ -599,13 +688,17 @@
     }
 
     /**
-     * Get a specialized type for an identity, if one exists
-     * @param node node to check specialized type for
-     * @return null if no specialization exists, otherwise type
+     * Reset the compile unit used to compile this function
+     * @see Compiler
+     * @param  lc lexical context
+     * @param  parameters the compile unit
+     * @return function node or a new one if state was changed
      */
-    @SuppressWarnings("static-method")
-    public Type getSpecializedType(final IdentNode node) {
-        return null; //TODO implement specialized types later
+    public FunctionNode setParameters(final LexicalContext lc, final List<IdentNode> parameters) {
+        if (this.parameters == parameters) {
+            return this;
+        }
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
     }
 
     /**
@@ -674,7 +767,10 @@
                     returnType),
                 compileUnit,
                 compilationState,
-                body));
+                body,
+                parameters,
+                snapshot,
+                hints));
     }
 
     /**
@@ -705,7 +801,7 @@
         if (this.compileUnit == compileUnit) {
             return this;
         }
-        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body));
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
     }
 
     /**
@@ -717,19 +813,6 @@
      *
      * @return Symbol used.
      */
-    public Symbol ensureSymbol(final Block block, final Type type, final Node node) {
-        Symbol symbol = node.getSymbol();
-
-        // If no symbol already present.
-        if (symbol == null) {
-            final String uname = uniqueName(TEMP_PREFIX.symbolName());
-            symbol = new Symbol(uname, IS_TEMP, type);
-            block.putSymbol(uname, symbol);
-            node.setSymbol(symbol);
-        }
-
-        return symbol;
-    }
 
     /**
      * Get the symbol for a compiler constant, or null if not available (yet)
@@ -739,5 +822,4 @@
     public Symbol compilerConstant(final CompilerConstants cc) {
         return body.getExistingSymbol(cc.symbolName());
     }
-
 }
diff --git a/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java b/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java
index daf79ee..2fb769a 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java
@@ -34,7 +34,6 @@
 import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation for an identifier.
@@ -56,14 +55,13 @@
     /**
      * Constructor
      *
-     * @param source  the source
      * @param token   token
      * @param finish  finish position
      * @param name    name of identifier
      */
-    public IdentNode(final Source source, final long token, final int finish, final String name) {
-        super(source, token, finish);
-        this.name = name;
+    public IdentNode(final long token, final int finish, final String name) {
+        super(token, finish);
+        this.name = name.intern();
         this.callSiteType = null;
         this.flags = 0;
     }
@@ -103,7 +101,7 @@
     }
 
     @Override
-    public IdentNode setType(final Type type) {
+    public IdentNode setType(final TemporarySymbols ts, final LexicalContext lc, final Type type) {
         // do NOT, repeat NOT touch the symbol here. it might be a local variable or whatever. This is the override if it isn't
         if (this.callSiteType == type) {
             return this;
diff --git a/nashorn/src/jdk/nashorn/internal/ir/IfNode.java b/nashorn/src/jdk/nashorn/internal/ir/IfNode.java
index 027e1a8..7731b30 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/IfNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/IfNode.java
@@ -27,13 +27,12 @@
 
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation for an IF statement.
  */
 @Immutable
-public final class IfNode extends Node {
+public final class IfNode extends Statement {
     /** Test expression. */
     private final Node test;
 
@@ -46,15 +45,15 @@
     /**
      * Constructor
      *
-     * @param source  the source
-     * @param token   token
-     * @param finish  finish
-     * @param test    test
-     * @param pass    block to execute when test passes
-     * @param fail    block to execute when test fails or null
+     * @param lineNumber line number
+     * @param token      token
+     * @param finish     finish
+     * @param test       test
+     * @param pass       block to execute when test passes
+     * @param fail       block to execute when test fails or null
      */
-    public IfNode(final Source source, final long token, final int finish, final Node test, final Block pass, final Block fail) {
-        super(source, token, finish);
+    public IfNode(final int lineNumber, final long token, final int finish, final Node test, final Block pass, final Block fail) {
+        super(lineNumber, token, finish);
         this.test = test;
         this.pass = pass;
         this.fail = fail;
diff --git a/nashorn/src/jdk/nashorn/internal/ir/IndexNode.java b/nashorn/src/jdk/nashorn/internal/ir/IndexNode.java
index 764ee38..a22c617 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/IndexNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/IndexNode.java
@@ -28,7 +28,6 @@
 import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation of an indexed access (brackets operator.)
@@ -41,14 +40,13 @@
     /**
      * Constructors
      *
-     * @param source  the source
      * @param token   token
      * @param finish  finish
      * @param base    base node for access
      * @param index   index for access
      */
-    public IndexNode(final Source source, final long token, final int finish, final Node base, final Node index) {
-        super(source, token, finish, base, false, false);
+    public IndexNode(final long token, final int finish, final Node base, final Node index) {
+        super(token, finish, base, false, false);
         this.index = index;
     }
 
@@ -108,6 +106,18 @@
         return index;
     }
 
+    /**
+     * Set the index expression for this node
+     * @param index new index expression
+     * @return a node equivalent to this one except for the requested change.
+     */
+    public IndexNode setIndex(Node index) {
+        if(this.index == index) {
+            return this;
+        }
+        return new IndexNode(this, base, index, isFunction(), hasCallSiteType());
+    }
+
     @Override
     public BaseNode setIsFunction() {
         if (isFunction()) {
@@ -117,10 +127,10 @@
     }
 
     @Override
-    public IndexNode setType(final Type type) {
+    public IndexNode setType(final TemporarySymbols ts, final LexicalContext lc, final Type type) {
         logTypeChange(type);
-        getSymbol().setTypeOverride(type); //always a temp so this is fine.
-        return new IndexNode(this, base, index, isFunction(), true);
+        final IndexNode newIndexNode = (IndexNode)setSymbol(lc, getSymbol().setTypeOverrideShared(type, ts));
+        return new IndexNode(newIndexNode, base, index, isFunction(), true);
     }
 
 }
diff --git a/nashorn/src/jdk/nashorn/internal/ir/LabelNode.java b/nashorn/src/jdk/nashorn/internal/ir/LabelNode.java
index bf932db..d791f3f 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/LabelNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/LabelNode.java
@@ -27,7 +27,6 @@
 
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation for a labeled statement.
@@ -43,14 +42,14 @@
     /**
      * Constructor
      *
-     * @param source the source
-     * @param token  token
-     * @param finish finish
-     * @param label  label identifier
-     * @param body   body of label node
+     * @param lineNumber line number
+     * @param token      token
+     * @param finish     finish
+     * @param label      label identifier
+     * @param body       body of label node
      */
-    public LabelNode(final Source source, final long token, final int finish, final IdentNode label, final Block body) {
-        super(source, token, finish);
+    public LabelNode(final int lineNumber, final long token, final int finish, final IdentNode label, final Block body) {
+        super(lineNumber, token, finish);
 
         this.label = label;
         this.body  = body;
diff --git a/nashorn/src/jdk/nashorn/internal/ir/LexicalContext.java b/nashorn/src/jdk/nashorn/internal/ir/LexicalContext.java
index c3f096f..13eb0aa 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/LexicalContext.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/LexicalContext.java
@@ -64,7 +64,6 @@
             for (int i = sp - 1; i >= 0; i--) {
                 if (stack[i] == node) {
                     flags[i] |= flag;
-                    //System.err.println("Setting flag " + node + " " + flag);
                     return;
                 }
             }
@@ -117,8 +116,6 @@
         return (FunctionNode)stack[0];
     }
 
-
-
     /**
      * Pushes a new block on top of the context, making it the innermost open block.
      * @param node the new node
@@ -395,8 +392,7 @@
      */
     public boolean isFunctionDefinedInCurrentCall(FunctionNode functionNode) {
         final LexicalContextNode parent = stack[sp - 2];
-        if(parent instanceof CallNode && ((CallNode)parent).getFunction() == functionNode) {
-            assert functionNode.getSource() == peek().getSource();
+        if (parent instanceof CallNode && ((CallNode)parent).getFunction() == functionNode) {
             return true;
         }
         return false;
@@ -543,13 +539,16 @@
             sb.append('@');
             sb.append(Debug.id(node));
             sb.append(':');
-            final Source source = node.getSource();
-            String src = source.toString();
-            if (src.indexOf(File.pathSeparator) != -1) {
-                src = src.substring(src.lastIndexOf(File.pathSeparator));
+            if (node instanceof FunctionNode) {
+                final Source source = ((FunctionNode)node).getSource();
+                String src = source.toString();
+                if (src.indexOf(File.pathSeparator) != -1) {
+                    src = src.substring(src.lastIndexOf(File.pathSeparator));
+                }
+                src += ' ';
+                src += source.getLine(node.getStart());
+                sb.append(src);
             }
-            src += ' ';
-            src += source.getLine(node.getStart());
             sb.append(' ');
         }
         sb.append(" ==> ]");
diff --git a/nashorn/src/jdk/nashorn/internal/ir/LexicalContextNode.java b/nashorn/src/jdk/nashorn/internal/ir/LexicalContextNode.java
index e48c6e0..52f62f0 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/LexicalContextNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/LexicalContextNode.java
@@ -25,22 +25,21 @@
 package jdk.nashorn.internal.ir;
 
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * Superclass for nodes that can be part of the lexical context
  * @see LexicalContext
  */
-public abstract class LexicalContextNode extends Node {
+public abstract class LexicalContextNode extends Statement {
     /**
      * Constructor
      *
-     * @param source source
-     * @param token  token
-     * @param finish finish
+     * @param lineNumber line number
+     * @param token      token
+     * @param finish     finish
      */
-    protected LexicalContextNode(final Source source, final long token, final int finish) {
-        super(source, token, finish);
+    protected LexicalContextNode(final int lineNumber, final long token, final int finish) {
+        super(lineNumber, token, finish);
     }
 
     /**
@@ -70,4 +69,16 @@
         final LexicalContextNode newNode = (LexicalContextNode)accept(lc, visitor);
         return lc.pop(newNode);
     }
+
+    /**
+     * Set the symbol and replace in lexical context if applicable
+     * @param lc     lexical context
+     * @param symbol symbol
+     * @return new node if symbol changed
+     */
+    @Override
+    public Node setSymbol(final LexicalContext lc, final Symbol symbol) {
+        return Node.replaceInLexicalContext(lc, this, (LexicalContextNode)super.setSymbol(null, symbol));
+    }
+
 }
diff --git a/nashorn/src/jdk/nashorn/internal/ir/LineNumberNode.java b/nashorn/src/jdk/nashorn/internal/ir/LineNumberNode.java
deleted file mode 100644
index 63f0459..0000000
--- a/nashorn/src/jdk/nashorn/internal/ir/LineNumberNode.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.nashorn.internal.ir;
-
-import jdk.nashorn.internal.ir.annotations.Immutable;
-import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.parser.Token;
-import jdk.nashorn.internal.runtime.Source;
-
-/**
- * IR Node representing a line number
- */
-@Immutable
-public final class LineNumberNode extends Node {
-    /** Line number */
-    private final int lineNumber;
-
-    /**
-     * Constructor
-     *
-     * @param source     the source
-     * @param token      token
-     * @param lineNumber the line number
-     */
-    public LineNumberNode(final Source source, final long token, final int lineNumber) {
-        super(source, token, Token.descPosition(token));
-        this.lineNumber = lineNumber;
-    }
-
-    private LineNumberNode(final LineNumberNode lineNumberNode) {
-        super(lineNumberNode);
-        this.lineNumber = lineNumberNode.getLineNumber();
-    }
-
-    @Override
-    public Node accept(final NodeVisitor visitor) {
-        if (visitor.enterLineNumberNode(this)) {
-            return visitor.leaveLineNumberNode(this);
-        }
-
-        return this;
-    }
-
-    @Override
-    public void toString(final StringBuilder sb) {
-        sb.append("[|");
-        sb.append(lineNumber);
-        sb.append("|]");
-    }
-
-    @Override
-    public boolean isAtom() {
-        return true;
-    }
-
-    /**
-     * Get the line number
-     * @return line number
-     */
-    public int getLineNumber() {
-        return lineNumber;
-    }
-
-    @Override
-    public boolean isDebug() {
-        return true;
-    }
-}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java b/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java
index ae80214..4c2f932 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java
@@ -37,7 +37,6 @@
 import jdk.nashorn.internal.parser.TokenType;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
-import jdk.nashorn.internal.runtime.Source;
 import jdk.nashorn.internal.runtime.Undefined;
 
 /**
@@ -50,16 +49,15 @@
     /** Literal value */
     protected final T value;
 
-     /**
+    /**
      * Constructor
      *
-     * @param source  the source
      * @param token   token
      * @param finish  finish
      * @param value   the value of the literal
      */
-    protected LiteralNode(final Source source, final long token, final int finish, final T value) {
-        super(source, token, finish);
+    protected LiteralNode(final long token, final int finish, final T value) {
+        super(token, finish);
         this.value = value;
     }
 
@@ -238,14 +236,13 @@
     /**
      * Create a new null literal
      *
-     * @param source  the source
      * @param token   token
      * @param finish  finish
      *
      * @return the new literal node
      */
-    public static LiteralNode<Node> newInstance(final Source source, final long token, final int finish) {
-        return new NodeLiteralNode(source, token, finish);
+    public static LiteralNode<Node> newInstance(final long token, final int finish) {
+        return new NodeLiteralNode(token, finish);
     }
 
     /**
@@ -256,14 +253,14 @@
      * @return the new literal node
      */
     public static LiteralNode<?> newInstance(final Node parent) {
-        return new NodeLiteralNode(parent.getSource(), parent.getToken(), parent.getFinish());
+        return new NodeLiteralNode(parent.getToken(), parent.getFinish());
     }
 
     @Immutable
     private static final class BooleanLiteralNode extends LiteralNode<Boolean> {
 
-        private BooleanLiteralNode(final Source source, final long token, final int finish, final boolean value) {
-            super(source, Token.recast(token, value ? TokenType.TRUE : TokenType.FALSE), finish, value);
+        private BooleanLiteralNode(final long token, final int finish, final boolean value) {
+            super(Token.recast(token, value ? TokenType.TRUE : TokenType.FALSE), finish, value);
         }
 
         private BooleanLiteralNode(final BooleanLiteralNode literalNode) {
@@ -289,15 +286,14 @@
     /**
      * Create a new boolean literal
      *
-     * @param source  the source
      * @param token   token
      * @param finish  finish
      * @param value   true or false
      *
      * @return the new literal node
      */
-    public static LiteralNode<Boolean> newInstance(final Source source, final long token, final int finish, final boolean value) {
-        return new BooleanLiteralNode(source, token,  finish, value);
+    public static LiteralNode<Boolean> newInstance(final long token, final int finish, final boolean value) {
+        return new BooleanLiteralNode(token, finish, value);
     }
 
     /**
@@ -309,7 +305,7 @@
      * @return the new literal node
      */
     public static LiteralNode<?> newInstance(final Node parent, final boolean value) {
-        return new BooleanLiteralNode(parent.getSource(), parent.getToken(), parent.getFinish(), value);
+        return new BooleanLiteralNode(parent.getToken(), parent.getFinish(), value);
     }
 
     @Immutable
@@ -317,8 +313,8 @@
 
         private final Type type = numberGetType(value);
 
-        private NumberLiteralNode(final Source source, final long token, final int finish, final Number value) {
-            super(source, Token.recast(token, TokenType.DECIMAL), finish, value);
+        private NumberLiteralNode(final long token, final int finish, final Number value) {
+            super(Token.recast(token, TokenType.DECIMAL), finish, value);
         }
 
         private NumberLiteralNode(final NumberLiteralNode literalNode) {
@@ -353,15 +349,14 @@
     /**
      * Create a new number literal
      *
-     * @param source  the source
      * @param token   token
      * @param finish  finish
      * @param value   literal value
      *
      * @return the new literal node
      */
-    public static LiteralNode<Number> newInstance(final Source source, final long token, final int finish, final Number value) {
-        return new NumberLiteralNode(source, token, finish, value);
+    public static LiteralNode<Number> newInstance(final long token, final int finish, final Number value) {
+        return new NumberLiteralNode(token, finish, value);
     }
 
     /**
@@ -373,12 +368,12 @@
      * @return the new literal node
      */
     public static LiteralNode<?> newInstance(final Node parent, final Number value) {
-        return new NumberLiteralNode(parent.getSource(), parent.getToken(), parent.getFinish(), value);
+        return new NumberLiteralNode(parent.getToken(), parent.getFinish(), value);
     }
 
     private static class UndefinedLiteralNode extends LiteralNode<Undefined> {
-        private UndefinedLiteralNode(final Source source, final long token, final int finish) {
-            super(source, Token.recast(token, TokenType.OBJECT), finish, ScriptRuntime.UNDEFINED);
+        private UndefinedLiteralNode(final long token, final int finish) {
+            super(Token.recast(token, TokenType.OBJECT), finish, ScriptRuntime.UNDEFINED);
         }
 
         private UndefinedLiteralNode(final UndefinedLiteralNode literalNode) {
@@ -389,15 +384,14 @@
     /**
      * Create a new undefined literal
      *
-     * @param source  the source
      * @param token   token
      * @param finish  finish
      * @param value   undefined value, passed only for polymorphisism discrimination
      *
      * @return the new literal node
      */
-    public static LiteralNode<Undefined> newInstance(final Source source, final long token, final int finish, final Undefined value) {
-        return new UndefinedLiteralNode(source, token, finish);
+    public static LiteralNode<Undefined> newInstance(final long token, final int finish, final Undefined value) {
+        return new UndefinedLiteralNode(token, finish);
     }
 
     /**
@@ -409,13 +403,13 @@
      * @return the new literal node
      */
     public static LiteralNode<?> newInstance(final Node parent, final Undefined value) {
-        return new UndefinedLiteralNode(parent.getSource(), parent.getToken(), parent.getFinish());
+        return new UndefinedLiteralNode(parent.getToken(), parent.getFinish());
     }
 
     @Immutable
     private static class StringLiteralNode extends LiteralNode<String> {
-        private StringLiteralNode(final Source source, final long token, final int finish, final String value) {
-            super(source, Token.recast(token, TokenType.STRING), finish, value);
+        private StringLiteralNode(final long token, final int finish, final String value) {
+            super(Token.recast(token, TokenType.STRING), finish, value);
         }
 
         private StringLiteralNode(final StringLiteralNode literalNode) {
@@ -433,15 +427,14 @@
     /**
      * Create a new string literal
      *
-     * @param source  the source
      * @param token   token
      * @param finish  finish
      * @param value   string value
      *
      * @return the new literal node
      */
-    public static LiteralNode<String> newInstance(final Source source, final long token, final int finish, final String value) {
-        return new StringLiteralNode(source, token, finish, value);
+    public static LiteralNode<String> newInstance(final long token, final int finish, final String value) {
+        return new StringLiteralNode(token, finish, value);
     }
 
     /**
@@ -453,13 +446,13 @@
      * @return the new literal node
      */
     public static LiteralNode<?> newInstance(final Node parent, final String value) {
-        return new StringLiteralNode(parent.getSource(), parent.getToken(), parent.getFinish(), value);
+        return new StringLiteralNode(parent.getToken(), parent.getFinish(), value);
     }
 
     @Immutable
     private static class LexerTokenLiteralNode extends LiteralNode<LexerToken> {
-        private LexerTokenLiteralNode(final Source source, final long token, final int finish, final LexerToken value) {
-            super(source, Token.recast(token, TokenType.STRING), finish, value); //TODO is string the correct token type here?
+        private LexerTokenLiteralNode(final long token, final int finish, final LexerToken value) {
+            super(Token.recast(token, TokenType.STRING), finish, value); //TODO is string the correct token type here?
         }
 
         private LexerTokenLiteralNode(final LexerTokenLiteralNode literalNode) {
@@ -480,15 +473,14 @@
     /**
      * Create a new literal node for a lexer token
      *
-     * @param source  the source
      * @param token   token
      * @param finish  finish
      * @param value   lexer token value
      *
      * @return the new literal node
      */
-    public static LiteralNode<LexerToken> newInstance(final Source source, final long token, final int finish, final LexerToken value) {
-        return new LexerTokenLiteralNode(source, token, finish, value);
+    public static LiteralNode<LexerToken> newInstance(final long token, final int finish, final LexerToken value) {
+        return new LexerTokenLiteralNode(token, finish, value);
     }
 
     /**
@@ -500,17 +492,17 @@
      * @return the new literal node
      */
     public static LiteralNode<?> newInstance(final Node parent, final LexerToken value) {
-        return new LexerTokenLiteralNode(parent.getSource(), parent.getToken(), parent.getFinish(), value);
+        return new LexerTokenLiteralNode(parent.getToken(), parent.getFinish(), value);
     }
 
     private static final class NodeLiteralNode extends LiteralNode<Node> {
 
-        private NodeLiteralNode(final Source source, final long token, final int finish) {
-            this(source, token, finish, null);
+        private NodeLiteralNode(final long token, final int finish) {
+            this(token, finish, null);
         }
 
-        private NodeLiteralNode(final Source source, final long token, final int finish, final Node value) {
-            super(source, Token.recast(token, TokenType.OBJECT), finish, value);
+        private NodeLiteralNode(final long token, final int finish, final Node value) {
+            super(Token.recast(token, TokenType.OBJECT), finish, value);
         }
 
         private NodeLiteralNode(final LiteralNode<Node> literalNode) {
@@ -550,15 +542,14 @@
     /**
      * Create a new node literal for an arbitrary node
      *
-     * @param source  the source
      * @param token   token
      * @param finish  finish
      * @param value   the literal value node
      *
      * @return the new literal node
      */
-    public static LiteralNode<Node> newInstance(final Source source, final long token, final int finish, final Node value) {
-        return new NodeLiteralNode(source, token, finish, value);
+    public static LiteralNode<Node> newInstance(final long token, final int finish, final Node value) {
+        return new NodeLiteralNode(token, finish, value);
     }
 
     /**
@@ -570,7 +561,7 @@
      * @return the new literal node
      */
     public static LiteralNode<?> newInstance(final Node parent, final Node value) {
-        return new NodeLiteralNode(parent.getSource(), parent.getToken(), parent.getFinish(), value);
+        return new NodeLiteralNode(parent.getToken(), parent.getFinish(), value);
     }
 
     /**
@@ -645,13 +636,12 @@
         /**
          * Constructor
          *
-         * @param source  the source
          * @param token   token
          * @param finish  finish
          * @param value   array literal value, a Node array
          */
-        protected ArrayLiteralNode(final Source source, final long token, final int finish, final Node[] value) {
-            super(source, Token.recast(token, TokenType.ARRAY), finish, value);
+        protected ArrayLiteralNode(final long token, final int finish, final Node[] value) {
+            super(Token.recast(token, TokenType.ARRAY), finish, value);
             this.elementType = Type.UNKNOWN;
         }
 
@@ -659,9 +649,12 @@
          * Copy constructor
          * @param node source array literal node
          */
-        protected ArrayLiteralNode(final ArrayLiteralNode node) {
-            super(node);
+        private ArrayLiteralNode(final ArrayLiteralNode node, final Node[] value) {
+            super(node, value);
             this.elementType = node.elementType;
+            this.presets     = node.presets;
+            this.postsets    = node.postsets;
+            this.units       = node.units;
         }
 
         /**
@@ -750,9 +743,8 @@
                     break;
                 }
 
-                final Symbol symbol = node.getSymbol();
-                assert symbol != null; //don't run this on unresolved nodes or you are in trouble
-                Type symbolType = symbol.getSymbolType();
+                assert node.getSymbol() != null; //don't run this on unresolved nodes or you are in trouble
+                Type symbolType = node.getSymbol().getSymbolType();
                 if (symbolType.isUnknown()) {
                     symbolType = Type.OBJECT;
                 }
@@ -813,7 +805,8 @@
         }
 
         /**
-         * Get indices of arrays containing computed post sets
+         * Get indices of arrays containing computed post sets. post sets
+         * are things like non literals e.g. "x+y" instead of i or 17
          * @return post set indices
          */
         public int[] getPostsets() {
@@ -849,17 +842,17 @@
         @Override
         public Node accept(final NodeVisitor visitor) {
             if (visitor.enterLiteralNode(this)) {
-                for (int i = 0; i < value.length; i++) {
-                    final Node element = value[i];
-                    if (element != null) {
-                        value[i] = element.accept(visitor);
-                    }
-                }
-                return visitor.leaveLiteralNode(this);
+                final List<Node> oldValue = Arrays.asList(value);
+                final List<Node> newValue = Node.accept(visitor, Node.class, oldValue);
+                return visitor.leaveLiteralNode(oldValue != newValue ? setValue(newValue) : this);
             }
             return this;
         }
 
+        private ArrayLiteralNode setValue(final List<Node> value) {
+            return new ArrayLiteralNode(this, value.toArray(new Node[value.size()]));
+        }
+
         @Override
         public void toString(final StringBuilder sb) {
             sb.append('[');
@@ -883,15 +876,14 @@
     /**
      * Create a new array literal of Nodes from a list of Node values
      *
-     * @param source  the source
      * @param token   token
      * @param finish  finish
      * @param value   literal value list
      *
      * @return the new literal node
      */
-    public static LiteralNode<Node[]> newInstance(final Source source, final long token, final int finish, final List<Node> value) {
-        return new ArrayLiteralNode(source, token, finish, value.toArray(new Node[value.size()]));
+    public static LiteralNode<Node[]> newInstance(final long token, final int finish, final List<Node> value) {
+        return new ArrayLiteralNode(token, finish, value.toArray(new Node[value.size()]));
     }
 
 
@@ -904,20 +896,19 @@
      * @return the new literal node
      */
     public static LiteralNode<?> newInstance(final Node parent, final List<Node> value) {
-        return new ArrayLiteralNode(parent.getSource(), parent.getToken(), parent.getFinish(), value.toArray(new Node[value.size()]));
+        return new ArrayLiteralNode(parent.getToken(), parent.getFinish(), value.toArray(new Node[value.size()]));
     }
 
     /**
      * Create a new array literal of Nodes
      *
-     * @param source  the source
      * @param token   token
      * @param finish  finish
      * @param value   literal value array
      *
      * @return the new literal node
      */
-    public static LiteralNode<Node[]> newInstance(final Source source, final long token, final int finish, final Node[] value) {
-        return new ArrayLiteralNode(source, token, finish, value);
+    public static LiteralNode<Node[]> newInstance(final long token, final int finish, final Node[] value) {
+        return new ArrayLiteralNode(token, finish, value);
     }
 }
diff --git a/nashorn/src/jdk/nashorn/internal/ir/Location.java b/nashorn/src/jdk/nashorn/internal/ir/Location.java
deleted file mode 100644
index cd9edb5..0000000
--- a/nashorn/src/jdk/nashorn/internal/ir/Location.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.nashorn.internal.ir;
-
-import jdk.nashorn.internal.parser.Token;
-import jdk.nashorn.internal.parser.TokenType;
-import jdk.nashorn.internal.runtime.Source;
-
-/**
- * Used to locate an entity back to it's source file.
- */
-public class Location implements Cloneable {
-    /** Source of entity. */
-    private final Source source;
-
-    /** Token descriptor. */
-    private final long token;
-
-    /**
-     * Constructor
-     *
-     * @param source the source
-     * @param token  token
-     */
-    public Location(final Source source, final long token) {
-        this.source = source;
-        this.token = token;
-    }
-
-    /**
-     * Copy constructor
-     *
-     * @param location source node
-     */
-    protected Location(final Location location) {
-        this.source = location.source;
-        this.token = location.token;
-    }
-
-    @Override
-    protected Object clone() {
-        try {
-            return super.clone();
-        } catch(CloneNotSupportedException e) {
-            throw new AssertionError(e);
-        }
-    }
-
-    @Override
-    public final boolean equals(final Object other) {
-        return super.equals(other);
-    }
-
-    @Override
-    public final int hashCode() {
-        return super.hashCode();
-    }
-
-    /**
-     * Return token position from a token descriptor.
-     *
-     * @return Start position of the token in the source.
-     */
-    public int position() {
-        return Token.descPosition(token);
-    }
-
-    /**
-     * Return token length from a token descriptor.
-     *
-     * @return Length of the token.
-     */
-    public int length() {
-        return Token.descLength(token);
-    }
-
-    /**
-     * Return token tokenType from a token descriptor.
-     *
-     * @return Type of token.
-     */
-    public TokenType tokenType() {
-        return Token.descType(token);
-    }
-
-    /**
-     * Test token tokenType.
-     *
-     * @param type a type to check this token against
-     * @return true if token types match.
-     */
-    public boolean isTokenType(final TokenType type) {
-        return Token.descType(token) == type;
-    }
-
-    /**
-     * Get the source for this location
-     * @return the source
-     */
-    public Source getSource() {
-        return source;
-    }
-
-    /**
-     * Get the token for this location
-     * @return the token
-     */
-    public long getToken() {
-        return token;
-    }
-}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/LoopNode.java b/nashorn/src/jdk/nashorn/internal/ir/LoopNode.java
index b3909dc..4a4fd3b 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/LoopNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/LoopNode.java
@@ -29,7 +29,6 @@
 import java.util.List;
 
 import jdk.nashorn.internal.codegen.Label;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * A loop node, for example a while node, do while node or for node
@@ -50,15 +49,15 @@
     /**
      * Constructor
      *
-     * @param source  source
-     * @param token   token
-     * @param finish  finish
-     * @param test    test, or null if infinite loop
-     * @param body    loop body
+     * @param lineNumber         lineNumber
+     * @param token              token
+     * @param finish             finish
+     * @param test               test, or null if infinite loop
+     * @param body               loop body
      * @param controlFlowEscapes controlFlowEscapes
      */
-    protected LoopNode(final Source source, final long token, final int finish, final Node test, final Block body, final boolean controlFlowEscapes) {
-        super(source, token, finish, new Label("while_break"));
+    protected LoopNode(final int lineNumber, final long token, final int finish, final Node test, final Block body, final boolean controlFlowEscapes) {
+        super(lineNumber, token, finish, new Label("while_break"));
         this.continueLabel = new Label("while_continue");
         this.test = test;
         this.body = body;
diff --git a/nashorn/src/jdk/nashorn/internal/ir/Node.java b/nashorn/src/jdk/nashorn/internal/ir/Node.java
index dfed903..0fb95cc 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/Node.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/Node.java
@@ -27,16 +27,15 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
 import jdk.nashorn.internal.parser.Token;
-import jdk.nashorn.internal.runtime.Source;
+import jdk.nashorn.internal.parser.TokenType;
 
 /**
  * Nodes are used to compose Abstract Syntax Trees.
  */
-public abstract class Node extends Location {
+public abstract class Node implements Cloneable {
     /** Node symbol. */
     private Symbol symbol;
 
@@ -46,16 +45,17 @@
     /** End of source range. */
     protected int finish;
 
+    /** Token descriptor. */
+    private final long token;
+
     /**
      * Constructor
      *
-     * @param source the source
      * @param token  token
      * @param finish finish
      */
-    public Node(final Source source, final long token, final int finish) {
-        super(source, token);
-
+    public Node(final long token, final int finish) {
+        this.token  = token;
         this.start  = Token.descPosition(token);
         this.finish = finish;
     }
@@ -63,16 +63,14 @@
     /**
      * Constructor
      *
-     * @param source  source
      * @param token   token
      * @param start   start
      * @param finish  finish
      */
-    protected Node(final Source source, final long token, final int start, final int finish) {
-        super(source, token);
-
+    protected Node(final long token, final int start, final int finish) {
         this.start = start;
         this.finish = finish;
+        this.token = token;
     }
 
     /**
@@ -81,8 +79,7 @@
      * @param node source node
      */
     protected Node(final Node node) {
-        super(node);
-
+        this.token  = node.token;
         this.symbol = node.symbol;
         this.start  = node.start;
         this.finish = node.finish;
@@ -156,15 +153,6 @@
     }
 
     /**
-     * Is this a debug info node like LineNumberNode etc?
-     *
-     * @return true if this is a debug node
-     */
-    public boolean isDebug() {
-        return false;
-    }
-
-    /**
      * For reference copies - ensure that labels in the copy node are unique
      * using an appropriate copy constructor
      * @param lc lexical context
@@ -248,14 +236,86 @@
         return symbol;
     }
 
+    @Override
+    protected Object clone() {
+        try {
+            return super.clone();
+        } catch (final CloneNotSupportedException e) {
+            throw new AssertionError(e);
+        }
+    }
+
     /**
      * Assign a symbol to this node. See {@link Node#getSymbol()} for explanation
      * of what a symbol is
      *
+     * @param lc lexical context
      * @param symbol the symbol
+     * @return new node
      */
-    public void setSymbol(final Symbol symbol) {
-        this.symbol = symbol;
+    public Node setSymbol(final LexicalContext lc, final Symbol symbol) {
+        if (this.symbol == symbol) {
+            return this;
+        }
+        final Node newNode = (Node)clone();
+        newNode.symbol = symbol;
+        return newNode;
+    }
+
+
+    @Override
+    public final boolean equals(final Object other) {
+        return super.equals(other);
+    }
+
+    @Override
+    public final int hashCode() {
+        return super.hashCode();
+    }
+
+    /**
+     * Return token position from a token descriptor.
+     *
+     * @return Start position of the token in the source.
+     */
+    public int position() {
+        return Token.descPosition(token);
+    }
+
+    /**
+     * Return token length from a token descriptor.
+     *
+     * @return Length of the token.
+     */
+    public int length() {
+        return Token.descLength(token);
+    }
+
+    /**
+     * Return token tokenType from a token descriptor.
+     *
+     * @return Type of token.
+     */
+    public TokenType tokenType() {
+        return Token.descType(token);
+    }
+
+    /**
+     * Test token tokenType.
+     *
+     * @param type a type to check this token against
+     * @return true if token types match.
+     */
+    public boolean isTokenType(final TokenType type) {
+        return Token.descType(token) == type;
+    }
+
+    /**
+     * Get the token for this location
+     * @return the token
+     */
+    public long getToken() {
+        return token;
     }
 
     /**
@@ -274,7 +334,7 @@
         final List<T> newList = new ArrayList<>();
 
         for (final Node node : list) {
-            final T newNode = clazz.cast(node.accept(visitor));
+            final T newNode = node == null ? null : clazz.cast(node.accept(visitor));
             if (newNode != node) {
                 changed = true;
             }
diff --git a/nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java b/nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java
index 744a44d..3406972 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java
@@ -30,7 +30,6 @@
 
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation of an object literal.
@@ -44,13 +43,12 @@
     /**
      * Constructor
      *
-     * @param source   the source
      * @param token    token
      * @param finish   finish
      * @param elements the elements used to initialize this ObjectNode
      */
-    public ObjectNode(final Source source, final long token, final int finish, final List<Node> elements) {
-        super(source, token, finish);
+    public ObjectNode(final long token, final int finish, final List<Node> elements) {
+        super(token, finish);
         this.elements = elements;
     }
 
diff --git a/nashorn/src/jdk/nashorn/internal/ir/PropertyNode.java b/nashorn/src/jdk/nashorn/internal/ir/PropertyNode.java
index 635e1aa..7040d41 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/PropertyNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/PropertyNode.java
@@ -27,7 +27,6 @@
 
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation of an object literal property.
@@ -50,7 +49,6 @@
     /**
      * Constructor
      *
-     * @param source  the source
      * @param token   token
      * @param finish  finish
      * @param key     the key of this property
@@ -58,8 +56,8 @@
      * @param getter  getter function body
      * @param setter  setter function body
      */
-    public PropertyNode(final Source source, final long token, final int finish, final PropertyKey key, final Node value, final FunctionNode getter, final FunctionNode setter) {
-        super(source, token, finish);
+    public PropertyNode(final long token, final int finish, final PropertyKey key, final Node value, final FunctionNode getter, final FunctionNode setter) {
+        super(token, finish);
         this.key    = key;
         this.value  = value;
         this.getter = getter;
diff --git a/nashorn/src/jdk/nashorn/internal/ir/ReturnNode.java b/nashorn/src/jdk/nashorn/internal/ir/ReturnNode.java
index dafc956..c0091eb 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/ReturnNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/ReturnNode.java
@@ -29,26 +29,25 @@
 import static jdk.nashorn.internal.parser.TokenType.YIELD;
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation for RETURN or YIELD statements.
  */
 @Immutable
-public class ReturnNode extends Node {
+public class ReturnNode extends Statement {
     /** Optional expression. */
     private final Node expression;
 
     /**
      * Constructor
      *
-     * @param source     the source
+     * @param lineNumber line number
      * @param token      token
      * @param finish     finish
      * @param expression expression to return
      */
-    public ReturnNode(final Source source, final long token, final int finish, final Node expression) {
-        super(source, token, finish);
+    public ReturnNode(final int lineNumber, final long token, final int finish, final Node expression) {
+        super(lineNumber, token, finish);
         this.expression = expression;
     }
 
@@ -101,9 +100,9 @@
 
     @Override
     public void toString(final StringBuilder sb) {
-        sb.append(isYield() ? "yield" : "return ");
-
+        sb.append(isYield() ? "yield" : "return");
         if (expression != null) {
+            sb.append(' ');
             expression.toString(sb);
         }
     }
diff --git a/nashorn/src/jdk/nashorn/internal/ir/RuntimeNode.java b/nashorn/src/jdk/nashorn/internal/ir/RuntimeNode.java
index 7bdb6c0..47509be 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/RuntimeNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/RuntimeNode.java
@@ -33,7 +33,6 @@
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
 import jdk.nashorn.internal.parser.TokenType;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation for a runtime call.
@@ -280,14 +279,13 @@
     /**
      * Constructor
      *
-     * @param source  the source
      * @param token   token
      * @param finish  finish
      * @param request the request
      * @param args    arguments to request
      */
-    public RuntimeNode(final Source source, final long token, final int finish, final Request request, final List<Node> args) {
-        super(source, token, finish);
+    public RuntimeNode(final long token, final int finish, final Request request, final List<Node> args) {
+        super(token, finish);
 
         this.request      = request;
         this.args         = args;
@@ -307,14 +305,13 @@
     /**
      * Constructor
      *
-     * @param source  the source
      * @param token   token
      * @param finish  finish
      * @param request the request
      * @param args    arguments to request
      */
-    public RuntimeNode(final Source source, final long token, final int finish, final Request request, final Node... args) {
-        this(source, token, finish, request, Arrays.asList(args));
+    public RuntimeNode(final long token, final int finish, final Request request, final Node... args) {
+        this(token, finish, request, Arrays.asList(args));
     }
 
     /**
@@ -393,7 +390,7 @@
     }
 
     @Override
-    public RuntimeNode setType(final Type type) {
+    public RuntimeNode setType(final TemporarySymbols ts, final LexicalContext lc, final Type type) {
         if (this.callSiteType == type) {
             return this;
         }
diff --git a/nashorn/src/jdk/nashorn/internal/ir/SplitNode.java b/nashorn/src/jdk/nashorn/internal/ir/SplitNode.java
index 49c4092..ee6e023 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/SplitNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/SplitNode.java
@@ -46,12 +46,13 @@
     /**
      * Constructor
      *
+     * @param lineNumber  lineNumber
      * @param name        name of split node
      * @param body        body of split code
      * @param compileUnit compile unit to use for the body
      */
-    public SplitNode(final String name, final Node body, final CompileUnit compileUnit) {
-        super(body.getSource(), body.getToken(), body.getFinish());
+    public SplitNode(final int lineNumber, final String name, final Node body, final CompileUnit compileUnit) {
+        super(lineNumber, body.getToken(), body.getFinish());
         this.name        = name;
         this.body        = body;
         this.compileUnit = compileUnit;
diff --git a/nashorn/src/jdk/nashorn/internal/ir/Statement.java b/nashorn/src/jdk/nashorn/internal/ir/Statement.java
new file mode 100644
index 0000000..6b171cb
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/Statement.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.internal.ir;
+
+/**
+ * Statement is something that becomes code and can be stepped past. A block is
+ * made up of statements. The only node subclass that needs to keep token and
+ * location information is the Statement
+ */
+public abstract class Statement extends Node {
+
+    private final int lineNumber;
+
+    /**
+     * Constructor
+     *
+     * @param lineNumber line number
+     * @param token      token
+     * @param finish     finish
+     */
+    public Statement(final int lineNumber, final long token, final int finish) {
+        super(token, finish);
+        this.lineNumber = lineNumber;
+    }
+
+    /**
+     * Constructor
+     *
+     * @param lineNumber line number
+     * @param token      token
+     * @param start      start
+     * @param finish     finish
+     */
+    protected Statement(final int lineNumber, final long token, final int start, final int finish) {
+        super(token, start, finish);
+        this.lineNumber = lineNumber;
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param node source node
+     */
+    protected Statement(final Statement node) {
+        super(node);
+        this.lineNumber = node.lineNumber;
+    }
+
+    /**
+     * Return the line number
+     * @return line number
+     */
+    public int getLineNumber() {
+        return lineNumber;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/SwitchNode.java b/nashorn/src/jdk/nashorn/internal/ir/SwitchNode.java
index 7864a10..bfc0310 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/SwitchNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/SwitchNode.java
@@ -32,7 +32,6 @@
 import jdk.nashorn.internal.codegen.Label;
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation of a SWITCH statement.
@@ -54,15 +53,15 @@
     /**
      * Constructor
      *
-     * @param source      the source
+     * @param lineNumber  lineNumber
      * @param token       token
      * @param finish      finish
      * @param expression  switch expression
      * @param cases       cases
      * @param defaultCase the default case node - null if none, otherwise has to be present in cases list
      */
-    public SwitchNode(final Source source, final long token, final int finish, final Node expression, final List<CaseNode> cases, final CaseNode defaultCase) {
-        super(source, token, finish, new Label("switch_break"));
+    public SwitchNode(final int lineNumber, final long token, final int finish, final Node expression, final List<CaseNode> cases, final CaseNode defaultCase) {
+        super(lineNumber, token, finish, new Label("switch_break"));
         this.expression       = expression;
         this.cases            = cases;
         this.defaultCaseIndex = defaultCase == null ? -1 : cases.indexOf(defaultCase);
diff --git a/nashorn/src/jdk/nashorn/internal/ir/Symbol.java b/nashorn/src/jdk/nashorn/internal/ir/Symbol.java
index da22f64..0549515 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/Symbol.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/Symbol.java
@@ -29,7 +29,6 @@
 import java.util.HashSet;
 import java.util.Set;
 import java.util.StringTokenizer;
-
 import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.Debug;
@@ -67,6 +66,10 @@
     public static final int IS_INTERNAL      = 1 << 9;
     /** Is this a function self-reference symbol */
     public static final int IS_FUNCTION_SELF = 1 << 10;
+    /** Is this a specialized param? */
+    public static final int IS_SPECIALIZED_PARAM = 1 << 11;
+    /** Is this symbol a shared temporary? */
+    public static final int IS_SHARED = 1 << 12;
 
     /** Null or name identifying symbol. */
     private final String name;
@@ -152,6 +155,16 @@
         this(name, flags, type, -1);
     }
 
+    private Symbol(final Symbol base, final String name, final int flags) {
+        this.flags = flags;
+        this.name = name;
+
+        this.fieldIndex = base.fieldIndex;
+        this.slot = base.slot;
+        this.type = base.type;
+        this.useCount = base.useCount;
+    }
+
     private static String align(final String string, final int max) {
         final StringBuilder sb = new StringBuilder();
         sb.append(string.substring(0, Math.min(string.length(), max)));
@@ -261,32 +274,14 @@
         return type.isCategory2() ? 2 : 1;
     }
 
-    private static String type(final String desc) {
-        switch (desc.charAt(desc.length() - 1)) {
-        case ';':
-            return desc;//"obj";
-        case 'D':
-            return "double";
-        case 'I':
-            return "int";
-        case 'J':
-            return "long";
-        case 'Z':
-            return "boolean";
-        default:
-            return "UNKNOWN";
-        }
-    }
-
     @Override
     public String toString() {
         final StringBuilder sb   = new StringBuilder();
-        final String        desc = getSymbolType().getDescriptor();
 
         sb.append(name).
             append(' ').
             append('(').
-            append(type(desc)).
+            append(getSymbolType().getTypeClass().getSimpleName()).
             append(')');
 
         if (hasSlot()) {
@@ -347,6 +342,24 @@
     }
 
     /**
+     * Returns true if this symbol is a temporary that is being shared across expressions.
+     * @return true if this symbol is a temporary that is being shared across expressions.
+     */
+    public boolean isShared() {
+        return (flags & IS_SHARED) == IS_SHARED;
+    }
+
+    /**
+     * Creates an unshared copy of a symbol. The symbol must be currently shared.
+     * @param newName the name for the new symbol.
+     * @return a new, unshared symbol.
+     */
+    public Symbol createUnshared(final String newName) {
+        assert isShared();
+        return new Symbol(this, newName, flags & ~IS_SHARED);
+    }
+
+    /**
      * Flag this symbol as scope as described in {@link Symbol#isScope()}
      */
     /**
@@ -355,10 +368,23 @@
      public void setIsScope() {
         if (!isScope()) {
             trace("SET IS SCOPE");
+            assert !isShared();
+            flags |= IS_SCOPE;
         }
-        flags |= IS_SCOPE;
     }
 
+     /**
+      * Mark this symbol as one being shared by multiple expressions. The symbol must be a temporary.
+      */
+     public void setIsShared() {
+         if(!isShared()) {
+             assert isTemp();
+             trace("SET IS SHARED");
+             flags |= IS_SHARED;
+         }
+     }
+
+
     /**
      * Check if this symbol is a variable
      * @return true if variable
@@ -384,6 +410,15 @@
     }
 
     /**
+     * Check if this symbol is a function parameter of known
+     * narrowest type
+     * @return true if parameter
+     */
+    public boolean isSpecializedParam() {
+        return (flags & IS_SPECIALIZED_PARAM) == IS_SPECIALIZED_PARAM;
+    }
+
+    /**
      * Check whether this symbol ever has primitive assignments. Conservative
      * @return true if primitive assignments exist
      */
@@ -404,7 +439,10 @@
      */
     public void setCanBeUndefined() {
         assert type.isObject() : type;
-        flags |= CAN_BE_UNDEFINED;
+        if(!canBeUndefined()) {
+            assert !isShared();
+            flags |= CAN_BE_UNDEFINED;
+        }
     }
 
     /**
@@ -412,7 +450,10 @@
      * @param type the primitive type it occurs with, currently unused but can be used for width guesses
      */
     public void setCanBePrimitive(final Type type) {
-        flags |= CAN_BE_PRIMITIVE;
+        if(!canBePrimitive()) {
+            assert !isShared();
+            flags |= CAN_BE_PRIMITIVE;
+        }
     }
 
     /**
@@ -452,7 +493,10 @@
      * Flag this symbol as a let
      */
     public void setIsLet() {
-        flags |= IS_LET;
+        if(!isLet()) {
+            assert !isShared();
+            flags |= IS_LET;
+        }
     }
 
     /**
@@ -481,7 +525,10 @@
      * @param fieldIndex field index - a positive integer
      */
     public void setFieldIndex(final int fieldIndex) {
-        this.fieldIndex = fieldIndex;
+        if(this.fieldIndex != fieldIndex) {
+            assert !isShared();
+            this.fieldIndex = fieldIndex;
+        }
     }
 
     /**
@@ -497,7 +544,10 @@
      * @param flags flags
      */
     public void setFlags(final int flags) {
-        this.flags = flags;
+        if(this.flags != flags) {
+            assert !isShared();
+            this.flags = flags;
+        }
     }
 
     /**
@@ -537,6 +587,7 @@
      */
     public void setSlot(final int slot) {
         if (slot != this.slot) {
+            assert !isShared();
             trace("SET SLOT " + slot);
             this.slot = slot;
         }
@@ -562,6 +613,15 @@
     }
 
     /**
+     * Returns true if calling {@link #setType(Type)} on this symbol would effectively change its type.
+     * @param newType the new type to test for
+     * @return true if setting this symbols type to a new value would effectively change its type.
+     */
+    public boolean wouldChangeType(final Type newType) {
+        return Type.widest(this.type, newType) != this.type;
+    }
+
+    /**
      * Only use this if you know about an existing type
      * constraint - otherwise a type can only be
      * widened
@@ -571,12 +631,33 @@
     public void setTypeOverride(final Type type) {
         final Type old = this.type;
         if (old != type) {
+            assert !isShared();
             trace("TYPE CHANGE: " + old + "=>" + type + " == " + type);
             this.type = type;
         }
     }
 
     /**
+     * Sets the type of the symbol to the specified type. If the type would be changed, but this symbol is a shared
+     * temporary, it will instead return a different temporary symbol of the requested type from the passed temporary
+     * symbols. That way, it never mutates the type of a shared temporary.
+     * @param type the new type for the symbol
+     * @param ts a holder of temporary symbols
+     * @return either this symbol, or a different symbol if this symbol is a shared temporary and it type would have to
+     * be changed.
+     */
+    public Symbol setTypeOverrideShared(final Type type, final TemporarySymbols ts) {
+        if(getSymbolType() != type) {
+            if(isShared()) {
+                assert !hasSlot();
+                return ts.getTypedTemporarySymbol(type);
+            }
+            setTypeOverride(type);
+        }
+        return this;
+    }
+
+    /**
      * From a lexical context, set this symbol as needing scope, which
      * will set flags for the defining block that will be written when
      * block is popped from the lexical context stack, used by codegen
diff --git a/nashorn/src/jdk/nashorn/internal/ir/TemporarySymbols.java b/nashorn/src/jdk/nashorn/internal/ir/TemporarySymbols.java
new file mode 100644
index 0000000..ee8069e
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/TemporarySymbols.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.internal.ir;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.TEMP_PREFIX;
+import static jdk.nashorn.internal.ir.Symbol.IS_TEMP;
+
+import java.util.HashMap;
+import java.util.Map;
+import jdk.nashorn.internal.codegen.types.Type;
+
+/**
+ * Class that holds reusable temporary symbols by type.
+ *
+ */
+public class TemporarySymbols {
+    private static final String prefix = TEMP_PREFIX.symbolName() + "$";
+
+    private int totalSymbolCount;
+    private final Map<Type, TypedTemporarySymbols> temporarySymbolsByType = new HashMap<>();
+
+    /**
+     * Associates a temporary symbol of a given type with a node, if the node doesn't already have any symbol.
+     * @param lc the current lexical context
+     * @param type the type of the temporary symbol
+     * @param node the node
+     * @return the node that is guaranteed to have a symbol.
+     */
+    public Node ensureSymbol(final LexicalContext lc, final Type type, final Node node) {
+        final Symbol symbol = node.getSymbol();
+        if (symbol != null) {
+            return node;
+        }
+        return node.setSymbol(lc, getTypedTemporarySymbol(type));
+    }
+
+    /**
+     * Given a type, returns a temporary symbol of that type.
+     * @param type the required type of the symbol.
+     * @return a temporary symbol of the required type.
+     */
+    public Symbol getTypedTemporarySymbol(final Type type) {
+        return getTypedTemporarySymbols(type).getTemporarySymbol(type);
+    }
+
+    private TypedTemporarySymbols getTypedTemporarySymbols(final Type type) {
+        TypedTemporarySymbols temporarySymbols = temporarySymbolsByType.get(type);
+        if(temporarySymbols == null) {
+            temporarySymbols = new TypedTemporarySymbols();
+            temporarySymbolsByType.put(type, temporarySymbols);
+        }
+        return temporarySymbols;
+    }
+
+    /**
+     * This method is called to signal to this object that all the symbols it holds can be reused now.
+     */
+    public void reuse() {
+        for(TypedTemporarySymbols ts: temporarySymbolsByType.values()) {
+            ts.reuse();
+        }
+    }
+
+    /**
+     * Given a shared symbol, creates an unshared copy of it with a unique name.
+     * @param symbol the shared symbol
+     * @return the unshared, uniquely named copy of the symbol
+     */
+    public Symbol createUnshared(Symbol symbol) {
+        return symbol.createUnshared(getUniqueName());
+    }
+
+    private String getUniqueName() {
+        return prefix + (++totalSymbolCount);
+    }
+
+    /**
+     * Returns the total number of symbols this object created during its lifetime.
+     * @return the total number of symbols this object created during its lifetime.
+     */
+    public int getTotalSymbolCount() {
+        return totalSymbolCount;
+    }
+
+    private class TypedTemporarySymbols {
+        private Symbol[] symbols = new Symbol[16];
+        private int nextFreeSymbol = 0;
+        private int symbolCount = 0;
+
+        Symbol getTemporarySymbol(final Type type) {
+            while(nextFreeSymbol < symbolCount) {
+                final Symbol nextSymbol = symbols[nextFreeSymbol];
+                assert nextSymbol != null;
+                // If it has a slot, we can't reuse it.
+                if(!nextSymbol.hasSlot()) {
+                    final Type symbolType = nextSymbol.getSymbolType();
+                    if(symbolType == type) {
+                        assert nextSymbol.isTemp();
+                        assert !nextSymbol.isScope();
+                        // If types match, we can reuse it.
+                        nextSymbol.setIsShared();
+                        nextFreeSymbol++;
+                        return nextSymbol;
+                    }
+                    // If its type changed, but it doesn't have a slot then move it to its new home according to its
+                    // new type.
+                    getTypedTemporarySymbols(symbolType).addSymbol(nextSymbol);
+                }
+                // If we can move another symbol into its place, do that and repeat the analysis for this symbol.
+                --symbolCount;
+                if(symbolCount != nextFreeSymbol) {
+                    final Symbol lastFreeSymbol = symbols[symbolCount];
+                    symbols[nextFreeSymbol] = lastFreeSymbol;
+                }
+                symbols[symbolCount] = null;
+            }
+            return createNewSymbol(type);
+        }
+
+        private Symbol createNewSymbol(final Type type) {
+            ensureCapacity();
+            final Symbol symbol = symbols[nextFreeSymbol] = new Symbol(getUniqueName(), IS_TEMP, type);
+            nextFreeSymbol++;
+            symbolCount++;
+            return symbol;
+        }
+
+        private void addSymbol(Symbol symbol) {
+            ensureCapacity();
+            symbols[symbolCount++] = symbol;
+        }
+
+        void reuse() {
+            nextFreeSymbol = 0;
+        }
+
+        private void ensureCapacity() {
+            if(symbolCount == symbols.length) {
+                final Symbol[] newSymbols = new Symbol[symbolCount * 2];
+                System.arraycopy(symbols, 0, newSymbols, 0, symbolCount);
+                symbols = newSymbols;
+            }
+        }
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/TernaryNode.java b/nashorn/src/jdk/nashorn/internal/ir/TernaryNode.java
index e2ccdb9..25ac1a4 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/TernaryNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/TernaryNode.java
@@ -27,7 +27,6 @@
 
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * TernaryNode nodes represent three operand operations (?:).
@@ -44,14 +43,13 @@
     /**
      * Constructor
      *
-     * @param source the source
      * @param token  token
      * @param lhs    left hand side node
      * @param rhs    right hand side node
      * @param third  third node
      */
-    public TernaryNode(final Source source, final long token, final Node lhs, final Node rhs, final Node third) {
-        super(source, token, third.getFinish());
+    public TernaryNode(final long token, final Node lhs, final Node rhs, final Node third) {
+        super(token, third.getFinish());
         this.lhs = lhs;
         this.rhs = rhs;
         this.third = third;
diff --git a/nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java b/nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java
index 7a10a6a..e37302e 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java
@@ -27,31 +27,29 @@
 
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation for THROW statements.
  */
 @Immutable
-public final class ThrowNode extends Node {
+public final class ThrowNode extends Statement {
     /** Exception expression. */
     private final Node expression;
 
     /**
      * Constructor
      *
-     * @param source     the source
+     * @param lineNumber line number
      * @param token      token
      * @param finish     finish
      * @param expression expression to throw
      */
-    public ThrowNode(final Source source, final long token, final int finish, final Node expression) {
-        super(source, token, finish);
-
+    public ThrowNode(final int lineNumber, final long token, final int finish, final Node expression) {
+        super(lineNumber, token, finish);
         this.expression = expression;
     }
 
-    private ThrowNode(final Node node, final Node expression) {
+    private ThrowNode(final ThrowNode node, final Node expression) {
         super(node);
         this.expression = expression;
     }
diff --git a/nashorn/src/jdk/nashorn/internal/ir/TryNode.java b/nashorn/src/jdk/nashorn/internal/ir/TryNode.java
index 5e3ff7a..01ea75c 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/TryNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/TryNode.java
@@ -32,13 +32,12 @@
 import jdk.nashorn.internal.codegen.Label;
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation of a TRY statement.
  */
 @Immutable
-public final class TryNode extends Node {
+public final class TryNode extends Statement {
     /** Try statements. */
     private final Block body;
 
@@ -60,27 +59,27 @@
     /**
      * Constructor
      *
-     * @param source      the source
+     * @param lineNumber  lineNumber
      * @param token       token
      * @param finish      finish
      * @param body        try node body
      * @param catchBlocks list of catch blocks in order
      * @param finallyBody body of finally block or null if none
      */
-    public TryNode(final Source source, final long token, final int finish, final Block body, final List<Block> catchBlocks, final Block finallyBody) {
-        super(source, token, finish);
-        this.body = body;
+    public TryNode(final int lineNumber, final long token, final int finish, final Block body, final List<Block> catchBlocks, final Block finallyBody) {
+        super(lineNumber, token, finish);
+        this.body        = body;
         this.catchBlocks = catchBlocks;
         this.finallyBody = finallyBody;
-        this.exit = new Label("exit");
+        this.exit        = new Label("exit");
     }
 
     private TryNode(final TryNode tryNode, final Block body, final List<Block> catchBlocks, final Block finallyBody) {
         super(tryNode);
-        this.body = body;
+        this.body        = body;
         this.catchBlocks = catchBlocks;
         this.finallyBody = finallyBody;
-        this.exit = new Label(tryNode.exit);
+        this.exit        = new Label(tryNode.exit);
     }
 
     @Override
diff --git a/nashorn/src/jdk/nashorn/internal/ir/TypeOverride.java b/nashorn/src/jdk/nashorn/internal/ir/TypeOverride.java
index 61c1fe2..929d012 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/TypeOverride.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/TypeOverride.java
@@ -43,10 +43,12 @@
     /**
      * Set the override type
      *
-     * @param type  the type
+     * @param ts temporary symbols
+     * @param lc the current lexical context
+     * @param type the type
      * @return a node equivalent to this one except for the requested change.
      */
-    public T setType(final Type type);
+    public T setType(final TemporarySymbols ts, final LexicalContext lc, final Type type);
 
     /**
      * Returns true if this node can have a callsite override, e.g. all scope ident nodes
diff --git a/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java b/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java
index fed5e40..ed1d8a9 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java
@@ -35,7 +35,6 @@
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
 import jdk.nashorn.internal.parser.Token;
 import jdk.nashorn.internal.parser.TokenType;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * UnaryNode nodes represent single operand operations.
@@ -48,24 +47,23 @@
     /**
      * Constructor
      *
-     * @param source the source
      * @param token  token
      * @param rhs    expression
      */
-    public UnaryNode(final Source source, final long token, final Node rhs) {
-        this(source, token, Math.min(rhs.getStart(), Token.descPosition(token)), Math.max(Token.descPosition(token) + Token.descLength(token), rhs.getFinish()), rhs);
+    public UnaryNode(final long token, final Node rhs) {
+        this(token, Math.min(rhs.getStart(), Token.descPosition(token)), Math.max(Token.descPosition(token) + Token.descLength(token), rhs.getFinish()), rhs);
     }
 
     /**
      * Constructor
-     * @param source the source
+     *
      * @param token  token
      * @param start  start
      * @param finish finish
      * @param rhs    expression
      */
-    public UnaryNode(final Source source, final long token, final int start, final int finish, final Node rhs) {
-        super(source, token, start, finish);
+    public UnaryNode(final long token, final int start, final int finish, final Node rhs) {
+        super(token, start, finish);
         this.rhs = rhs;
     }
 
diff --git a/nashorn/src/jdk/nashorn/internal/ir/VarNode.java b/nashorn/src/jdk/nashorn/internal/ir/VarNode.java
index fbc3eab..c28f545 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/VarNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/VarNode.java
@@ -27,13 +27,12 @@
 
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * Node represents a var/let declaration.
  */
 @Immutable
-public final class VarNode extends Node implements Assignment<IdentNode> {
+public final class VarNode extends Statement implements Assignment<IdentNode> {
     /** Var name. */
     private final IdentNode name;
 
@@ -54,14 +53,14 @@
     /**
      * Constructor
      *
-     * @param source the source
-     * @param token  token
-     * @param finish finish
-     * @param name   name of variable
-     * @param init   init node or null if just a declaration
+     * @param lineNumber line number
+     * @param token      token
+     * @param finish     finish
+     * @param name       name of variable
+     * @param init       init node or null if just a declaration
      */
-    public VarNode(final Source source, final long token, final int finish, final IdentNode name, final Node init) {
-        this(source, token, finish, name, init, IS_STATEMENT);
+    public VarNode(final int lineNumber, final long token, final int finish, final IdentNode name, final Node init) {
+        this(lineNumber, token, finish, name, init, IS_STATEMENT);
     }
 
     private VarNode(final VarNode varNode, final IdentNode name, final Node init, final int flags) {
@@ -74,15 +73,15 @@
     /**
      * Constructor
      *
-     * @param source the source
-     * @param token  token
-     * @param finish finish
-     * @param name   name of variable
-     * @param init   init node or null if just a declaration
-     * @param flags  flags
+     * @param lineNumber line number
+     * @param token      token
+     * @param finish     finish
+     * @param name       name of variable
+     * @param init       init node or null if just a declaration
+     * @param flags      flags
      */
-    public VarNode(final Source source, final long token, final int finish, final IdentNode name, final Node init, final int flags) {
-        super(source, token, finish);
+    public VarNode(final int lineNumber, final long token, final int finish, final IdentNode name, final Node init, final int flags) {
+        super(lineNumber, token, finish);
 
         this.name  = init == null ? name : name.setIsInitializedHere();
         this.init  = init;
diff --git a/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java b/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java
index 438be01..c52209f 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java
@@ -27,7 +27,6 @@
 
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation for a WHILE statement. This is the superclass of all
@@ -42,13 +41,13 @@
     /**
      * Constructor
      *
-     * @param source    the source
-     * @param token     token
-     * @param finish    finish
-     * @param isDoWhile is this a do while loop?
+     * @param lineNumber line number
+     * @param token      token
+     * @param finish     finish
+     * @param isDoWhile  is this a do while loop?
      */
-    public WhileNode(final Source source, final long token, final int finish, final boolean isDoWhile) {
-        super(source, token, finish, null, null, false);
+    public WhileNode(final int lineNumber, final long token, final int finish, final boolean isDoWhile) {
+        super(lineNumber, token, finish, null, null, false);
         this.isDoWhile = isDoWhile;
     }
 
@@ -135,17 +134,9 @@
 
     @Override
     public void toString(final StringBuilder sb) {
-        if (isDoWhile()) {
-            sb.append("do {");
-            body.toString(sb);
-            sb.append("} while (");
-            test.toString(sb);
-            sb.append(')');
-        } else {
-            sb.append("while (");
-            test.toString(sb);
-            sb.append(')');
-        }
+        sb.append("while (");
+        test.toString(sb);
+        sb.append(')');
     }
 
     @Override
diff --git a/nashorn/src/jdk/nashorn/internal/ir/WithNode.java b/nashorn/src/jdk/nashorn/internal/ir/WithNode.java
index 5ebbfd5..e069ff5 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/WithNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/WithNode.java
@@ -27,7 +27,6 @@
 
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * IR representation for {@code with} statements.
@@ -43,20 +42,18 @@
     /**
      * Constructor
      *
-     * @param source     the source
+     * @param lineNumber line number
      * @param token      token
      * @param finish     finish
      */
-    public WithNode(final Source source, final long token, final int finish) {
-        super(source, token, finish);
-
+    public WithNode(final int lineNumber, final long token, final int finish) {
+        super(lineNumber, token, finish);
         this.expression = null;
         this.body       = null;
     }
 
     private WithNode(final WithNode node, final Node expression, final Block body) {
         super(node);
-
         this.expression = expression;
         this.body       = body;
     }
diff --git a/nashorn/src/jdk/nashorn/internal/ir/debug/ClassHistogramElement.java b/nashorn/src/jdk/nashorn/internal/ir/debug/ClassHistogramElement.java
new file mode 100644
index 0000000..c65f8ef
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/debug/ClassHistogramElement.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.internal.ir.debug;
+
+import java.util.Comparator;
+
+/**
+ * Class histogram element for IR / Java object instrumentation
+ */
+public class ClassHistogramElement {
+    /**
+     * Instance comparator
+     */
+    public static final Comparator<ClassHistogramElement> COMPARE_INSTANCES = new Comparator<ClassHistogramElement>() {
+        @Override
+        public int compare(final ClassHistogramElement o1, final ClassHistogramElement o2) {
+            return (int)Math.abs(o1.instances - o2.instances);
+        }
+    };
+
+    /**
+     * Bytes comparator
+     */
+    public static final Comparator<ClassHistogramElement> COMPARE_BYTES = new Comparator<ClassHistogramElement>() {
+        @Override
+        public int compare(final ClassHistogramElement o1, final ClassHistogramElement o2) {
+            return (int)Math.abs(o1.bytes - o2.bytes);
+        }
+    };
+
+    /**
+     * Classname comparator
+     */
+    public static final Comparator<ClassHistogramElement> COMPARE_CLASSNAMES = new Comparator<ClassHistogramElement>() {
+        @Override
+        public int compare(final ClassHistogramElement o1, final ClassHistogramElement o2) {
+            return o1.clazz.getCanonicalName().compareTo(o2.clazz.getCanonicalName());
+        }
+    };
+
+    private final Class<?> clazz;
+    private long instances;
+    private long bytes;
+
+    /**
+     * Constructor
+     * @param clazz class for which to construct histogram
+     */
+    public ClassHistogramElement(final Class<?> clazz) {
+        this.clazz = clazz;
+    }
+
+    /**
+     * Add an instance
+     * @param sizeInBytes byte count
+     */
+    public void addInstance(final long sizeInBytes) {
+        instances++;
+        this.bytes += sizeInBytes;
+    }
+
+    /**
+     * Get size in bytes
+     * @return size in bytes
+     */
+    public long getBytes() {
+        return bytes;
+    }
+
+    /**
+     * Get class
+     * @return class
+     */
+    public Class<?> getClazz() {
+        return clazz;
+    }
+
+    /**
+     * Get number of instances
+     * @return number of instances
+     */
+    public long getInstances() {
+        return instances;
+    }
+
+    @Override
+    public String toString() {
+        return "ClassHistogramElement[class=" + clazz.getCanonicalName() + ", instances=" + instances + ", bytes=" + bytes + "]";
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java
index 988b756..177fcf9 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java
@@ -27,6 +27,7 @@
 
 import java.util.Arrays;
 import java.util.List;
+
 import jdk.nashorn.internal.codegen.CompilerConstants;
 import jdk.nashorn.internal.ir.AccessNode;
 import jdk.nashorn.internal.ir.BinaryNode;
@@ -44,7 +45,6 @@
 import jdk.nashorn.internal.ir.IfNode;
 import jdk.nashorn.internal.ir.IndexNode;
 import jdk.nashorn.internal.ir.LabelNode;
-import jdk.nashorn.internal.ir.LineNumberNode;
 import jdk.nashorn.internal.ir.LiteralNode;
 import jdk.nashorn.internal.ir.Node;
 import jdk.nashorn.internal.ir.ObjectNode;
@@ -52,6 +52,7 @@
 import jdk.nashorn.internal.ir.ReturnNode;
 import jdk.nashorn.internal.ir.RuntimeNode;
 import jdk.nashorn.internal.ir.SplitNode;
+import jdk.nashorn.internal.ir.Statement;
 import jdk.nashorn.internal.ir.SwitchNode;
 import jdk.nashorn.internal.ir.TernaryNode;
 import jdk.nashorn.internal.ir.ThrowNode;
@@ -406,17 +407,15 @@
         }
 
         // body consists of nested functions and statements
-        final List<Node> stats = functionNode.getBody().getStatements();
+        final List<Statement> stats = functionNode.getBody().getStatements();
         final int size = stats.size();
         int idx = 0;
         arrayStart("body");
 
         for (final Node stat : stats) {
-            if (! stat.isDebug()) {
-                stat.accept(this);
-                if (idx != (size - 1)) {
-                    comma();
-                }
+            stat.accept(this);
+            if (idx != (size - 1)) {
+                comma();
             }
             idx++;
         }
@@ -504,11 +503,6 @@
         return leave();
     }
 
-    @Override
-    public boolean enterLineNumberNode(final LineNumberNode lineNumberNode) {
-        return false;
-    }
-
     @SuppressWarnings("rawtypes")
     @Override
     public boolean enterLiteralNode(final LiteralNode literalNode) {
@@ -931,15 +925,13 @@
         int idx = 0;
         arrayStart(name);
         for (final Node node : nodes) {
-            if (node == null || !node.isDebug()) {
-                if (node != null) {
-                    node.accept(this);
-                } else {
-                    nullValue();
-                }
-                if (idx != (size - 1)) {
-                    comma();
-                }
+            if (node != null) {
+                node.accept(this);
+            } else {
+                nullValue();
+            }
+            if (idx != (size - 1)) {
+                comma();
             }
             idx++;
         }
@@ -971,7 +963,7 @@
             objectStart("loc");
 
             // source name
-            final Source src = node.getSource();
+            final Source src = getLexicalContext().getCurrentFunction().getSource();
             property("source", src.getName());
             comma();
 
diff --git a/nashorn/src/jdk/nashorn/internal/ir/debug/ObjectSizeCalculator.java b/nashorn/src/jdk/nashorn/internal/ir/debug/ObjectSizeCalculator.java
new file mode 100644
index 0000000..2d4412e
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/debug/ObjectSizeCalculator.java
@@ -0,0 +1,457 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.internal.ir.debug;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryPoolMXBean;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.IdentityHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Contains utility methods for calculating the memory usage of objects. It
+ * only works on the HotSpot JVM, and infers the actual memory layout (32 bit
+ * vs. 64 bit word size, compressed object pointers vs. uncompressed) from
+ * best available indicators. It can reliably detect a 32 bit vs. 64 bit JVM.
+ * It can only make an educated guess at whether compressed OOPs are used,
+ * though; specifically, it knows what the JVM's default choice of OOP
+ * compression would be based on HotSpot version and maximum heap sizes, but if
+ * the choice is explicitly overridden with the <tt>-XX:{+|-}UseCompressedOops</tt> command line
+ * switch, it can not detect
+ * this fact and will report incorrect sizes, as it will presume the default JVM
+ * behavior.
+ *
+ * @author Attila Szegedi
+ */
+public class ObjectSizeCalculator {
+
+    /**
+     * Describes constant memory overheads for various constructs in a JVM implementation.
+     */
+    public interface MemoryLayoutSpecification {
+
+        /**
+         * Returns the fixed overhead of an array of any type or length in this JVM.
+         *
+         * @return the fixed overhead of an array.
+         */
+        int getArrayHeaderSize();
+
+        /**
+         * Returns the fixed overhead of for any {@link Object} subclass in this JVM.
+         *
+         * @return the fixed overhead of any object.
+         */
+        int getObjectHeaderSize();
+
+        /**
+         * Returns the quantum field size for a field owned by an object in this JVM.
+         *
+         * @return the quantum field size for an object.
+         */
+        int getObjectPadding();
+
+        /**
+         * Returns the fixed size of an object reference in this JVM.
+         *
+         * @return the size of all object references.
+         */
+        int getReferenceSize();
+
+        /**
+         * Returns the quantum field size for a field owned by one of an object's ancestor superclasses
+         * in this JVM.
+         *
+         * @return the quantum field size for a superclass field.
+         */
+        int getSuperclassFieldPadding();
+    }
+
+    private static class CurrentLayout {
+        private static final MemoryLayoutSpecification SPEC =
+                getEffectiveMemoryLayoutSpecification();
+    }
+
+    /**
+     * Given an object, returns the total allocated size, in bytes, of the object
+     * and all other objects reachable from it.  Attempts to to detect the current JVM memory layout,
+     * but may fail with {@link UnsupportedOperationException};
+     *
+     * @param obj the object; can be null. Passing in a {@link java.lang.Class} object doesn't do
+     *          anything special, it measures the size of all objects
+     *          reachable through it (which will include its class loader, and by
+     *          extension, all other Class objects loaded by
+     *          the same loader, and all the parent class loaders). It doesn't provide the
+     *          size of the static fields in the JVM class that the Class object
+     *          represents.
+     * @return the total allocated size of the object and all other objects it
+     *         retains.
+     * @throws UnsupportedOperationException if the current vm memory layout cannot be detected.
+     */
+    public static long getObjectSize(final Object obj) throws UnsupportedOperationException {
+        return obj == null ? 0 : new ObjectSizeCalculator(CurrentLayout.SPEC).calculateObjectSize(obj);
+    }
+
+    // Fixed object header size for arrays.
+    private final int arrayHeaderSize;
+    // Fixed object header size for non-array objects.
+    private final int objectHeaderSize;
+    // Padding for the object size - if the object size is not an exact multiple
+    // of this, it is padded to the next multiple.
+    private final int objectPadding;
+    // Size of reference (pointer) fields.
+    private final int referenceSize;
+    // Padding for the fields of superclass before fields of subclasses are
+    // added.
+    private final int superclassFieldPadding;
+
+    private final Map<Class<?>, ClassSizeInfo> classSizeInfos = new IdentityHashMap<>();
+
+
+    private final Map<Object, Object> alreadyVisited = new IdentityHashMap<>();
+    private final Map<Class<?>, ClassHistogramElement> histogram = new IdentityHashMap<>();
+
+    private final Deque<Object> pending = new ArrayDeque<>(16 * 1024);
+    private long size;
+
+    /**
+     * Creates an object size calculator that can calculate object sizes for a given
+     * {@code memoryLayoutSpecification}.
+     *
+     * @param memoryLayoutSpecification a description of the JVM memory layout.
+     */
+    public ObjectSizeCalculator(final MemoryLayoutSpecification memoryLayoutSpecification) {
+        memoryLayoutSpecification.getClass();
+        arrayHeaderSize = memoryLayoutSpecification.getArrayHeaderSize();
+        objectHeaderSize = memoryLayoutSpecification.getObjectHeaderSize();
+        objectPadding = memoryLayoutSpecification.getObjectPadding();
+        referenceSize = memoryLayoutSpecification.getReferenceSize();
+        superclassFieldPadding = memoryLayoutSpecification.getSuperclassFieldPadding();
+    }
+
+    /**
+     * Given an object, returns the total allocated size, in bytes, of the object
+     * and all other objects reachable from it.
+     *
+     * @param obj the object; can be null. Passing in a {@link java.lang.Class} object doesn't do
+     *          anything special, it measures the size of all objects
+     *          reachable through it (which will include its class loader, and by
+     *          extension, all other Class objects loaded by
+     *          the same loader, and all the parent class loaders). It doesn't provide the
+     *          size of the static fields in the JVM class that the Class object
+     *          represents.
+     * @return the total allocated size of the object and all other objects it
+     *         retains.
+     */
+    public synchronized long calculateObjectSize(final Object obj) {
+        // Breadth-first traversal instead of naive depth-first with recursive
+        // implementation, so we don't blow the stack traversing long linked lists.
+        histogram.clear();
+        try {
+            for (Object o = obj;;) {
+                visit(o);
+                if (pending.isEmpty()) {
+                    return size;
+                }
+                o = pending.removeFirst();
+            }
+        } finally {
+            alreadyVisited.clear();
+            pending.clear();
+            size = 0;
+        }
+    }
+
+    /**
+     * Get the class histograpm
+     * @return class histogram element list
+     */
+    public List<ClassHistogramElement> getClassHistogram() {
+        return new ArrayList<>(histogram.values());
+    }
+
+    private ClassSizeInfo getClassSizeInfo(final Class<?> clazz) {
+        ClassSizeInfo csi = classSizeInfos.get(clazz);
+        if(csi == null) {
+            csi = new ClassSizeInfo(clazz);
+            classSizeInfos.put(clazz, csi);
+        }
+        return csi;
+    }
+
+    private void visit(final Object obj) {
+        if (alreadyVisited.containsKey(obj)) {
+            return;
+        }
+        final Class<?> clazz = obj.getClass();
+        if (clazz == ArrayElementsVisitor.class) {
+            ((ArrayElementsVisitor) obj).visit(this);
+        } else {
+            alreadyVisited.put(obj, obj);
+            if (clazz.isArray()) {
+                visitArray(obj);
+            } else {
+                getClassSizeInfo(clazz).visit(obj, this);
+            }
+        }
+    }
+
+    private void visitArray(final Object array) {
+        final Class<?> arrayClass = array.getClass();
+        final Class<?> componentType = arrayClass.getComponentType();
+        final int length = Array.getLength(array);
+        if (componentType.isPrimitive()) {
+            increaseByArraySize(arrayClass, length, getPrimitiveFieldSize(componentType));
+        } else {
+            increaseByArraySize(arrayClass, length, referenceSize);
+            // If we didn't use an ArrayElementsVisitor, we would be enqueueing every
+            // element of the array here instead. For large arrays, it would
+            // tremendously enlarge the queue. In essence, we're compressing it into
+            // a small command object instead. This is different than immediately
+            // visiting the elements, as their visiting is scheduled for the end of
+            // the current queue.
+            switch (length) {
+            case 0: {
+                break;
+            }
+            case 1: {
+                enqueue(Array.get(array, 0));
+                break;
+            }
+            default: {
+                enqueue(new ArrayElementsVisitor((Object[]) array));
+            }
+            }
+        }
+    }
+
+    private void increaseByArraySize(final Class<?> clazz, final int length, final long elementSize) {
+        increaseSize(clazz, roundTo(arrayHeaderSize + length * elementSize, objectPadding));
+    }
+
+    private static class ArrayElementsVisitor {
+        private final Object[] array;
+
+        ArrayElementsVisitor(final Object[] array) {
+            this.array = array;
+        }
+
+        public void visit(final ObjectSizeCalculator calc) {
+            for (final Object elem : array) {
+                if (elem != null) {
+                    calc.visit(elem);
+                }
+            }
+        }
+    }
+
+    void enqueue(final Object obj) {
+        if (obj != null) {
+            pending.addLast(obj);
+        }
+    }
+
+    void increaseSize(final Class<?> clazz, final long objectSize) {
+        ClassHistogramElement he = histogram.get(clazz);
+        if(he == null) {
+            he = new ClassHistogramElement(clazz);
+            histogram.put(clazz, he);
+        }
+        he.addInstance(objectSize);
+        size += objectSize;
+    }
+
+    static long roundTo(final long x, final int multiple) {
+        return ((x + multiple - 1) / multiple) * multiple;
+    }
+
+    private class ClassSizeInfo {
+        // Padded fields + header size
+        private final long objectSize;
+        // Only the fields size - used to calculate the subclasses' memory
+        // footprint.
+        private final long fieldsSize;
+        private final Field[] referenceFields;
+
+        public ClassSizeInfo(final Class<?> clazz) {
+            long newFieldsSize = 0;
+            final List<Field> newReferenceFields = new LinkedList<>();
+            for (Field f : clazz.getDeclaredFields()) {
+                if (Modifier.isStatic(f.getModifiers())) {
+                    continue;
+                }
+                final Class<?> type = f.getType();
+                if (type.isPrimitive()) {
+                    newFieldsSize += getPrimitiveFieldSize(type);
+                } else {
+                    f.setAccessible(true);
+                    newReferenceFields.add(f);
+                    newFieldsSize += referenceSize;
+                }
+            }
+            final Class<?> superClass = clazz.getSuperclass();
+            if (superClass != null) {
+                final ClassSizeInfo superClassInfo = getClassSizeInfo(superClass);
+                newFieldsSize += roundTo(superClassInfo.fieldsSize, superclassFieldPadding);
+                newReferenceFields.addAll(Arrays.asList(superClassInfo.referenceFields));
+            }
+            this.fieldsSize = newFieldsSize;
+            this.objectSize = roundTo(objectHeaderSize + newFieldsSize, objectPadding);
+            this.referenceFields = newReferenceFields.toArray(
+                    new Field[newReferenceFields.size()]);
+        }
+
+        void visit(final Object obj, final ObjectSizeCalculator calc) {
+            calc.increaseSize(obj.getClass(), objectSize);
+            enqueueReferencedObjects(obj, calc);
+        }
+
+        public void enqueueReferencedObjects(final Object obj, final ObjectSizeCalculator calc) {
+            for (Field f : referenceFields) {
+                try {
+                    calc.enqueue(f.get(obj));
+                } catch (IllegalAccessException e) {
+                    final AssertionError ae = new AssertionError(
+                            "Unexpected denial of access to " + f);
+                    ae.initCause(e);
+                    throw ae;
+                }
+            }
+        }
+    }
+
+    private static long getPrimitiveFieldSize(final Class<?> type) {
+        if (type == boolean.class || type == byte.class) {
+            return 1;
+        }
+        if (type == char.class || type == short.class) {
+            return 2;
+        }
+        if (type == int.class || type == float.class) {
+            return 4;
+        }
+        if (type == long.class || type == double.class) {
+            return 8;
+        }
+        throw new AssertionError("Encountered unexpected primitive type " +
+                type.getName());
+    }
+
+    /**
+     * Return the current memory usage
+     * @return current memory usage derived from system configuration
+     */
+    public static MemoryLayoutSpecification getEffectiveMemoryLayoutSpecification() {
+        final String vmName = System.getProperty("java.vm.name");
+        if (vmName == null || !vmName.startsWith("Java HotSpot(TM) ")) {
+            throw new UnsupportedOperationException(
+                    "ObjectSizeCalculator only supported on HotSpot VM");
+        }
+
+        final String dataModel = System.getProperty("sun.arch.data.model");
+        if ("32".equals(dataModel)) {
+            // Running with 32-bit data model
+            return new MemoryLayoutSpecification() {
+                @Override public int getArrayHeaderSize() {
+                    return 12;
+                }
+                @Override public int getObjectHeaderSize() {
+                    return 8;
+                }
+                @Override public int getObjectPadding() {
+                    return 8;
+                }
+                @Override public int getReferenceSize() {
+                    return 4;
+                }
+                @Override public int getSuperclassFieldPadding() {
+                    return 4;
+                }
+            };
+        } else if (!"64".equals(dataModel)) {
+            throw new UnsupportedOperationException("Unrecognized value '" +
+                    dataModel + "' of sun.arch.data.model system property");
+        }
+
+        final String strVmVersion = System.getProperty("java.vm.version");
+        final int vmVersion = Integer.parseInt(strVmVersion.substring(0,
+                strVmVersion.indexOf('.')));
+        if (vmVersion >= 17) {
+            long maxMemory = 0;
+            for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans()) {
+                maxMemory += mp.getUsage().getMax();
+            }
+            if (maxMemory < 30L * 1024 * 1024 * 1024) {
+                // HotSpot 17.0 and above use compressed OOPs below 30GB of RAM total
+                // for all memory pools (yes, including code cache).
+                return new MemoryLayoutSpecification() {
+                    @Override public int getArrayHeaderSize() {
+                        return 16;
+                    }
+                    @Override public int getObjectHeaderSize() {
+                        return 12;
+                    }
+                    @Override public int getObjectPadding() {
+                        return 8;
+                    }
+                    @Override public int getReferenceSize() {
+                        return 4;
+                    }
+                    @Override public int getSuperclassFieldPadding() {
+                        return 4;
+                    }
+                };
+            }
+        }
+
+        // In other cases, it's a 64-bit uncompressed OOPs object model
+        return new MemoryLayoutSpecification() {
+            @Override public int getArrayHeaderSize() {
+                return 24;
+            }
+            @Override public int getObjectHeaderSize() {
+                return 16;
+            }
+            @Override public int getObjectPadding() {
+                return 8;
+            }
+            @Override public int getReferenceSize() {
+                return 8;
+            }
+            @Override public int getSuperclassFieldPadding() {
+                return 8;
+            }
+        };
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java b/nashorn/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java
index 8637b66..3ac5006 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java
@@ -36,9 +36,9 @@
 import jdk.nashorn.internal.ir.FunctionNode;
 import jdk.nashorn.internal.ir.IfNode;
 import jdk.nashorn.internal.ir.LabelNode;
-import jdk.nashorn.internal.ir.LineNumberNode;
 import jdk.nashorn.internal.ir.Node;
 import jdk.nashorn.internal.ir.SplitNode;
+import jdk.nashorn.internal.ir.Statement;
 import jdk.nashorn.internal.ir.SwitchNode;
 import jdk.nashorn.internal.ir.Symbol;
 import jdk.nashorn.internal.ir.TryNode;
@@ -55,7 +55,7 @@
  */
 public final class PrintVisitor extends NodeVisitor {
     /** Tab width */
-    private static final int TABWIDTH = 1;
+    private static final int TABWIDTH = 4;
 
     /** Composing buffer. */
     private final StringBuilder sb;
@@ -69,6 +69,8 @@
     /** Print line numbers */
     private final boolean printLineNumbers;
 
+    private int lastLineNumber = -1;
+
     /**
      * Constructor.
      */
@@ -138,24 +140,27 @@
     @Override
     public boolean enterBlock(final Block block) {
         sb.append(' ');
+        //sb.append(Debug.id(block));
         sb.append('{');
 
         indent += TABWIDTH;
 
-        final List<Node> statements = block.getStatements();
-
-        boolean lastLineNumber = false;
+        final List<Statement> statements = block.getStatements();
 
         for (final Node statement : statements) {
-            if (printLineNumbers || !lastLineNumber) {
-                sb.append(EOLN);
-                indent();
+            if (printLineNumbers && (statement instanceof Statement)) {
+                final int lineNumber = ((Statement)statement).getLineNumber();
+                sb.append('\n');
+                if (lineNumber != lastLineNumber) {
+                    indent();
+                    sb.append("[|").append(lineNumber).append("|];").append('\n');
+                }
+                lastLineNumber = lineNumber;
             }
+            indent();
 
             statement.accept(this);
 
-            lastLineNumber = statement instanceof LineNumberNode;
-
             if (statement instanceof FunctionNode) {
                 continue;
             }
@@ -168,12 +173,14 @@
                 sb.append(']');
             }
 
-            final char lastChar = sb.charAt(sb.length() - 1);
+            int  lastIndex = sb.length() - 1;
+            char lastChar  = sb.charAt(lastIndex);
+            while (Character.isWhitespace(lastChar) && lastIndex >= 0) {
+                lastChar = sb.charAt(--lastIndex);
+            }
 
             if (lastChar != '}' && lastChar != ';') {
-                if (printLineNumbers || !lastLineNumber) {
-                    sb.append(';');
-                }
+                sb.append(';');
             }
 
             if (statement.hasGoto()) {
@@ -189,7 +196,8 @@
 
         sb.append(EOLN);
         indent();
-        sb.append("}");
+        sb.append('}');
+       // sb.append(Debug.id(block));
 
         return false;
     }
@@ -221,7 +229,7 @@
     public boolean enterFunctionNode(final FunctionNode functionNode) {
         functionNode.toString(sb);
         enterBlock(functionNode.getBody());
-        sb.append(EOLN);
+        //sb.append(EOLN);
         return false;
     }
 
@@ -252,15 +260,6 @@
     }
 
     @Override
-    public boolean enterLineNumberNode(final LineNumberNode lineNumberNode) {
-        if (printLineNumbers) {
-            lineNumberNode.toString(sb);
-        }
-
-        return false;
-    }
-
-    @Override
     public boolean enterSplitNode(final SplitNode splitNode) {
         splitNode.toString(sb);
         sb.append(EOLN);
@@ -334,6 +333,7 @@
             sb.append(" = ");
             init.accept(this);
         }
+
         return false;
     }
 
diff --git a/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java b/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java
index 4f128412..2beba46 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java
@@ -149,7 +149,7 @@
             return enterASSIGN_SUB(binaryNode);
         case BIND:
             return enterBIND(binaryNode);
-         case BIT_AND:
+        case BIT_AND:
             return enterBIT_AND(binaryNode);
         case BIT_OR:
             return enterBIT_OR(binaryNode);
diff --git a/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java b/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java
index e3c0d34..8c807df 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java
@@ -42,7 +42,6 @@
 import jdk.nashorn.internal.ir.IndexNode;
 import jdk.nashorn.internal.ir.LabelNode;
 import jdk.nashorn.internal.ir.LexicalContext;
-import jdk.nashorn.internal.ir.LineNumberNode;
 import jdk.nashorn.internal.ir.LiteralNode;
 import jdk.nashorn.internal.ir.Node;
 import jdk.nashorn.internal.ir.ObjectNode;
@@ -454,26 +453,6 @@
     }
 
     /**
-     * Callback for entering a LineNumberNode
-     *
-     * @param  lineNumberNode the node
-     * @return true if traversal should continue and node children be traversed, false otherwise
-     */
-    public boolean enterLineNumberNode(final LineNumberNode lineNumberNode) {
-        return enterDefault(lineNumberNode);
-    }
-
-    /**
-     * Callback for leaving a LineNumberNode
-     *
-     * @param  lineNumberNode the node
-     * @return processed node, which will replace the original one, or the original node
-     */
-    public Node leaveLineNumberNode(final LineNumberNode lineNumberNode) {
-        return leaveDefault(lineNumberNode);
-    }
-
-    /**
      * Callback for entering a LiteralNode
      *
      * @param  literalNode the node
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
index a659af4..c9a71b5 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
@@ -297,7 +297,7 @@
     @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
     public static Object length(final Object self) {
         if (isArray(self)) {
-            return ((NativeArray) self).getArray().length() & JSType.MAX_UINT;
+            return ((ScriptObject) self).getArray().length() & JSType.MAX_UINT;
         }
 
         return 0;
@@ -311,7 +311,7 @@
     @Setter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
     public static void length(final Object self, final Object length) {
         if (isArray(self)) {
-            ((NativeArray) self).setLength(validLength(length, true));
+            ((ScriptObject) self).setLength(validLength(length, true));
         }
     }
 
@@ -642,10 +642,9 @@
             final boolean      strict = sobj.isStrictContext();
 
             if (bulkable(sobj)) {
-                final NativeArray nativeArray = (NativeArray)sobj;
-                if (nativeArray.getArray().length() + args.length <= JSType.MAX_UINT) {
-                    final ArrayData newData = nativeArray.getArray().push(nativeArray.isStrictContext(), args);
-                    nativeArray.setArray(newData);
+                if (sobj.getArray().length() + args.length <= JSType.MAX_UINT) {
+                    final ArrayData newData = sobj.getArray().push(sobj.isStrictContext(), args);
+                    sobj.setArray(newData);
                     return newData.length();
                 }
                 //fallthru
@@ -780,8 +779,7 @@
         }
 
         if (bulkable(sobj)) {
-            final NativeArray narray = (NativeArray) sobj;
-            return new NativeArray(narray.getArray().slice(k, finale));
+            return new NativeArray(sobj.getArray().slice(k, finale));
         }
 
         final NativeArray copy = new NativeArray(0);
@@ -1001,11 +999,10 @@
         }
 
         if (bulkable(sobj)) {
-            final NativeArray nativeArray = (NativeArray) sobj;
-            nativeArray.getArray().shiftRight(items.length);
+            sobj.getArray().shiftRight(items.length);
 
             for (int j = 0; j < items.length; j++) {
-                nativeArray.setArray(nativeArray.getArray().set(j, items[j], sobj.isStrictContext()));
+                sobj.setArray(sobj.getArray().set(j, items[j], sobj.isStrictContext()));
             }
         } else {
             for (long k = len; k > 0; k--) {
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java
index aba76c8..337f2e3 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java
@@ -87,66 +87,6 @@
     }
 
     /**
-     * Nashorn extension: get embed0 from {@link ScriptObject}
-     *
-     * @param self self reference
-     * @param obj script object
-     * @return the embed0 property value for the given ScriptObject
-     */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object embed0(final Object self, final Object obj) {
-        if (obj instanceof ScriptObject) {
-            return ((ScriptObject)obj).embed0;
-        }
-        return UNDEFINED;
-    }
-
-    /**
-     * Nashorn extension: get embed1 from {@link ScriptObject}
-     *
-     * @param self self reference
-     * @param obj script object
-     * @return the embed1 property value for the given ScriptObject
-     */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object embed1(final Object self, final Object obj) {
-        if (obj instanceof ScriptObject) {
-            return ((ScriptObject)obj).embed1;
-        }
-        return UNDEFINED;
-    }
-
-    /**
-     * Nashorn extension: get embed2 from {@link ScriptObject}
-     *
-     * @param self self reference
-     * @param obj script object
-     * @return the embed2 property value for the given ScriptObject
-     */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object embed2(final Object self, final Object obj) {
-        if (obj instanceof ScriptObject) {
-            return ((ScriptObject)obj).embed2;
-        }
-        return UNDEFINED;
-    }
-
-    /**
-     * Nashorn extension: get embed3 from {@link ScriptObject}
-     *
-     * @param self self reference
-     * @param obj script object
-     * @return the embed3 property value for the given ScriptObject
-     */
-    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object embed3(final Object self, final Object obj) {
-        if (obj instanceof ScriptObject) {
-            return ((ScriptObject)obj).embed3;
-        }
-        return UNDEFINED;
-    }
-
-    /**
      * Nashorn extension: get spill vector from {@link ScriptObject}
      *
      * @param self self reference
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
index 8a3f42d..153db76 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
@@ -620,7 +620,7 @@
                 // to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice.
                 return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class,
                         func.makeBoundFunction(this, new Object[] { name })), 0, Object.class),
-                        adaptee.getMap().getProtoGetSwitchPoint(__call__), testJSAdaptor(adaptee, null, null, null));
+                        adaptee.getMap().getProtoGetSwitchPoint(adaptee.getProto(), __call__), testJSAdaptor(adaptee, null, null, null));
             }
             throw typeError("no.such.function", desc.getNameToken(2), ScriptRuntime.safeToString(this));
         default:
@@ -687,7 +687,7 @@
             if (methodHandle != null) {
                 return new GuardedInvocation(
                         methodHandle,
-                        adaptee.getMap().getProtoGetSwitchPoint(hook),
+                        adaptee.getMap().getProtoGetSwitchPoint(adaptee.getProto(), hook),
                         testJSAdaptor(adaptee, findData.getGetter(Object.class), findData.getOwner(), func));
             }
         }
@@ -699,7 +699,7 @@
             final MethodHandle methodHandle = hook.equals(__put__) ?
             MH.asType(Lookup.EMPTY_SETTER, type) :
             Lookup.emptyGetter(type.returnType());
-            return new GuardedInvocation(methodHandle, adaptee.getMap().getProtoGetSwitchPoint(hook), testJSAdaptor(adaptee, null, null, null));
+            return new GuardedInvocation(methodHandle, adaptee.getMap().getProtoGetSwitchPoint(adaptee.getProto(), hook), testJSAdaptor(adaptee, null, null, null));
         }
     }
 
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
index 9a12911..8b469bc 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
@@ -794,15 +794,15 @@
 
         RegExpResult match;
         final int inputLength = string.length();
-        int lastLength = -1;
-        int lastIndex = 0;
-        int lastLastIndex = 0;
+        int splitLastLength = -1;
+        int splitLastIndex = 0;
+        int splitLastLastIndex = 0;
 
-        while ((match = execSplit(string, lastIndex)) != null) {
-            lastIndex = match.getIndex() + match.length();
+        while ((match = execSplit(string, splitLastIndex)) != null) {
+            splitLastIndex = match.getIndex() + match.length();
 
-            if (lastIndex > lastLastIndex) {
-                matches.add(string.substring(lastLastIndex, match.getIndex()));
+            if (splitLastIndex > splitLastLastIndex) {
+                matches.add(string.substring(splitLastLastIndex, match.getIndex()));
                 final Object[] groups = match.getGroups();
                 if (groups.length > 1 && match.getIndex() < inputLength) {
                     for (int index = 1; index < groups.length && matches.size() < limit; index++) {
@@ -810,7 +810,7 @@
                     }
                 }
 
-                lastLength = match.length();
+                splitLastLength = match.length();
 
                 if (matches.size() >= limit) {
                     break;
@@ -818,10 +818,10 @@
             }
 
             // bump the index to avoid infinite loop
-            if (lastIndex == lastLastIndex) {
-                lastIndex++;
+            if (splitLastIndex == splitLastLastIndex) {
+                splitLastIndex++;
             } else {
-                lastLastIndex = lastIndex;
+                splitLastLastIndex = splitLastIndex;
             }
         }
 
@@ -829,12 +829,12 @@
             // check special case if we need to append an empty string at the
             // end of the match
             // if the lastIndex was the entire string
-            if (lastLastIndex == string.length()) {
-                if (lastLength > 0 || execSplit("", 0) == null) {
+            if (splitLastLastIndex == string.length()) {
+                if (splitLastLength > 0 || execSplit("", 0) == null) {
                     matches.add("");
                 }
             } else {
-                matches.add(string.substring(lastLastIndex, inputLength));
+                matches.add(string.substring(splitLastLastIndex, inputLength));
             }
         }
 
@@ -899,10 +899,6 @@
         }
     }
 
-    private void setGlobal(final boolean global) {
-        regexp.setGlobal(global);
-    }
-
     boolean getGlobal() {
         return regexp.isGlobal();
     }
diff --git a/nashorn/src/jdk/nashorn/internal/parser/AbstractParser.java b/nashorn/src/jdk/nashorn/internal/parser/AbstractParser.java
index 8f65e0f..25b500c 100644
--- a/nashorn/src/jdk/nashorn/internal/parser/AbstractParser.java
+++ b/nashorn/src/jdk/nashorn/internal/parser/AbstractParser.java
@@ -249,6 +249,7 @@
      *
      * @param errorType  The error type of the warning
      * @param message    Warning message.
+     * @param errorToken error token
      */
     protected final void warning(final JSErrorType errorType, final String message, final long errorToken) {
         errors.warning(error(errorType, message, errorToken));
@@ -363,7 +364,7 @@
             next();
 
             // Create IDENT node.
-            return new IdentNode(source, identToken, finish, ident);
+            return new IdentNode(identToken, finish, ident);
         }
 
         // Get IDENT.
@@ -372,7 +373,7 @@
             return null;
         }
         // Create IDENT node.
-        return new IdentNode(source, identToken, finish, ident);
+        return new IdentNode(identToken, finish, ident);
     }
 
     /**
@@ -407,7 +408,7 @@
             final String ident = (String)getValue(identToken);
             next();
             // Create IDENT node.
-            return new IdentNode(source, identToken, finish, ident);
+            return new IdentNode(identToken, finish, ident);
         } else {
             expect(IDENT);
             return null;
@@ -432,11 +433,11 @@
         LiteralNode<?> node = null;
 
         if (value == null) {
-            node = LiteralNode.newInstance(source, literalToken, finish);
+            node = LiteralNode.newInstance(literalToken, finish);
         } else if (value instanceof Number) {
-            node = LiteralNode.newInstance(source, literalToken, finish, (Number)value);
+            node = LiteralNode.newInstance(literalToken, finish, (Number)value);
         } else if (value instanceof String) {
-            node = LiteralNode.newInstance(source, literalToken, finish, (String)value);
+            node = LiteralNode.newInstance(literalToken, finish, (String)value);
         } else if (value instanceof LexerToken) {
             if (value instanceof RegexToken) {
                 final RegexToken regex = (RegexToken)value;
@@ -446,7 +447,7 @@
                     throw error(e.getMessage());
                 }
             }
-            node = LiteralNode.newInstance(source, literalToken, finish, (LexerToken)value);
+            node = LiteralNode.newInstance(literalToken, finish, (LexerToken)value);
         } else {
             assert false : "unknown type for LiteralNode: " + value.getClass();
         }
diff --git a/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java b/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java
index e074cf0..d4985ea 100644
--- a/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java
+++ b/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java
@@ -193,13 +193,13 @@
             return getLiteral();
         case FALSE:
             next();
-            return LiteralNode.newInstance(source, literalToken, finish, false);
+            return LiteralNode.newInstance(literalToken, finish, false);
         case TRUE:
             next();
-            return LiteralNode.newInstance(source, literalToken, finish, true);
+            return LiteralNode.newInstance(literalToken, finish, true);
         case NULL:
             next();
-            return LiteralNode.newInstance(source, literalToken, finish);
+            return LiteralNode.newInstance(literalToken, finish);
         case LBRACKET:
             return arrayLiteral();
         case LBRACE:
@@ -218,7 +218,7 @@
 
             if (value instanceof Number) {
                 next();
-                return new UnaryNode(source, literalToken, LiteralNode.newInstance(source, realToken, finish, (Number)value));
+                return new UnaryNode(literalToken, LiteralNode.newInstance(realToken, finish, (Number)value));
             }
 
             throw error(AbstractParser.message("expected", "number", type.getNameOrType()));
@@ -250,7 +250,7 @@
             switch (type) {
             case RBRACKET:
                 next();
-                result = LiteralNode.newInstance(source, arrayToken, finish, elements);
+                result = LiteralNode.newInstance(arrayToken, finish, elements);
                 break loop;
 
             case COMMARIGHT:
@@ -310,7 +310,7 @@
         }
 
         // Construct new object literal.
-        return new ObjectNode(source, objectToken, finish, elements);
+        return new ObjectNode(objectToken, finish, elements);
     }
 
     /**
@@ -331,7 +331,7 @@
         if (name != null) {
             expect(COLON);
             final Node value = jsonLiteral();
-            return new PropertyNode(source, propertyToken, value.getFinish(), name, value, null, null);
+            return new PropertyNode(propertyToken, value.getFinish(), name, value, null, null);
         }
 
         // Raise an error.
diff --git a/nashorn/src/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk/nashorn/internal/parser/Parser.java
index ab70859..efb7a39 100644
--- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java
+++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java
@@ -59,9 +59,11 @@
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+
 import jdk.nashorn.internal.codegen.CompilerConstants;
 import jdk.nashorn.internal.codegen.Namespace;
 import jdk.nashorn.internal.ir.AccessNode;
+import jdk.nashorn.internal.ir.BaseNode;
 import jdk.nashorn.internal.ir.BinaryNode;
 import jdk.nashorn.internal.ir.Block;
 import jdk.nashorn.internal.ir.BlockLexicalContext;
@@ -81,7 +83,6 @@
 import jdk.nashorn.internal.ir.IndexNode;
 import jdk.nashorn.internal.ir.LabelNode;
 import jdk.nashorn.internal.ir.LexicalContext;
-import jdk.nashorn.internal.ir.LineNumberNode;
 import jdk.nashorn.internal.ir.LiteralNode;
 import jdk.nashorn.internal.ir.LoopNode;
 import jdk.nashorn.internal.ir.Node;
@@ -90,6 +91,7 @@
 import jdk.nashorn.internal.ir.PropertyNode;
 import jdk.nashorn.internal.ir.ReturnNode;
 import jdk.nashorn.internal.ir.RuntimeNode;
+import jdk.nashorn.internal.ir.Statement;
 import jdk.nashorn.internal.ir.SwitchNode;
 import jdk.nashorn.internal.ir.TernaryNode;
 import jdk.nashorn.internal.ir.ThrowNode;
@@ -117,7 +119,7 @@
     /** Is scripting mode. */
     private final boolean scripting;
 
-    private List<Node> functionDeclarations;
+    private List<Statement> functionDeclarations;
 
     private final BlockLexicalContext lc = new BlockLexicalContext();
 
@@ -275,8 +277,7 @@
      * @return New block.
      */
     private Block newBlock() {
-        final Block block = new Block(source, token, Token.descPosition(token));
-        return lc.push(block);
+        return lc.push(new Block(line, token, Token.descPosition(token)));
     }
 
     /**
@@ -305,11 +306,17 @@
         if (isStrictMode) {
             flags |= FunctionNode.IS_STRICT;
         }
+        if (env._specialize_calls != null) {
+            if (env._specialize_calls.contains(name)) {
+                flags |= FunctionNode.CAN_SPECIALIZE;
+            }
+        }
 
         // Start new block.
         FunctionNode functionNode =
             new FunctionNode(
                 source,
+                line, //TODO?
                 token,
                 Token.descPosition(token),
                 startToken,
@@ -320,11 +327,11 @@
                 kind,
                 flags);
 
-        functionNode = functionNode.setState(lc, errors.hasErrors() ? CompilationState.PARSE_ERROR : CompilationState.PARSED);
         lc.push(functionNode);
         // Create new block, and just put it on the context stack, restoreFunctionNode() will associate it with the
         // FunctionNode.
         newBlock();
+
         return functionNode;
     }
 
@@ -332,14 +339,19 @@
      * Restore the current block.
      */
     private Block restoreBlock(final Block block) {
-        return lc.pop(block);//.setFlag(lc, flags);
+        return lc.pop(block);
     }
 
+
     private FunctionNode restoreFunctionNode(final FunctionNode functionNode, final long lastToken) {
         final Block newBody = restoreBlock(lc.getFunctionBody(functionNode));
 
-        return lc.pop(functionNode).setBody(lc, newBody).setLastToken(lc, lastToken);
-    }
+        return lc.pop(functionNode).
+            setBody(lc, newBody).
+            setLastToken(lc, lastToken).
+            setState(lc, errors.hasErrors() ? CompilationState.PARSE_ERROR : CompilationState.PARSED).
+            snapshot(lc);
+        }
 
     /**
      * Get the statements in a block.
@@ -469,7 +481,7 @@
         }
 
         // Build up node.
-        return new BinaryNode(source, op, lhs, rhs);
+        return new BinaryNode(op, lhs, rhs);
     }
 
     /**
@@ -480,12 +492,12 @@
      * @param isPostfix  Prefix or postfix.
      * @return           Reduced expression.
      */
-    private Node incDecExpression(final long firstToken, final TokenType tokenType, final Node expression, final boolean isPostfix) {
+    private static Node incDecExpression(final long firstToken, final TokenType tokenType, final Node expression, final boolean isPostfix) {
         if (isPostfix) {
-            return new UnaryNode(source, Token.recast(firstToken, tokenType == DECPREFIX ? DECPOSTFIX : INCPOSTFIX), expression.getStart(), Token.descPosition(firstToken) + Token.descLength(firstToken), expression);
+            return new UnaryNode(Token.recast(firstToken, tokenType == DECPREFIX ? DECPOSTFIX : INCPOSTFIX), expression.getStart(), Token.descPosition(firstToken) + Token.descLength(firstToken), expression);
         }
 
-        return new UnaryNode(source, firstToken, expression);
+        return new UnaryNode(firstToken, expression);
     }
 
     /**
@@ -514,7 +526,7 @@
 
         FunctionNode script = newFunctionNode(
             functionToken,
-            new IdentNode(source, functionToken, Token.descPosition(functionToken), scriptName),
+            new IdentNode(functionToken, Token.descPosition(functionToken), scriptName),
             new ArrayList<IdentNode>(),
             FunctionNode.Kind.SCRIPT);
 
@@ -529,6 +541,7 @@
 
         script = restoreFunctionNode(script, token); //commit code
         script = script.setBody(lc, script.getBody().setNeedsScope(lc));
+
         return script;
     }
 
@@ -670,8 +683,6 @@
      * @param topLevel does this statement occur at the "top level" of a script or a function?
      */
     private void statement(final boolean topLevel) {
-        final LineNumberNode lineNumberNode = lineNumber();
-
         if (type == FUNCTION) {
             // As per spec (ECMA section 12), function declarations as arbitrary statement
             // is not "portable". Implementation can issue a warning or disallow the same.
@@ -679,10 +690,6 @@
             return;
         }
 
-        if (lineNumberNode != null) {
-            appendStatement(lineNumberNode);
-        }
-
         switch (type) {
         case LBRACE:
             block();
@@ -763,7 +770,7 @@
     private void block() {
         final Block newBlock = getBlock(true);
         // Force block execution.
-        appendStatement(new ExecuteNode(source, newBlock.getToken(), finish, newBlock));
+        appendStatement(new ExecuteNode(newBlock.getLineNumber(), newBlock.getToken(), finish, newBlock));
     }
 
     /**
@@ -800,7 +807,6 @@
      * @param ident         Identifier that is verified
      * @param contextString String used in error message to give context to the user
      */
-    @SuppressWarnings("fallthrough")
     private void verifyStrictIdent(final IdentNode ident, final String contextString) {
         if (isStrictMode) {
             switch (ident.getName()) {
@@ -840,6 +846,7 @@
 
         while (true) {
             // Get starting token.
+            final int  varLine  = line;
             final long varToken = token;
             // Get name of var.
             final IdentNode name = getIdent();
@@ -857,7 +864,7 @@
             }
 
             // Allocate var node.
-            final VarNode var = new VarNode(source, varToken, finish, name, init);
+            final VarNode var = new VarNode(varLine, varToken, finish, name, init);
             vars.add(var);
             appendStatement(var);
 
@@ -889,7 +896,7 @@
      */
     private void emptyStatement() {
         if (env._empty_statements) {
-            appendStatement(new EmptyNode(source, token, Token.descPosition(token) + Token.descLength(token)));
+            appendStatement(new EmptyNode(line, token, Token.descPosition(token) + Token.descLength(token)));
         }
 
         // SEMICOLON checked in caller.
@@ -906,6 +913,7 @@
      */
     private void expressionStatement() {
         // Lookahead checked in caller.
+        final int  expressionLine  = line;
         final long expressionToken = token;
 
         // Get expression and add as statement.
@@ -913,7 +921,7 @@
 
         ExecuteNode executeNode = null;
         if (expression != null) {
-            executeNode = new ExecuteNode(source, expressionToken, finish, expression);
+            executeNode = new ExecuteNode(expressionLine, expressionToken, finish, expression);
             appendStatement(executeNode);
         } else {
             expect(null);
@@ -938,6 +946,7 @@
      */
     private void ifStatement() {
         // Capture IF token.
+        final int  ifLine  = line;
         final long ifToken = token;
          // IF tested in caller.
         next();
@@ -953,7 +962,7 @@
             fail = getStatement();
         }
 
-        appendStatement(new IfNode(source, ifToken, fail != null ? fail.getFinish() : pass.getFinish(), test, pass, fail));
+        appendStatement(new IfNode(ifLine, ifToken, fail != null ? fail.getFinish() : pass.getFinish(), test, pass, fail));
     }
 
     /**
@@ -970,8 +979,7 @@
      */
     private void forStatement() {
         // Create FOR node, capturing FOR token.
-        ForNode forNode = new ForNode(source, token, Token.descPosition(token), null, null, null, null, ForNode.IS_FOR);
-
+        ForNode forNode = new ForNode(line, token, Token.descPosition(token), null, null, null, null, ForNode.IS_FOR);
 
         // Set up new block for scope of vars. Captures first token.
         Block outer = newBlock();
@@ -1074,7 +1082,7 @@
             outer = restoreBlock(outer);
         }
 
-        appendStatement(new ExecuteNode(source, outer.getToken(), outer.getFinish(), outer));
+        appendStatement(new ExecuteNode(outer.getLineNumber(), outer.getToken(), outer.getFinish(), outer));
      }
 
     /**
@@ -1105,12 +1113,13 @@
      */
     private void whileStatement() {
         // Capture WHILE token.
+        final int  whileLine  = line;
         final long whileToken = token;
         // WHILE tested in caller.
         next();
 
         // Construct WHILE node.
-        WhileNode whileNode = new WhileNode(source, whileToken, Token.descPosition(whileToken), false);
+        WhileNode whileNode = new WhileNode(whileLine, whileToken, Token.descPosition(whileToken), false);
         lc.push(whileNode);
 
         try {
@@ -1136,11 +1145,12 @@
      */
     private void doStatement() {
         // Capture DO token.
+        final int  doLine  = line;
         final long doToken = token;
         // DO tested in the caller.
         next();
 
-        WhileNode doWhileNode = new WhileNode(source, doToken, Token.descPosition(doToken), true);
+        WhileNode doWhileNode = new WhileNode(doLine, doToken, Token.descPosition(doToken), true);
         lc.push(doWhileNode);
 
         try {
@@ -1172,6 +1182,7 @@
      */
     private void continueStatement() {
         // Capture CONTINUE token.
+        final int  continueLine  = line;
         final long continueToken = token;
         // CONTINUE tested in caller.
         nextOrEOL();
@@ -1206,7 +1217,7 @@
         endOfLine();
 
         // Construct and add CONTINUE node.
-        appendStatement(new ContinueNode(source, continueToken, finish, label == null ? null : new IdentNode(label)));
+        appendStatement(new ContinueNode(continueLine, continueToken, finish, label == null ? null : new IdentNode(label)));
     }
 
     /**
@@ -1218,6 +1229,7 @@
      */
     private void breakStatement() {
         // Capture BREAK token.
+        final int  breakLine  = line;
         final long breakToken = token;
         // BREAK tested in caller.
         nextOrEOL();
@@ -1253,7 +1265,7 @@
         endOfLine();
 
         // Construct and add BREAK node.
-        appendStatement(new BreakNode(source, breakToken, finish, label == null ? null : new IdentNode(label)));
+        appendStatement(new BreakNode(breakLine, breakToken, finish, label == null ? null : new IdentNode(label)));
     }
 
     /**
@@ -1271,6 +1283,7 @@
         }
 
         // Capture RETURN token.
+        final int  returnLine  = line;
         final long returnToken = token;
         // RETURN tested in caller.
         nextOrEOL();
@@ -1292,7 +1305,7 @@
         endOfLine();
 
         // Construct and add RETURN node.
-        appendStatement(new ReturnNode(source, returnToken, finish, expression));
+        appendStatement(new ReturnNode(returnLine, returnToken, finish, expression));
     }
 
     /**
@@ -1305,6 +1318,7 @@
      */
     private void yieldStatement() {
         // Capture YIELD token.
+        final int  yieldLine  = line;
         final long yieldToken = token;
         // YIELD tested in caller.
         nextOrEOL();
@@ -1326,7 +1340,7 @@
         endOfLine();
 
         // Construct and add YIELD node.
-        appendStatement(new ReturnNode(source, yieldToken, finish, expression));
+        appendStatement(new ReturnNode(yieldLine, yieldToken, finish, expression));
     }
 
     /**
@@ -1339,6 +1353,7 @@
      */
     private void withStatement() {
         // Capture WITH token.
+        final int  withLine  = line;
         final long withToken = token;
         // WITH tested in caller.
         next();
@@ -1349,7 +1364,7 @@
         }
 
         // Get WITH expression.
-        WithNode withNode = new WithNode(source, withToken, finish);
+        WithNode withNode = new WithNode(withLine, withToken, finish);
 
         try {
             lc.push(withNode);
@@ -1387,12 +1402,13 @@
      * Parse SWITCH statement.
      */
     private void switchStatement() {
+        final int  switchLine  = line;
         final long switchToken = token;
         // SWITCH tested in caller.
         next();
 
         // Create and add switch statement.
-        SwitchNode switchNode = new SwitchNode(source, switchToken, Token.descPosition(switchToken), null, new ArrayList<CaseNode>(), null);
+        SwitchNode switchNode = new SwitchNode(switchLine, switchToken, Token.descPosition(switchToken), null, new ArrayList<CaseNode>(), null);
         lc.push(switchNode);
 
         try {
@@ -1434,7 +1450,7 @@
 
                 // Get CASE body.
                 final Block statements = getBlock(false);
-                final CaseNode caseNode = new CaseNode(source, caseToken, finish, caseExpression, statements);
+                final CaseNode caseNode = new CaseNode(caseToken, finish, caseExpression, statements);
                 statements.setFinish(finish);
 
                 if (caseExpression == null) {
@@ -1474,7 +1490,7 @@
             throw error(AbstractParser.message("duplicate.label", ident.getName()), labelToken);
         }
 
-        LabelNode labelNode = new LabelNode(source, labelToken, finish, ident, null);
+        LabelNode labelNode = new LabelNode(line, labelToken, finish, ident, null);
         try {
             lc.push(labelNode);
             labelNode = labelNode.setBody(lc, getStatement());
@@ -1496,6 +1512,7 @@
      */
     private void throwStatement() {
         // Capture THROW token.
+        final int  throwLine  = line;
         final long throwToken = token;
         // THROW tested in caller.
         nextOrEOL();
@@ -1520,7 +1537,7 @@
 
         endOfLine();
 
-        appendStatement(new ThrowNode(source, throwToken, finish, expression));
+        appendStatement(new ThrowNode(throwLine, throwToken, finish, expression));
     }
 
     /**
@@ -1542,6 +1559,7 @@
      */
     private void tryStatement() {
         // Capture TRY token.
+        final int  tryLine  = line;
         final long tryToken = token;
         // TRY tested in caller.
         next();
@@ -1556,6 +1574,7 @@
             final List<Block> catchBlocks = new ArrayList<>();
 
             while (type == CATCH) {
+                final int  catchLine  = line;
                 final long catchToken = token;
                 next();
                 expect(LPAREN);
@@ -1578,7 +1597,7 @@
                 try {
                     // Get CATCH body.
                     final Block catchBody = getBlock(true);
-                    final CatchNode catchNode = new CatchNode(source, catchToken, finish, exception, ifExpression, catchBody);
+                    final CatchNode catchNode = new CatchNode(catchLine, catchToken, finish, exception, ifExpression, catchBody);
                     appendStatement(catchNode);
                 } finally {
                     catchBlock = restoreBlock(catchBlock);
@@ -1604,7 +1623,7 @@
                 throw error(AbstractParser.message("missing.catch.or.finally"), tryToken);
             }
 
-            final TryNode tryNode = new TryNode(source, tryToken, Token.descPosition(tryToken), tryBody, catchBlocks, finallyStatements);
+            final TryNode tryNode = new TryNode(tryLine, tryToken, Token.descPosition(tryToken), tryBody, catchBlocks, finallyStatements);
             // Add try.
             assert lc.peek() == outer;
             appendStatement(tryNode);
@@ -1616,7 +1635,7 @@
             outer = restoreBlock(outer);
         }
 
-        appendStatement(new ExecuteNode(source, outer.getToken(), outer.getFinish(), outer));
+        appendStatement(new ExecuteNode(outer.getLineNumber(), outer.getToken(), outer.getFinish(), outer));
     }
 
     /**
@@ -1629,11 +1648,12 @@
      */
     private void  debuggerStatement() {
         // Capture DEBUGGER token.
+        final int  debuggerLine  = line;
         final long debuggerToken = token;
         // DEBUGGER tested in caller.
         next();
         endOfLine();
-        appendStatement(new RuntimeNode(source, debuggerToken, finish, RuntimeNode.Request.DEBUGGER, new ArrayList<Node>()));
+        appendStatement(new ExecuteNode(debuggerLine, debuggerToken, finish, new RuntimeNode(debuggerToken, finish, RuntimeNode.Request.DEBUGGER, new ArrayList<Node>())));
     }
 
     /**
@@ -1653,13 +1673,14 @@
     @SuppressWarnings("fallthrough")
     private Node primaryExpression() {
         // Capture first token.
+        final int  primaryLine  = line;
         final long primaryToken = token;
 
         switch (type) {
         case THIS:
             final String name = type.getName();
             next();
-            return new IdentNode(source, primaryToken, finish, name);
+            return new IdentNode(primaryToken, finish, name);
         case IDENT:
             final IdentNode ident = getIdent();
             if (ident == null) {
@@ -1680,16 +1701,16 @@
         case XML:
             return getLiteral();
         case EXECSTRING:
-            return execString(primaryToken);
+            return execString(primaryLine, primaryToken);
         case FALSE:
             next();
-            return LiteralNode.newInstance(source, primaryToken, finish, false);
+            return LiteralNode.newInstance(primaryToken, finish, false);
         case TRUE:
             next();
-            return LiteralNode.newInstance(source, primaryToken, finish, true);
+            return LiteralNode.newInstance(primaryToken, finish, true);
         case NULL:
             next();
-            return LiteralNode.newInstance(source, primaryToken, finish);
+            return LiteralNode.newInstance(primaryToken, finish);
         case LBRACKET:
             return arrayLiteral();
         case LBRACE:
@@ -1724,9 +1745,9 @@
      * @param primaryToken Original string token.
      * @return callNode to $EXEC.
      */
-    Node execString(final long primaryToken) {
+    Node execString(final int primaryLine, final long primaryToken) {
         // Synthesize an ident to call $EXEC.
-        final IdentNode execIdent = new IdentNode(source, primaryToken, finish, ScriptingFunctions.EXEC_NAME);
+        final IdentNode execIdent = new IdentNode(primaryToken, finish, ScriptingFunctions.EXEC_NAME);
         // Skip over EXECSTRING.
         next();
         // Set up argument list for call.
@@ -1738,7 +1759,7 @@
         // Skip ending of edit string expression.
         expect(RBRACE);
 
-        return new CallNode(source, primaryToken, finish, execIdent, arguments);
+        return new CallNode(primaryLine, primaryToken, finish, execIdent, arguments);
     }
 
     /**
@@ -1809,7 +1830,7 @@
             }
         }
 
-        return LiteralNode.newInstance(source, arrayToken, finish, elements);
+        return LiteralNode.newInstance(arrayToken, finish, elements);
     }
 
     /**
@@ -1916,7 +1937,7 @@
                             map.put(key, newProperty = newProperty.setValue(value));
                         } else {
                             final long propertyToken = Token.recast(newProperty.getToken(), COMMARIGHT);
-                            map.put(key, newProperty = newProperty.setValue(new BinaryNode(source, propertyToken, prevValue, value)));
+                            map.put(key, newProperty = newProperty.setValue(new BinaryNode(propertyToken, prevValue, value)));
                         }
 
                         map.put(key, newProperty = newProperty.setGetter(null).setSetter(null));
@@ -1933,7 +1954,7 @@
             }
         }
 
-        return new ObjectNode(source, objectToken, finish, new ArrayList<Node>(map.values()));
+        return new ObjectNode(objectToken, finish, new ArrayList<Node>(map.values()));
     }
 
     /**
@@ -2003,16 +2024,16 @@
                 case "get":
                     final PropertyKey getIdent = propertyName();
                     final String getterName = getIdent.getPropertyName();
-                    final IdentNode getNameNode = new IdentNode(source, ((Node)getIdent).getToken(), finish, "get " + getterName);
+                    final IdentNode getNameNode = new IdentNode(((Node)getIdent).getToken(), finish, "get " + getterName);
                     expect(LPAREN);
                     expect(RPAREN);
                     functionNode = functionBody(getSetToken, getNameNode, new ArrayList<IdentNode>(), FunctionNode.Kind.GETTER);
-                    return new PropertyNode(source, propertyToken, finish, getIdent, null, functionNode, null);
+                    return new PropertyNode(propertyToken, finish, getIdent, null, functionNode, null);
 
                 case "set":
                     final PropertyKey setIdent = propertyName();
                     final String setterName = setIdent.getPropertyName();
-                    final IdentNode setNameNode = new IdentNode(source, ((Node)setIdent).getToken(), finish, "set " + setterName);
+                    final IdentNode setNameNode = new IdentNode(((Node)setIdent).getToken(), finish, "set " + setterName);
                     expect(LPAREN);
                     final IdentNode argIdent = getIdent();
                     verifyStrictIdent(argIdent, "setter argument");
@@ -2020,21 +2041,21 @@
                     List<IdentNode> parameters = new ArrayList<>();
                     parameters.add(argIdent);
                     functionNode = functionBody(getSetToken, setNameNode, parameters, FunctionNode.Kind.SETTER);
-                    return new PropertyNode(source, propertyToken, finish, setIdent, null, null, functionNode);
+                    return new PropertyNode(propertyToken, finish, setIdent, null, null, functionNode);
 
                 default:
                     break;
                 }
             }
 
-            propertyName =  new IdentNode(source, propertyToken, finish, ident);
+            propertyName =  new IdentNode(propertyToken, finish, ident);
         } else {
             propertyName = propertyName();
         }
 
         expect(COLON);
 
-        return new PropertyNode(source, propertyToken, finish, propertyName, assignmentExpression(false), null, null);
+        return new PropertyNode(propertyToken, finish, propertyName, assignmentExpression(false), null, null);
     }
 
     /**
@@ -2054,6 +2075,7 @@
      * @return Expression node.
      */
     private Node leftHandSideExpression() {
+        int  callLine  = line;
         long callToken = token;
 
         Node lhs = memberExpression();
@@ -2066,12 +2088,13 @@
                 detectSpecialFunction((IdentNode)lhs);
             }
 
-            lhs = new CallNode(source, callToken, finish, lhs, arguments);
+            lhs = new CallNode(callLine, callToken, finish, lhs, arguments);
         }
 
 loop:
         while (true) {
             // Capture token.
+            callLine  = line;
             callToken = token;
 
             switch (type) {
@@ -2080,7 +2103,7 @@
                 final List<Node> arguments = argumentList();
 
                 // Create call node.
-                lhs = new CallNode(source, callToken, finish, lhs, arguments);
+                lhs = new CallNode(callLine, callToken, finish, lhs, arguments);
 
                 break;
 
@@ -2093,7 +2116,7 @@
                 expect(RBRACKET);
 
                 // Create indexing node.
-                lhs = new IndexNode(source, callToken, finish, lhs, rhs);
+                lhs = new IndexNode(callToken, finish, lhs, rhs);
 
                 break;
 
@@ -2103,7 +2126,7 @@
                 final IdentNode property = getIdentifierName();
 
                 // Create property access node.
-                lhs = new AccessNode(source, callToken, finish, lhs, property);
+                lhs = new AccessNode(callToken, finish, lhs, property);
 
                 break;
 
@@ -2131,6 +2154,7 @@
         next();
 
         // Get function base.
+        final int  callLine    = line;
         final Node constructor = memberExpression();
         if (constructor == null) {
             return null;
@@ -2159,9 +2183,9 @@
             arguments.add(objectLiteral());
         }
 
-        final CallNode callNode = new CallNode(source, constructor.getToken(), finish, constructor, arguments);
+        final CallNode callNode = new CallNode(callLine, constructor.getToken(), finish, constructor, arguments);
 
-        return new UnaryNode(source, newToken, callNode);
+        return new UnaryNode(newToken, callNode);
     }
 
     /**
@@ -2213,7 +2237,7 @@
                 expect(RBRACKET);
 
                 // Create indexing node.
-                lhs = new IndexNode(source, callToken, finish, lhs, index);
+                lhs = new IndexNode(callToken, finish, lhs, index);
 
                 break;
 
@@ -2227,7 +2251,7 @@
                 final IdentNode property = getIdentifierName();
 
                 // Create property access node.
-                lhs = new AccessNode(source, callToken, finish, lhs, property);
+                lhs = new AccessNode(callToken, finish, lhs, property);
 
                 break;
 
@@ -2294,9 +2318,8 @@
      * @return Expression node.
      */
     private Node functionExpression(final boolean isStatement, final boolean topLevel) {
-        final LineNumberNode lineNumber = lineNumber();
-
         final long functionToken = token;
+        final int  functionLine  = line;
         // FUNCTION is tested in caller.
         next();
 
@@ -2316,7 +2339,7 @@
         boolean isAnonymous = false;
         if (name == null) {
             final String tmpName = "_L" + source.getLine(Token.descPosition(token));
-            name = new IdentNode(source, functionToken, Token.descPosition(functionToken), tmpName);
+            name = new IdentNode(functionToken, Token.descPosition(functionToken), tmpName);
             isAnonymous = true;
         }
 
@@ -2367,7 +2390,7 @@
                     // rename in non-strict mode
                     parameterName = functionNode.uniqueName(parameterName);
                     final long parameterToken = parameter.getToken();
-                    parameters.set(i, new IdentNode(source, parameterToken, Token.descPosition(parameterToken), functionNode.uniqueName(parameterName)));
+                    parameters.set(i, new IdentNode(parameterToken, Token.descPosition(parameterToken), functionNode.uniqueName(parameterName)));
                 }
 
                 parametersSet.add(parameterName);
@@ -2379,12 +2402,10 @@
         }
 
         if (isStatement) {
-            final VarNode varNode = new VarNode(source, functionToken, finish, name, functionNode, VarNode.IS_STATEMENT);
+            final VarNode varNode = new VarNode(functionLine, functionToken, finish, name, functionNode, VarNode.IS_STATEMENT);
             if (topLevel) {
-                functionDeclarations.add(lineNumber);
                 functionDeclarations.add(varNode);
             } else {
-                appendStatement(lineNumber);
                 appendStatement(varNode);
             }
         }
@@ -2459,7 +2480,7 @@
                 assert lc.getCurrentBlock() == lc.getFunctionBody(functionNode);
                 // create a return statement - this creates code in itself and does not need to be
                 // wrapped into an ExecuteNode
-                final ReturnNode returnNode = new ReturnNode(source, expr.getToken(), finish, expr);
+                final ReturnNode returnNode = new ReturnNode(functionNode.getLineNumber(), expr.getToken(), finish, expr);
                 appendStatement(returnNode);
                 lastToken = token;
                 functionNode.setFinish(Token.descPosition(token) + Token.descLength(token));
@@ -2468,7 +2489,7 @@
                 expect(LBRACE);
 
                 // Gather the function elements.
-                final List<Node> prevFunctionDecls = functionDeclarations;
+                final List<Statement> prevFunctionDecls = functionDeclarations;
                 functionDeclarations = new ArrayList<>();
                 try {
                     sourceElements();
@@ -2492,7 +2513,7 @@
         assert lc.peek() == lc.getFunctionBody(functionNode);
         VarNode lastDecl = null;
         for (int i = functionDeclarations.size() - 1; i >= 0; i--) {
-            Node decl = functionDeclarations.get(i);
+            Statement decl = functionDeclarations.get(i);
             if (lastDecl == null && decl instanceof VarNode) {
                 decl = lastDecl = ((VarNode)decl).setFlag(VarNode.IS_LAST_FUNCTION_DECLARATION);
                 lc.setFlag(functionNode, FunctionNode.HAS_FUNCTION_DECLARATIONS);
@@ -2501,16 +2522,16 @@
         }
     }
 
-    private RuntimeNode referenceError(final Node lhs, final Node rhs) {
+    private static RuntimeNode referenceError(final Node lhs, final Node rhs) {
         final ArrayList<Node> args = new ArrayList<>();
         args.add(lhs);
         if (rhs == null) {
-            args.add(LiteralNode.newInstance(source, lhs.getToken(), lhs.getFinish()));
+            args.add(LiteralNode.newInstance(lhs.getToken(), lhs.getFinish()));
         } else {
             args.add(rhs);
         }
-        args.add(LiteralNode.newInstance(source, lhs.getToken(), lhs.getFinish(), lhs.toString()));
-        return new RuntimeNode(source, lhs.getToken(), lhs.getFinish(), RuntimeNode.Request.REFERENCE_ERROR, args);
+        args.add(LiteralNode.newInstance(lhs.getToken(), lhs.getFinish(), lhs.toString()));
+        return new RuntimeNode(lhs.getToken(), lhs.getFinish(), RuntimeNode.Request.REFERENCE_ERROR, args);
     }
 
     /*
@@ -2548,10 +2569,19 @@
      * @return Expression node.
      */
     private Node unaryExpression() {
+        final int  unaryLine  = line;
         final long unaryToken = token;
 
         switch (type) {
-        case DELETE:
+        case DELETE: {
+            next();
+            final Node expr = unaryExpression();
+            if (expr instanceof BaseNode || expr instanceof IdentNode) {
+                return new UnaryNode(unaryToken, expr);
+            }
+            appendStatement(new ExecuteNode(unaryLine, unaryToken, finish, expr));
+            return LiteralNode.newInstance(unaryToken, finish, true);
+        }
         case VOID:
         case TYPEOF:
         case ADD:
@@ -2560,7 +2590,7 @@
         case NOT:
             next();
             final Node expr = unaryExpression();
-            return new UnaryNode(source, unaryToken, expr);
+            return new UnaryNode(unaryToken, expr);
 
         case INCPREFIX:
         case DECPREFIX:
@@ -2749,7 +2779,7 @@
                 final Node third = expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
 
                 // Build up node.
-                lhs = new TernaryNode(source, op, lhs, rhs, third);
+                lhs = new TernaryNode(op, lhs, rhs, third);
             } else {
                 // Skip operator.
                 next();
@@ -2805,16 +2835,6 @@
         }
     }
 
-    /**
-     * Add a line number node at current position
-     */
-    private LineNumberNode lineNumber() {
-        if (env._debug_lines) {
-            return new LineNumberNode(source, token, line);
-        }
-        return null;
-    }
-
     @Override
     public String toString() {
         return "[JavaScript Parsing]";
@@ -2835,11 +2855,11 @@
         }
     }
 
-    private void prependStatement(final Node statement) {
+    private void prependStatement(final Statement statement) {
         lc.prependStatement(statement);
     }
 
-    private void appendStatement(final Node statement) {
+    private void appendStatement(final Statement statement) {
         lc.appendStatement(statement);
     }
 }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
index b0ca46f..38effda 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
@@ -50,8 +50,6 @@
 /**
  * An AccessorProperty is the most generic property type. An AccessorProperty is
  * represented as fields in a ScriptObject class.
- *
- * @see SpillProperty
  */
 public class AccessorProperty extends Property {
     private static final MethodHandles.Lookup lookup = MethodHandles.lookup();
@@ -77,6 +75,7 @@
 
     private static final MethodType[] ACCESSOR_GETTER_TYPES = new MethodType[NOOF_TYPES];
     private static final MethodType[] ACCESSOR_SETTER_TYPES = new MethodType[NOOF_TYPES];
+    private static final MethodHandle SPILLGETTER = MH.asType(MH.getter(MethodHandles.lookup(), ScriptObject.class, "spill", Object[].class), Lookup.GET_OBJECT_TYPE);
 
     /** Seed getter for the primitive version of this field (in -Dnashorn.fields.dual=true mode) */
     private MethodHandle primitiveGetter;
@@ -285,7 +284,7 @@
                 "get");
         }
 
-        return getters[i];
+        return isSpill() ? MH.filterArguments(getters[i], 0, SPILLGETTER) : getters[i];
     }
 
     private Property getWiderProperty(final Class<?> type) {
@@ -327,6 +326,7 @@
         final Class<?> forType = currentType == null ? type : currentType;
 
         //if we are asking for an object setter, but are still a primitive type, we might try to box it
+        MethodHandle mh;
 
         if (needsInvalidator(i, ci)) {
             final Property     newProperty = getWiderProperty(type);
@@ -335,12 +335,15 @@
             final MethodHandle explodeTypeSetter = MH.filterArguments(widerSetter, 0, MH.insertArguments(REPLACE_MAP, 1, newMap, getKey(), currentType, type));
             if (currentType != null && currentType.isPrimitive() && type == Object.class) {
                 //might try a box check on this to avoid widening field to object storage
-                return createGuardBoxedPrimitiveSetter(currentType, generateSetter(currentType, currentType), explodeTypeSetter);
+                mh = createGuardBoxedPrimitiveSetter(currentType, generateSetter(currentType, currentType), explodeTypeSetter);
+            } else {
+                mh = explodeTypeSetter;
             }
-            return explodeTypeSetter;
+        } else {
+            mh = generateSetter(forType, type);
         }
 
-        return generateSetter(forType, type);
+        return isSpill() ? MH.filterArguments(mh, 0, SPILLGETTER) : mh;
     }
 
     @Override
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java b/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java
index 3cc9f09..d36f216 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java
@@ -88,7 +88,7 @@
 
         int weight = Type.typeFor(type.returnType()).getWeight();
         for (final Class<?> paramType : type.parameterArray()) {
-            final int pweight = Type.typeFor(paramType).getWeight();
+            final int pweight = Type.typeFor(paramType).getWeight() * 2; //params are more important than call types as return values are always specialized
             weight += pweight;
         }
         return weight;
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunctions.java b/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunctions.java
index ff660d3..1ddc42b 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunctions.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunctions.java
@@ -69,5 +69,4 @@
         return best(type).moreGenericThan(type);
     }
 
-
 }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java
index 40fe1ba..338a826 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java
@@ -201,9 +201,6 @@
     /** Current error manager. */
     private final ErrorManager errors;
 
-    /** Empty map used for seed map for JO objects */
-    final PropertyMap emptyMap = PropertyMap.newEmptyMap(this);
-
     private static final ClassLoader myLoader = Context.class.getClassLoader();
     private static final StructureLoader sharedLoader;
 
@@ -414,7 +411,7 @@
         return ScriptRuntime.apply(func, evalThis);
     }
 
-    private Source loadInternal(final String srcStr, final String prefix, final String resourcePath) {
+    private static Source loadInternal(final String srcStr, final String prefix, final String resourcePath) {
         if (srcStr.startsWith(prefix)) {
             final String resource = resourcePath + srcStr.substring(prefix.length());
             // NOTE: even sandbox scripts should be able to load scripts in nashorn: scheme
@@ -513,7 +510,7 @@
 
     /**
      * Lookup a Java class. This is used for JSR-223 stuff linking in from
-     * {@link jdk.nashorn.internal.objects.NativeJava} and {@link jdk.nashorn.internal.runtime.NativeJavaPackage}
+     * {@code jdk.nashorn.internal.objects.NativeJava} and {@code jdk.nashorn.internal.runtime.NativeJavaPackage}
      *
      * @param fullName full name of class to load
      *
@@ -762,10 +759,10 @@
         final CodeSource   cs     = url == null ? null : new CodeSource(url, (CodeSigner[])null);
         final CodeInstaller<ScriptEnvironment> installer = new ContextCodeInstaller(this, loader, cs);
 
-        final Compiler compiler = new Compiler(installer, functionNode, strict);
+        final Compiler compiler = new Compiler(installer, strict);
 
-        compiler.compile();
-        script = compiler.install();
+        final FunctionNode newFunctionNode = compiler.compile(functionNode);
+        script = compiler.install(newFunctionNode);
 
         if (global != null) {
             global.cacheClass(source, script);
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java b/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java
index 729df58..6106a31 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java
@@ -25,8 +25,6 @@
 
 package jdk.nashorn.internal.runtime;
 
-import static jdk.nashorn.internal.runtime.ScriptObject.isArray;
-
 import java.lang.invoke.MethodHandle;
 import java.util.Iterator;
 import java.util.List;
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Property.java b/nashorn/src/jdk/nashorn/internal/runtime/Property.java
index dfb8bf5..585fc4b 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/Property.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Property.java
@@ -41,7 +41,6 @@
  *
  * @see PropertyMap
  * @see AccessorProperty
- * @see SpillProperty
  * @see UserAccessorProperty
  */
 public abstract class Property {
@@ -64,7 +63,7 @@
 
     private static final int MODIFY_MASK     = 0b0000_0000_1111;
 
-    /** Is this a spill property? See {@link SpillProperty} */
+    /** Is this a spill property? See {@link AccessorProperty} */
     public static final int IS_SPILL         = 0b0000_0001_0000;
 
     /** Is this a function parameter? */
@@ -88,7 +87,7 @@
     /** Property flags. */
     protected int flags;
 
-    /** Property field number or spill slot */
+    /** Property field number or spill slot. */
     private final int slot;
 
     /**
@@ -248,7 +247,7 @@
      * Does this property use any slots in the spill array described in
      * {@link Property#isSpill}? In that case how many. Currently a property
      * only uses max one spill slot, but this may change in future representations
-     * Only {@link SpillProperty} instances use spill slots
+     * Only {@link AccessorProperty} instances use spill slots
      *
      * @return number of spill slots a property is using
      */
@@ -345,6 +344,14 @@
     }
 
     /**
+     * Get the field number or spill slot
+     * @return number/slot, -1 if none exists
+     */
+    public int getSlot() {
+        return slot;
+    }
+
+    /**
      * Abstract method for retrieving the setter for the property. We do not know
      * anything about the internal representation when we request the setter, we only
      * know that the setter will take the property as a parameter of the given type.
@@ -388,14 +395,6 @@
         return null;
     }
 
-    /**
-     * Get the field number or spill slot
-     * @return number/slot, -1 if none exists
-     */
-    public int getSlot() {
-        return slot;
-    }
-
     @Override
     public int hashCode() {
         final Class<?> type = getCurrentType();
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/PropertyHashMap.java b/nashorn/src/jdk/nashorn/internal/runtime/PropertyHashMap.java
index 6e41fd5..bfa0692 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/PropertyHashMap.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyHashMap.java
@@ -110,7 +110,7 @@
     private static final int LIST_THRESHOLD = 8;
 
     /** Initial map. */
-    public static final PropertyHashMap EMPTY_MAP = new PropertyHashMap();
+    public static final PropertyHashMap EMPTY_HASHMAP = new PropertyHashMap();
 
     /** Number of properties in the map. */
     private final int size;
@@ -246,7 +246,7 @@
             }
         } else if (findElement(list, key) != null) {
             final int newSize = size - 1;
-            return newSize != 0 ? new PropertyHashMap(newSize, null, removeFromList(list, key)) : EMPTY_MAP;
+            return newSize != 0 ? new PropertyHashMap(newSize, null, removeFromList(list, key)) : EMPTY_HASHMAP;
         }
         return this;
     }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
index b5154c8..077218d 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
@@ -25,7 +25,7 @@
 
 package jdk.nashorn.internal.runtime;
 
-import static jdk.nashorn.internal.runtime.PropertyHashMap.EMPTY_MAP;
+import static jdk.nashorn.internal.runtime.PropertyHashMap.EMPTY_HASHMAP;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.SwitchPoint;
@@ -49,29 +49,27 @@
  * will return a new map.
  */
 public final class PropertyMap implements Iterable<Object>, PropertyListener {
-    /** Is this a prototype PropertyMap? */
-    public static final int IS_PROTOTYPE          = 0b0000_0001;
     /** Used for non extensible PropertyMaps, negative logic as the normal case is extensible. See {@link ScriptObject#preventExtensions()} */
-    public static final int NOT_EXTENSIBLE        = 0b0000_0010;
+    public static final int NOT_EXTENSIBLE        = 0b0000_0001;
     /** This mask is used to preserve certain flags when cloning the PropertyMap. Others should not be copied */
     private static final int CLONEABLE_FLAGS_MASK = 0b0000_1111;
     /** Has a listener been added to this property map. This flag is not copied when cloning a map. See {@link PropertyListener} */
     public static final int IS_LISTENER_ADDED     = 0b0001_0000;
 
+    /** Empty map used for seed map for JO$ objects */
+    private static final PropertyMap EMPTY_MAP = new PropertyMap(EMPTY_HASHMAP);
+
     /** Map status flags. */
     private int flags;
 
-    /** Class of object referenced.*/
-    private final Class<?> structure;
-
-    /** Context associated with this {@link PropertyMap}. */
-    private final Context context;
-
     /** Map of properties. */
     private final PropertyHashMap properties;
 
-    /** objects proto. */
-    private ScriptObject proto;
+    /** Number of fields in use. */
+    private int fieldCount;
+
+    /** Number of fields available. */
+    private int fieldMaximum;
 
     /** Length of spill in use. */
     private int spillLength;
@@ -91,15 +89,15 @@
     /**
      * Constructor.
      *
-     * @param structure  Class the map's {@link AccessorProperty}s apply to.
-     * @param context    Context associated with this {@link PropertyMap}.
-     * @param properties A {@link PropertyHashMap} with initial contents.
+     * @param properties    A {@link PropertyHashMap} with initial contents.
+     * @param fieldCount    Number of fields in use.
+     * @param fieldMaximum Number of fields available.
      */
-    PropertyMap(final Class<?> structure, final Context context, final PropertyHashMap properties) {
-        this.structure  = structure;
-        this.context    = context;
-        this.properties = properties;
-        this.hashCode   = computeHashCode();
+    private PropertyMap(final PropertyHashMap properties, final int fieldCount, final int fieldMaximum) {
+        this.properties   = properties;
+        this.hashCode     = computeHashCode();
+        this.fieldCount   = fieldCount;
+        this.fieldMaximum = fieldMaximum;
 
         if (Context.DEBUG) {
             count++;
@@ -107,19 +105,27 @@
     }
 
     /**
+     * Constructor.
+     *
+     * @param properties A {@link PropertyHashMap} with initial contents.
+     */
+    private PropertyMap(final PropertyHashMap properties) {
+        this(properties, 0, 0);
+    }
+
+    /**
      * Cloning constructor.
      *
      * @param propertyMap Existing property map.
      * @param properties  A {@link PropertyHashMap} with a new set of properties.
      */
     private PropertyMap(final PropertyMap propertyMap, final PropertyHashMap properties) {
-        this.structure   = propertyMap.structure;
-        this.context     = propertyMap.context;
-        this.properties  = properties;
-        this.flags       = propertyMap.getClonedFlags();
-        this.proto       = propertyMap.proto;
-        this.spillLength = propertyMap.spillLength;
-        this.hashCode    = computeHashCode();
+        this.properties   = properties;
+        this.flags        = propertyMap.getClonedFlags();
+        this.spillLength  = propertyMap.spillLength;
+        this.fieldCount   = propertyMap.fieldCount;
+        this.fieldMaximum = propertyMap.fieldMaximum;
+        this.hashCode     = computeHashCode();
 
         if (Context.DEBUG) {
             count++;
@@ -128,6 +134,15 @@
     }
 
     /**
+     * Cloning constructor.
+     *
+     * @param propertyMap Existing property map.
+      */
+    private PropertyMap(final PropertyMap propertyMap) {
+        this(propertyMap, propertyMap.properties);
+    }
+
+    /**
      * Duplicates this PropertyMap instance. This is used by nasgen generated
      * prototype and constructor classes. {@link PropertyMap} used for singletons
      * like these (and global instance) are duplicated using this method and used.
@@ -138,7 +153,7 @@
      * @return Duplicated {@link PropertyMap}.
      */
     public PropertyMap duplicate() {
-        return new PropertyMap(this.structure, this.context, this.properties);
+        return new PropertyMap(this.properties);
     }
 
     /**
@@ -146,20 +161,20 @@
      *
      * @param structure  Class the map's {@link AccessorProperty}s apply to.
      * @param properties Collection of initial properties.
+     * @param fieldCount    Number of fields in use.
+     * @param fieldMaximum Number of fields available.
      *
      * @return New {@link PropertyMap}.
      */
-    public static PropertyMap newMap(final Class<?> structure, final Collection<Property> properties) {
-        final Context context = Context.fromClass(structure);
-
+    public static PropertyMap newMap(final Class<?> structure, final Collection<Property> properties, final int fieldCount, final int fieldMaximum) {
         // Reduce the number of empty maps in the context.
         if (structure == jdk.nashorn.internal.scripts.JO.class) {
-            return context.emptyMap;
+            return EMPTY_MAP;
         }
 
-        PropertyHashMap newProperties = EMPTY_MAP.immutableAdd(properties);
+        PropertyHashMap newProperties = EMPTY_HASHMAP.immutableAdd(properties);
 
-        return new PropertyMap(structure, context, newProperties);
+        return new PropertyMap(newProperties, fieldCount, fieldMaximum);
     }
 
     /**
@@ -170,7 +185,7 @@
      * @return New {@link PropertyMap}.
      */
     public static PropertyMap newMap(final Class<?> structure) {
-        return newMap(structure, null);
+        return newMap(structure, null, 0, 0);
     }
 
     /**
@@ -180,7 +195,7 @@
      * @return New empty {@link PropertyMap}.
      */
     public static PropertyMap newEmptyMap(final Context context) {
-        return new PropertyMap(jdk.nashorn.internal.scripts.JO.class, context, EMPTY_MAP);
+        return new PropertyMap(EMPTY_HASHMAP);
     }
 
     /**
@@ -195,11 +210,12 @@
     /**
      * Return a SwitchPoint used to track changes of a property in a prototype.
      *
-     * @param key {@link Property} key.
+     * @param proto  Object prototype.
+     * @param key    {@link Property} key.
      *
      * @return A shared {@link SwitchPoint} for the property.
      */
-    public SwitchPoint getProtoGetSwitchPoint(final String key) {
+    public SwitchPoint getProtoGetSwitchPoint(final ScriptObject proto, final String key) {
         if (proto == null) {
             return null;
         }
@@ -295,6 +311,11 @@
             final PropertyHashMap newProperties = properties.immutableAdd(property);
             newMap = new PropertyMap(this, newProperties);
             addToHistory(property, newMap);
+
+            if(!property.isSpill()) {
+                newMap.fieldCount = Math.max(newMap.fieldCount, property.getSlot() + 1);
+            }
+
             newMap.spillLength += property.getSpillCount();
         }
 
@@ -355,7 +376,6 @@
                 newProperty instanceof UserAccessorProperty) : "arbitrary replaceProperty attempted";
 
         newMap.flags = getClonedFlags();
-        newMap.proto = proto;
 
         /*
          * spillLength remains same in case (1) and (2) because of slot reuse. Only for case (3), we need
@@ -411,7 +431,7 @@
      * @return New map with {@link #NOT_EXTENSIBLE} flag set.
      */
     PropertyMap preventExtensions() {
-        final PropertyMap newMap = new PropertyMap(this, this.properties);
+        final PropertyMap newMap = new PropertyMap(this);
         newMap.flags |= NOT_EXTENSIBLE;
         return newMap;
     }
@@ -423,7 +443,7 @@
      * {@link Property#NOT_CONFIGURABLE} set.
      */
     PropertyMap seal() {
-        PropertyHashMap newProperties = EMPTY_MAP;
+        PropertyHashMap newProperties = EMPTY_HASHMAP;
 
         for (final Property oldProperty :  properties.getProperties()) {
             newProperties = newProperties.immutableAdd(oldProperty.addFlags(Property.NOT_CONFIGURABLE));
@@ -442,7 +462,7 @@
      * {@link Property#NOT_CONFIGURABLE} and {@link Property#NOT_WRITABLE} set.
      */
     PropertyMap freeze() {
-        PropertyHashMap newProperties = EMPTY_MAP;
+        PropertyHashMap newProperties = EMPTY_HASHMAP;
 
         for (Property oldProperty : properties.getProperties()) {
             int propertyFlags = Property.NOT_CONFIGURABLE;
@@ -578,11 +598,7 @@
      * @return Computed hash code.
      */
     private int computeHashCode() {
-        int hash = structure.hashCode();
-
-        if (proto != null) {
-            hash ^= proto.hashCode();
-        }
+        int hash = 0;
 
         for (final Property property : getProperties()) {
             hash = hash << 7 ^ hash >> 7;
@@ -605,9 +621,7 @@
 
         final PropertyMap otherMap = (PropertyMap)other;
 
-        if (structure != otherMap.structure ||
-            proto != otherMap.proto ||
-            properties.size() != otherMap.properties.size()) {
+        if (properties.size() != otherMap.properties.size()) {
             return false;
         }
 
@@ -659,31 +673,6 @@
     }
 
     /**
-     * Return map's {@link Context}.
-     *
-     * @return The {@link Context} where the map originated.
-     */
-    Context getContext() {
-        return context;
-    }
-
-    /**
-     * Check if this map is a prototype
-     *
-     * @return {@code true} if is prototype
-     */
-    public boolean isPrototype() {
-        return (flags & IS_PROTOTYPE) != 0;
-    }
-
-    /**
-     * Flag this map as having a prototype.
-     */
-    private void setIsPrototype() {
-        flags |= IS_PROTOTYPE;
-    }
-
-    /**
      * Check whether a {@link PropertyListener} has been added to this map.
      *
      * @return {@code true} if {@link PropertyListener} exists
@@ -720,6 +709,22 @@
     boolean isFrozen() {
         return !isExtensible() && allFrozen();
     }
+    /**
+     * Get the number of fields allocated for this {@link PropertyMap}.
+     *
+     * @return Number of fields allocated.
+     */
+    int getFieldCount() {
+        return fieldCount;
+    }
+    /**
+     * Get maximum number of fields available for this {@link PropertyMap}.
+     *
+     * @return Number of fields available.
+     */
+    int getFieldMaximum() {
+        return fieldMaximum;
+    }
 
     /**
      * Get length of spill area associated with this {@link PropertyMap}.
@@ -731,24 +736,14 @@
     }
 
     /**
-     * Return the prototype of objects associated with this {@link PropertyMap}.
+     * Change the prototype of objects associated with this {@link PropertyMap}.
      *
-     * @return Prototype object.
-     */
-    ScriptObject getProto() {
-        return proto;
-    }
-
-    /**
-     * Set the prototype of objects associated with this {@link PropertyMap}.
-     *
-     * @param newProto Prototype object to use.
+     * @param oldProto Current prototype object.
+     * @param newProto New prototype object to replace oldProto.
      *
      * @return New {@link PropertyMap} with prototype changed.
      */
-    PropertyMap setProto(final ScriptObject newProto) {
-        final ScriptObject oldProto = this.proto;
-
+    PropertyMap changeProto(final ScriptObject oldProto, final ScriptObject newProto) {
         if (oldProto == newProto) {
             return this;
         }
@@ -761,19 +756,10 @@
         if (Context.DEBUG) {
             incrementSetProtoNewMapCount();
         }
-        final PropertyMap newMap = new PropertyMap(this, this.properties);
+
+        final PropertyMap newMap = new PropertyMap(this);
         addToProtoHistory(newProto, newMap);
 
-        newMap.proto = newProto;
-
-        if (oldProto != null && newMap.isListenerAdded()) {
-            oldProto.removePropertyListener(newMap);
-        }
-
-        if (newProto != null) {
-            newProto.getMap().setIsPrototype();
-        }
-
         return newMap;
     }
 
@@ -927,4 +913,3 @@
         setProtoNewMapCount++;
     }
 }
-
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java b/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java
index c225989..03a25da 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java
@@ -30,9 +30,12 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
+import java.util.LinkedList;
+
 import jdk.nashorn.internal.codegen.Compiler;
 import jdk.nashorn.internal.codegen.CompilerConstants;
 import jdk.nashorn.internal.codegen.FunctionSignature;
+import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.ir.FunctionNode;
 import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
 import jdk.nashorn.internal.parser.Token;
@@ -148,10 +151,10 @@
 
          if (functionNode.isLazy()) {
              Compiler.LOG.info("Trampoline hit: need to do lazy compilation of '", functionNode.getName(), "'");
-             final Compiler compiler = new Compiler(installer, functionNode);
-             functionNode = compiler.compile();
+             final Compiler compiler = new Compiler(installer);
+             functionNode = compiler.compile(functionNode);
              assert !functionNode.isLazy();
-             compiler.install();
+             compiler.install(functionNode);
 
              // we don't need to update any flags - varArgs and needsCallee are instrincic
              // in the function world we need to get a destination node from the compile instead
@@ -164,23 +167,118 @@
          assert functionNode.hasState(CompilationState.EMITTED) : functionNode.getName() + " " + functionNode.getState() + " " + Debug.id(functionNode);
 
          // code exists - look it up and add it into the automatically sorted invoker list
-         code.add(
-            new CompiledFunction(
-                MH.findStatic(
-                    LOOKUP,
-                    functionNode.getCompileUnit().getCode(),
-                    functionNode.getName(),
-                    new FunctionSignature(functionNode).
-                        getMethodType())));
+         addCode(functionNode, null, null);
     }
 
+    private MethodHandle addCode(final FunctionNode fn, final MethodHandle guard, final MethodHandle fallback) {
+        final MethodHandle target =
+            MH.findStatic(
+                    LOOKUP,
+                    fn.getCompileUnit().getCode(),
+                    fn.getName(),
+                    new FunctionSignature(fn).
+                        getMethodType());
+        MethodHandle mh = target;
+        if (guard != null) {
+            try {
+                mh = MH.guardWithTest(MH.asCollector(guard, Object[].class, target.type().parameterCount()), MH.asType(target, fallback.type()), fallback);
+            } catch (Throwable e) {
+                e.printStackTrace();
+            }
+        }
+
+        final CompiledFunction cf = new CompiledFunction(mh);
+        code.add(cf);
+
+        return cf.getInvoker();
+    }
+
+    private static Type runtimeType(final Object arg) {
+        if (arg == null) {
+            return Type.OBJECT;
+        }
+
+        final Class<?> clazz = arg.getClass();
+        assert !clazz.isPrimitive() : "always boxed";
+        if (clazz == Double.class) {
+            return JSType.isRepresentableAsInt((double)arg) ? Type.INT : Type.NUMBER;
+        } else if (clazz == Integer.class) {
+            return Type.INT;
+        } else if (clazz == Long.class) {
+            return Type.LONG;
+        } else if (clazz == String.class) {
+            return Type.STRING;
+        }
+        return Type.OBJECT;
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean paramTypeGuard(final Type[] compileTimeTypes, final Type[] runtimeTypes, Object... args) {
+        //System.err.println("Param type guard " + Arrays.asList(args));
+        return false;
+    }
+
+    private static final MethodHandle PARAM_TYPE_GUARD = findOwnMH("paramTypeGuard", boolean.class, Type[].class, Type[].class, Object[].class);
+
     @Override
     MethodHandle getBestInvoker(final MethodType callSiteType, final Object[] args) {
         final MethodHandle mh = super.getBestInvoker(callSiteType, args);
-        if (code.isLessSpecificThan(callSiteType)) {
-            // opportunity for code specialization - we can regenerate a better version of this method
+
+        if (!functionNode.canSpecialize() || !code.isLessSpecificThan(callSiteType)) {
+            return mh;
         }
-        return mh;
+
+        final FunctionNode snapshot = functionNode.getSnapshot();
+        if (snapshot == null) {
+            return mh;
+        }
+
+        int i;
+
+        //classes known at runtime
+        final LinkedList<Type> runtimeArgs = new LinkedList<>();
+        for (i = args.length - 1; i >= args.length - snapshot.getParameters().size(); i--) {
+            runtimeArgs.addLast(runtimeType(args[i]));
+        }
+
+        //classes known at compile time
+        final LinkedList<Type> compileTimeArgs = new LinkedList<>();
+        for (i = callSiteType.parameterCount() - 1; i >= 0 && compileTimeArgs.size() < snapshot.getParameters().size(); i--) {
+            compileTimeArgs.addLast(Type.typeFor(callSiteType.parameterType(i)));
+        }
+
+        //the classes known at compile time are a safe to generate as primitives without parameter guards
+        //the classes known at runtime are safe to generate as primitives IFF there are parameter guards
+        MethodHandle guard = null;
+        for (i = 0; i < compileTimeArgs.size(); i++) {
+            final Type runtimeType = runtimeArgs.get(i);
+            final Type compileType = compileTimeArgs.get(i);
+
+            if (compileType.isObject() && !runtimeType.isObject()) {
+                if (guard == null) {
+                    guard = PARAM_TYPE_GUARD;
+                    guard = MH.insertArguments(guard, 0, compileTimeArgs.toArray(new Type[compileTimeArgs.size()]), runtimeArgs.toArray(new Type[runtimeArgs.size()]));
+                }
+            }
+        }
+
+        //System.err.println("Specialized " + name + " " + runtimeArgs + " known=" + compileTimeArgs);
+
+        assert snapshot != null;
+        assert snapshot != functionNode;
+
+        final Compiler compiler = new Compiler(installer);
+        final FunctionNode compiledSnapshot = compiler.compile(snapshot.setHints(null, new Compiler.Hints(compileTimeArgs.toArray(new Type[compileTimeArgs.size()]))));
+
+        compiler.install(compiledSnapshot);
+
+        final MethodHandle nmh = addCode(compiledSnapshot, guard, mh);
+
+        return nmh;
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findStatic(MethodHandles.lookup(), RecompilableScriptFunctionData.class, name, MH.type(rtype, types));
     }
 
 }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java
index 74fab0c..0a556f9 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java
@@ -26,9 +26,13 @@
 package jdk.nashorn.internal.runtime;
 
 import java.io.PrintWriter;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
+import java.util.Set;
+import java.util.StringTokenizer;
 import java.util.TimeZone;
+
 import jdk.nashorn.internal.codegen.Namespace;
 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
 import jdk.nashorn.internal.runtime.options.KeyValueOption;
@@ -136,6 +140,9 @@
     /** Print resulting bytecode for script */
     public final boolean _print_code;
 
+    /** Print memory usage for IR after each phase */
+    public final boolean _print_mem_usage;
+
     /** Print function will no print newline characters */
     public final boolean _print_no_newline;
 
@@ -151,6 +158,9 @@
     /** is this environment in scripting mode? */
     public final boolean _scripting;
 
+    /** is the JIT allowed to specializ calls based on callsite types? */
+    public final Set<String> _specialize_calls;
+
     /** is this environment in strict mode? */
     public final boolean _strict;
 
@@ -204,6 +214,7 @@
         _print_ast            = options.getBoolean("print.ast");
         _print_lower_ast      = options.getBoolean("print.lower.ast");
         _print_code           = options.getBoolean("print.code");
+        _print_mem_usage      = options.getBoolean("print.mem.usage");
         _print_no_newline     = options.getBoolean("print.no.newline");
         _print_parse          = options.getBoolean("print.parse");
         _print_lower_parse    = options.getBoolean("print.lower.parse");
@@ -213,6 +224,17 @@
         _version              = options.getBoolean("version");
         _verify_code          = options.getBoolean("verify.code");
 
+        final String specialize = options.getString("specialize.calls");
+        if (specialize == null) {
+            _specialize_calls = null;
+        } else {
+            _specialize_calls = new HashSet<>();
+            final StringTokenizer st = new StringTokenizer(specialize, ",");
+            while (st.hasMoreElements()) {
+                _specialize_calls.add(st.nextToken());
+            }
+        }
+
         int callSiteFlags = 0;
         if (options.getBoolean("profile.callsites")) {
             callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_PROFILE;
@@ -247,6 +269,18 @@
     }
 
     /**
+     * Can we specialize a particular method name?
+     * @param functionName method name
+     * @return true if we are allowed to generate versions of this method
+     */
+    public boolean canSpecialize(final String functionName) {
+        if (_specialize_calls == null) {
+            return false;
+        }
+        return _specialize_calls.isEmpty() || _specialize_calls.contains(functionName);
+    }
+
+    /**
      * Get the output stream for this environment
      * @return output print writer
      */
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
index 9351720..61cce7b 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
@@ -104,34 +104,31 @@
     /** Per ScriptObject flag - is this an arguments object? */
     public static final int IS_ARGUMENTS   = 0b0000_0100;
 
+    /** Is this a prototype PropertyMap? */
+    public static final int IS_PROTOTYPE   = 0b0000_1000;
+
     /** Spill growth rate - by how many elements does {@link ScriptObject#spill} when full */
     public static final int SPILL_RATE = 8;
 
     /** Map to property information and accessor functions. Ordered by insertion. */
     private PropertyMap map;
 
+    /** objects proto. */
+    private ScriptObject proto;
+
+    /** Context of the object, lazily cached. */
+    private Context context;
+
     /** Object flags. */
     private int flags;
 
-    /** Area for properties added to object after instantiation, see {@link SpillProperty} */
+    /** Area for properties added to object after instantiation, see {@link AccessorProperty} */
     public Object[] spill;
 
-    /** Local embed area position 0 - used for {@link SpillProperty} before {@link ScriptObject#spill} */
-    public Object embed0;
-
-    /** Local embed area position 1 - used for {@link SpillProperty} before {@link ScriptObject#spill} */
-    public Object embed1;
-
-    /** Local embed area position 2 - used for {@link SpillProperty} before {@link ScriptObject#spill} */
-    public Object embed2;
-
-    /** Local embed area position 3 - used for {@link SpillProperty} before {@link ScriptObject#spill} */
-    public Object embed3;
-
     /** Indexed array data. */
     private ArrayData arrayData;
 
-    static final MethodHandle SETEMBED           = findOwnMH("setEmbed",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, int.class, Object.class, Object.class);
+    static final MethodHandle SETFIELD           = findOwnMH("setField",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class);
     static final MethodHandle SETSPILL           = findOwnMH("setSpill",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
     static final MethodHandle SETSPILLWITHNEW    = findOwnMH("setSpillWithNew",  void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
     static final MethodHandle SETSPILLWITHGROW   = findOwnMH("setSpillWithGrow", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, int.class, Object.class, Object.class);
@@ -665,9 +662,9 @@
         }
 
         if (deep) {
-            final ScriptObject proto = getProto();
-            if(proto != null) {
-                return proto.findProperty(key, deep, stopOnNonScope, start);
+            final ScriptObject myProto = getProto();
+            if (myProto != null) {
+                return myProto.findProperty(key, deep, stopOnNonScope, start);
             }
         }
 
@@ -783,8 +780,8 @@
                 // delete getter and setter function references so that we don't leak
                 if (property instanceof UserAccessorProperty) {
                     final UserAccessorProperty uc = (UserAccessorProperty) property;
-                    setEmbedOrSpill(uc.getGetterSlot(), null);
-                    setEmbedOrSpill(uc.getSetterSlot(), null);
+                    setSpill(uc.getGetterSlot(), null);
+                    setSpill(uc.getSetterSlot(), null);
                 }
                 return true;
             }
@@ -809,7 +806,7 @@
 
             int getterSlot = uc.getGetterSlot();
             // clear the old getter and set the new getter
-            setEmbedOrSpill(getterSlot, getter);
+            setSpill(getterSlot, getter);
             // if getter function is null, flag the slot to be negative (less by 1)
             if (getter == null) {
                 getterSlot = -getterSlot - 1;
@@ -817,7 +814,7 @@
 
             int setterSlot = uc.getSetterSlot();
             // clear the old setter and set the new setter
-            setEmbedOrSpill(setterSlot, setter);
+            setSpill(setterSlot, setter);
             // if setter function is null, flag the slot to be negative (less by 1)
             if (setter == null) {
                 setterSlot = -setterSlot - 1;
@@ -973,9 +970,7 @@
      * @param bindName  null or name to bind to second argument (property not found method.)
      *
      * @return value of property as a MethodHandle or null.
-     *
      */
-    @SuppressWarnings("static-method")
     protected MethodHandle getCallMethodHandle(final FindProperty find, final MethodType type, final String bindName) {
         return getCallMethodHandle(getObjectValue(find), type, bindName);
     }
@@ -1056,8 +1051,11 @@
      * Return the current context from the object's map.
      * @return Current context.
      */
-    final Context getContext() {
-        return getMap().getContext();
+    protected final Context getContext() {
+        if (context == null) {
+            context = Context.fromClass(getClass());
+        }
+        return context;
     }
 
     /**
@@ -1097,44 +1095,30 @@
      * @return __proto__ object.
      */
     public final ScriptObject getProto() {
-        return getMap().getProto();
-    }
-
-    /**
-     * Check if this is a prototype
-     * @return true if {@link PropertyMap#isPrototype()} is true for this ScriptObject
-     */
-    public final boolean isPrototype() {
-        return getMap().isPrototype();
+        return proto;
     }
 
     /**
      * Set the __proto__ of an object.
      * @param newProto new __proto__ to set.
      */
-    public final void setProto(final ScriptObject newProto) {
-        PropertyMap  oldMap   = getMap();
-        ScriptObject oldProto = getProto();
+    public synchronized final void setProto(final ScriptObject newProto) {
+        final ScriptObject oldProto = proto;
+        map = map.changeProto(oldProto, newProto);
 
-        while (oldProto != newProto) {
-            final PropertyMap newMap = oldMap.setProto(newProto);
+        if (newProto != null) {
+            newProto.setIsPrototype();
+        }
 
-            if (!compareAndSetMap(oldMap, newMap)) {
-                oldMap = getMap();
-                oldProto = getProto();
-            } else {
-                if (isPrototype()) {
+        proto = newProto;
 
-                    if (oldProto != null) {
-                        oldProto.removePropertyListener(this);
-                    }
+        if (isPrototype()) {
+            if (oldProto != null) {
+                oldProto.removePropertyListener(this);
+            }
 
-                    if (newProto != null) {
-                        newProto.addPropertyListener(this);
-                    }
-                }
-
-                return;
+            if (newProto != null) {
+                newProto.addPropertyListener(this);
             }
         }
     }
@@ -1327,6 +1311,25 @@
     }
 
     /**
+     * Check if this object is a prototype
+     *
+     * @return {@code true} if is prototype
+     */
+    public boolean isPrototype() {
+        return (flags & IS_PROTOTYPE) != 0;
+    }
+
+    /**
+     * Flag this object as having a prototype.
+     */
+    public void setIsPrototype() {
+        if (proto != null && !isPrototype()) {
+            proto.addPropertyListener(this);
+        }
+        flags |= IS_PROTOTYPE;
+    }
+
+    /**
      * Get the {@link ArrayData} for this ScriptObject if it is an array
      * @return array data
      */
@@ -1719,11 +1722,11 @@
             if (!property.hasGetterFunction()) {
                 methodHandle = bindTo(methodHandle, prototype);
             }
-            return new GuardedInvocation(methodHandle, getMap().getProtoGetSwitchPoint(name), guard);
+            return new GuardedInvocation(methodHandle, getMap().getProtoGetSwitchPoint(proto, name), guard);
         }
 
         assert !NashornCallSiteDescriptor.isFastScope(desc);
-        return new GuardedInvocation(Lookup.emptyGetter(returnType), getMap().getProtoGetSwitchPoint(name), guard);
+        return new GuardedInvocation(Lookup.emptyGetter(returnType), getMap().getProtoGetSwitchPoint(proto, name), guard);
     }
 
     private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name) {
@@ -1822,27 +1825,31 @@
            }
            assert canBeFastScope || !NashornCallSiteDescriptor.isFastScope(desc);
            final PropertyMap myMap = getMap();
-           return new GuardedInvocation(Lookup.EMPTY_SETTER, myMap.getProtoGetSwitchPoint(name), NashornGuards.getMapGuard(myMap));
+           return new GuardedInvocation(Lookup.EMPTY_SETTER, myMap.getProtoGetSwitchPoint(proto, name), NashornGuards.getMapGuard(myMap));
     }
 
     @SuppressWarnings("unused")
-    private static void setEmbed(final CallSiteDescriptor desc, final PropertyMap oldMap, final PropertyMap newMap, final MethodHandle setter, final int i, final Object self, final Object value) throws Throwable {
+    private static void setField(final CallSiteDescriptor desc, final PropertyMap oldMap, final PropertyMap newMap, final MethodHandle setter, final Object self, final Object value) throws Throwable {
         final ScriptObject obj = (ScriptObject)self;
-        if (obj.trySetEmbedOrSpill(desc, oldMap, newMap, value)) {
-            obj.useEmbed(i);
+        final boolean isStrict = NashornCallSiteDescriptor.isStrict(desc);
+        if (!obj.isExtensible()) {
+            throw typeError("object.non.extensible", desc.getNameToken(2), ScriptRuntime.safeToString(obj));
+        } else if (obj.compareAndSetMap(oldMap, newMap)) {
             setter.invokeExact(self, value);
+        } else {
+            obj.set(desc.getNameToken(CallSiteDescriptor.NAME_OPERAND), value, isStrict);
         }
     }
 
     @SuppressWarnings("unused")
     private static void setSpill(final CallSiteDescriptor desc, final PropertyMap oldMap, final PropertyMap newMap, final int index, final Object self, final Object value) {
         final ScriptObject obj = (ScriptObject)self;
-        if (obj.trySetEmbedOrSpill(desc, oldMap, newMap, value)) {
+        if (obj.trySetSpill(desc, oldMap, newMap, value)) {
             obj.spill[index] = value;
         }
     }
 
-    private boolean trySetEmbedOrSpill(final CallSiteDescriptor desc, final PropertyMap oldMap, final PropertyMap newMap, final Object value) {
+    private boolean trySetSpill(final CallSiteDescriptor desc, final PropertyMap oldMap, final PropertyMap newMap, final Object value) {
         final boolean isStrict = NashornCallSiteDescriptor.isStrict(desc);
         if (!isExtensible() && isStrict) {
             throw typeError("object.non.extensible", desc.getNameToken(2), ScriptRuntime.safeToString(this));
@@ -1964,7 +1971,7 @@
                     methodHandle = bindTo(methodHandle, UNDEFINED);
                 }
                 return new GuardedInvocation(methodHandle,
-                        find.isInherited()? getMap().getProtoGetSwitchPoint(NO_SUCH_PROPERTY_NAME) : null,
+                        find.isInherited()? getMap().getProtoGetSwitchPoint(proto, NO_SUCH_PROPERTY_NAME) : null,
                         getKnownFunctionPropertyGuard(getMap(), find.getGetter(Object.class), find.getOwner(), func));
             }
         }
@@ -1995,7 +2002,7 @@
     }
 
     private GuardedInvocation createEmptyGetter(final CallSiteDescriptor desc, final String name) {
-        return new GuardedInvocation(Lookup.emptyGetter(desc.getMethodType().returnType()), getMap().getProtoGetSwitchPoint(name), NashornGuards.getMapGuard(getMap()));
+        return new GuardedInvocation(Lookup.emptyGetter(desc.getMethodType().returnType()), getMap().getProtoGetSwitchPoint(proto, name), NashornGuards.getMapGuard(getMap()));
     }
 
     private abstract static class ScriptObjectIterator <T extends Object> implements Iterator<T> {
@@ -2070,36 +2077,39 @@
      * @return Added property.
      */
     private Property addSpillProperty(final String key, final int propertyFlags) {
-        int i = findEmbed();
-        Property spillProperty;
+        int fieldCount   = getMap().getFieldCount();
+        int fieldMaximum = getMap().getFieldMaximum();
+        Property property;
 
-        if (i >= EMBED_SIZE) {
-            i = getMap().getSpillLength();
+        if (fieldCount < fieldMaximum) {
+            property = new AccessorProperty(key, propertyFlags & ~Property.IS_SPILL, getClass(), fieldCount);
+            notifyPropertyAdded(this, property);
+            property = addOwnProperty(property);
+        } else {
+            int i = getMap().getSpillLength();
             MethodHandle getter = MH.arrayElementGetter(Object[].class);
             MethodHandle setter = MH.arrayElementSetter(Object[].class);
             getter = MH.asType(MH.insertArguments(getter, 1, i), Lookup.GET_OBJECT_TYPE);
             setter = MH.asType(MH.insertArguments(setter, 1, i), Lookup.SET_OBJECT_TYPE);
-            spillProperty = new SpillProperty(key, propertyFlags | Property.IS_SPILL, i, getter, setter);
-            notifyPropertyAdded(this, spillProperty);
-            spillProperty = addOwnProperty(spillProperty);
-            i = spillProperty.getSlot();
+            property = new AccessorProperty(key, propertyFlags | Property.IS_SPILL, i, getter, setter);
+            notifyPropertyAdded(this, property);
+            property = addOwnProperty(property);
+            i = property.getSlot();
 
             final int newLength = (i + SPILL_RATE) / SPILL_RATE * SPILL_RATE;
-            final Object[] newSpill = new Object[newLength];
 
-            if (spill != null) {
-                System.arraycopy(spill, 0, newSpill, 0, spill.length);
+            if (spill == null || newLength > spill.length) {
+                final Object[] newSpill = new Object[newLength];
+
+                if (spill != null) {
+                    System.arraycopy(spill, 0, newSpill, 0, spill.length);
+                }
+
+                spill = newSpill;
             }
-
-            spill = newSpill;
-         } else {
-            useEmbed(i);
-            spillProperty = new SpillProperty(key, propertyFlags, i, GET_EMBED[i], SET_EMBED[i]);
-            notifyPropertyAdded(this, spillProperty);
-            spillProperty = addOwnProperty(spillProperty);
         }
 
-        return spillProperty;
+        return property;
     }
 
 
@@ -3159,67 +3169,22 @@
     }
 
     /*
-     * Embed management
-     */
-
-    /** Number of embed slots */
-    public static final int EMBED_SIZE   = 4;
-    /** Embed offset */
-    public static final int EMBED_OFFSET = 32 - EMBED_SIZE;
-
-    static final MethodHandle[] GET_EMBED;
-    static final MethodHandle[] SET_EMBED;
-
-    static {
-        GET_EMBED = new MethodHandle[EMBED_SIZE];
-        SET_EMBED = new MethodHandle[EMBED_SIZE];
-
-        for (int i = 0; i < EMBED_SIZE; i++) {
-            final String name = "embed" + i;
-            GET_EMBED[i] = MH.asType(MH.getter(MethodHandles.lookup(), ScriptObject.class, name, Object.class), Lookup.GET_OBJECT_TYPE);
-            SET_EMBED[i] = MH.asType(MH.setter(MethodHandles.lookup(), ScriptObject.class, name, Object.class), Lookup.SET_OBJECT_TYPE);
-        }
-    }
-
-    void useEmbed(final int i) {
-        flags |= 1 << (EMBED_OFFSET + i);
-    }
-
-    int findEmbed() {
-        final int bits  = ~(flags >>> EMBED_OFFSET);
-        final int least = bits ^ -bits;
-        final int index = Integer.numberOfTrailingZeros(least) - 1;
-
-        return index;
-    }
-
-    /*
      * Make a new UserAccessorProperty property. getter and setter functions are stored in
      * this ScriptObject and slot values are used in property object.
      */
     private UserAccessorProperty newUserAccessors(final String key, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) {
         int oldSpillLength = getMap().getSpillLength();
 
-        int getterSlot = findEmbed();
-        if (getterSlot >= EMBED_SIZE) {
-            getterSlot = oldSpillLength + EMBED_SIZE;
-            ++oldSpillLength;
-        } else {
-            useEmbed(getterSlot);
-        }
-        setEmbedOrSpill(getterSlot, getter);
+        int getterSlot = oldSpillLength++;
+        setSpill(getterSlot, getter);
         // if getter function is null, flag the slot to be negative (less by 1)
         if (getter == null) {
             getterSlot = -getterSlot - 1;
         }
 
-        int setterSlot = findEmbed();
-        if (setterSlot >= EMBED_SIZE) {
-            setterSlot = oldSpillLength + EMBED_SIZE;
-        } else {
-            useEmbed(setterSlot);
-        }
-        setEmbedOrSpill(setterSlot, setter);
+        int setterSlot = oldSpillLength++;
+
+        setSpill(setterSlot, setter);
         // if setter function is null, flag the slot to be negative (less by 1)
         if (setter == null) {
             setterSlot = -setterSlot - 1;
@@ -3228,56 +3193,28 @@
         return new UserAccessorProperty(key, propertyFlags, getterSlot, setterSlot);
     }
 
-    private void setEmbedOrSpill(final int slot, final Object value) {
-        switch (slot) {
-        case 0:
-            embed0 = value;
-            break;
-        case 1:
-            embed1 = value;
-            break;
-        case 2:
-            embed2 = value;
-            break;
-        case 3:
-            embed3 = value;
-            break;
-        default:
-            if (slot >= 0) {
-                final int index = (slot - EMBED_SIZE);
-                if (spill == null) {
-                    // create new spill.
-                    spill = new Object[Math.max(index + 1, SPILL_RATE)];
-                } else if (index >= spill.length) {
-                    // grow spill as needed
-                    final Object[] newSpill = new Object[index + 1];
-                    System.arraycopy(spill, 0, newSpill, 0, spill.length);
-                    spill = newSpill;
-                }
-
-                spill[index] = value;
+    private void setSpill(final int slot, final Object value) {
+        if (slot >= 0) {
+            final int index = slot;
+            if (spill == null) {
+                // create new spill.
+                spill = new Object[Math.max(index + 1, SPILL_RATE)];
+            } else if (index >= spill.length) {
+                // grow spill as needed
+                final Object[] newSpill = new Object[index + 1];
+                System.arraycopy(spill, 0, newSpill, 0, spill.length);
+                spill = newSpill;
             }
-            break;
+
+            spill[index] = value;
         }
     }
 
-    // user accessors are either stored in embed fields or spill array slots
-    // get the accessor value using slot number. Note that slot is either embed
-    // field number or (spill array index + embedSize).
-    Object getEmbedOrSpill(final int slot) {
-        switch (slot) {
-        case 0:
-            return embed0;
-        case 1:
-            return embed1;
-        case 2:
-            return embed2;
-        case 3:
-            return embed3;
-        default:
-            final int index = (slot - EMBED_SIZE);
-            return (index < 0 || (index >= spill.length)) ? null : spill[index];
-        }
+    // user accessors are either stored in spill array slots
+    // get the accessor value using slot number. Note that slot is spill array index.
+    Object getSpill(final int slot) {
+        final int index = slot;
+        return (index < 0 || (index >= spill.length)) ? null : spill[index];
     }
 
     // User defined getter and setter are always called by "dyn:call". Note that the user
@@ -3287,7 +3224,7 @@
     @SuppressWarnings("unused")
     private static Object userAccessorGetter(final ScriptObject proto, final int slot, final Object self) {
         final ScriptObject container = (proto != null) ? proto : (ScriptObject)self;
-        final Object       func      = container.getEmbedOrSpill(slot);
+        final Object       func      = container.getSpill(slot);
 
         if (func instanceof ScriptFunction) {
             try {
@@ -3305,7 +3242,7 @@
     @SuppressWarnings("unused")
     private static void userAccessorSetter(final ScriptObject proto, final int slot, final String name, final Object self, final Object value) {
         final ScriptObject container = (proto != null) ? proto : (ScriptObject)self;
-        final Object       func      = container.getEmbedOrSpill(slot);
+        final Object       func      = container.getSpill(slot);
 
         if (func instanceof ScriptFunction) {
             try {
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java b/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java
index 8012ce0..5ff321f 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java
@@ -166,18 +166,20 @@
     }
 
     private SetMethod createNewPropertySetter() {
-        final int nextEmbed = sobj.findEmbed();
-        final SetMethod sm;
-        if (nextEmbed >= ScriptObject.EMBED_SIZE) {
-            sm = createNewSpillPropertySetter();
-        } else {
-            sm = createNewEmbedPropertySetter(nextEmbed);
-        }
-
+        final SetMethod sm = map.getFieldCount() < map.getFieldMaximum() ? createNewFieldSetter() : createNewSpillPropertySetter();
         sobj.notifyPropertyAdded(sobj, sm.property);
         return sm;
     }
 
+    private SetMethod createNewFieldSetter() {
+        final PropertyMap oldMap = getMap();
+        final Property property = new AccessorProperty(getName(), 0, sobj.getClass(), oldMap.getFieldCount());
+        final PropertyMap newMap = oldMap.addProperty(property);
+        MethodHandle setter = MH.insertArguments(ScriptObject.SETFIELD, 0, desc, oldMap, newMap, property.getSetter(Object.class, newMap));
+
+        return new SetMethod(MH.asType(setter, Lookup.SET_OBJECT_TYPE), property);
+    }
+
     private SetMethod createNewSpillPropertySetter() {
         final int nextSpill = getMap().getSpillLength();
 
@@ -189,7 +191,7 @@
         final MethodHandle getter = MH.asType(MH.insertArguments(MH.arrayElementGetter(Object[].class), 1, nextSpill), Lookup.GET_OBJECT_TYPE);
         final MethodHandle setter = MH.asType(MH.insertArguments(MH.arrayElementSetter(Object[].class), 1, nextSpill), Lookup.SET_OBJECT_TYPE);
 
-        return new SpillProperty(getName(), Property.IS_SPILL, nextSpill, getter, setter);
+        return new AccessorProperty(getName(), Property.IS_SPILL, nextSpill, getter, setter);
     }
 
     private MethodHandle createSpillMethodHandle(final int nextSpill, Property property) {
@@ -207,14 +209,6 @@
         }
     }
 
-    private SetMethod createNewEmbedPropertySetter(final int nextEmbed) {
-        sobj.useEmbed(nextEmbed);
-        final Property property = new SpillProperty(getName(), 0, nextEmbed, ScriptObject.GET_EMBED[nextEmbed], ScriptObject.SET_EMBED[nextEmbed]);
-        //TODO specfields
-        final MethodHandle methodHandle = MH.insertArguments(ScriptObject.SETEMBED, 0, desc, getMap(), getNewMap(property), property.getSetter(Object.class, getMap()), nextEmbed);
-        return new SetMethod(methodHandle, property);
-    }
-
     private PropertyMap getNewMap(Property property) {
         return getMap().addProperty(property);
     }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/SpillProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/SpillProperty.java
deleted file mode 100644
index 716097d..0000000
--- a/nashorn/src/jdk/nashorn/internal/runtime/SpillProperty.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.nashorn.internal.runtime;
-
-import static jdk.nashorn.internal.lookup.Lookup.MH;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import jdk.nashorn.internal.lookup.Lookup;
-
-/**
- * The SpillProperty is a subclass of AccessorProperties. Anything not in the initial property map
- * will end up in the embed fields of the ScriptObject or in the Spill, which currently is a growing
- * Object only array in ScriptObject
- *
- * @see AccessorProperty
- * @see ScriptObject
- */
-public final class SpillProperty extends AccessorProperty {
-    private static final MethodHandle SPILLGETTER = MH.asType(MH.getter(MethodHandles.lookup(), ScriptObject.class, "spill", Object[].class), Lookup.GET_OBJECT_TYPE);
-
-    /**
-     * Constructor
-     *
-     * @param key    property key
-     * @param flags  property flags
-     * @param slot   property slot/index
-     * @param getter getter for property
-     * @param setter setter for property, or null if not configurable and writable
-     */
-    public SpillProperty(final String key, final int flags, final int slot, final MethodHandle getter, final MethodHandle setter) {
-        super(key, flags, slot, getter, setter);
-    }
-
-    private SpillProperty(final SpillProperty property) {
-        super(property);
-    }
-
-    @Override
-    protected Property copy() {
-        return new SpillProperty(this);
-    }
-
-    @Override
-    public MethodHandle getGetter(final Class<?> type) {
-        if (isSpill()) {
-            return MH.filterArguments(super.getGetter(type), 0, SPILLGETTER);
-        }
-
-        return super.getGetter(type);
-    }
-
-    @Override
-    public MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap) {
-        if (isSpill()) {
-            return MH.filterArguments(super.getSetter(type, currentMap), 0, SPILLGETTER);
-        }
-
-        return super.getSetter(type, currentMap);
-    }
-
-}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java b/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java
index db55fff..ff6973a 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java
@@ -110,8 +110,7 @@
     @Override
     protected Class<?> findClass(final String name) throws ClassNotFoundException {
         if (name.startsWith(JS_OBJECT_PREFIX_EXTERNAL)) {
-            final int start = name.indexOf(JS_OBJECT_PREFIX.symbolName()) + JS_OBJECT_PREFIX.symbolName().length();
-            return generateClass(name, name.substring(start, name.length()));
+            return generateClass(name, name.substring(JS_OBJECT_PREFIX_EXTERNAL.length()));
         }
         return super.findClass(name);
     }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java
index 83d3c8d..75c285a 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java
@@ -67,7 +67,6 @@
 
     private UserAccessorProperty(final UserAccessorProperty property) {
         super(property);
-
         this.getterSlot = property.getterSlot;
         this.setterSlot = property.setterSlot;
     }
@@ -115,10 +114,10 @@
     public int getSpillCount() {
         // calculate how many spill array slots used by this propery.
         int count = 0;
-        if (getGetterSlot() >= ScriptObject.EMBED_SIZE) {
+        if (getGetterSlot() >= 0) {
             count++;
         }
-        if (getSetterSlot() >= ScriptObject.EMBED_SIZE) {
+        if (getSetterSlot() >= 0) {
             count++;
         }
         return count;
@@ -141,7 +140,7 @@
 
     @Override
     public ScriptFunction getGetterFunction(final ScriptObject obj) {
-        final Object value = obj.getEmbedOrSpill(getterSlot);
+        final Object value = obj.getSpill(getterSlot);
         return (value instanceof ScriptFunction) ? (ScriptFunction) value : null;
     }
 
@@ -152,7 +151,7 @@
 
     @Override
     public ScriptFunction getSetterFunction(final ScriptObject obj) {
-        final Object value = obj.getEmbedOrSpill(setterSlot);
+        final Object value = obj.getSpill(setterSlot);
         return (value instanceof ScriptFunction) ? (ScriptFunction) value : null;
     }
 
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java
index 1703b7e..5061683 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java
@@ -57,7 +57,6 @@
      * Is this a reverse order iteration?
      * @return true if reverse
      */
-    @SuppressWarnings("static-method")
     public boolean isReverse() {
         return false;
     }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java
index 05b1a93..7457641 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java
@@ -278,7 +278,7 @@
             @SuppressWarnings("resource")
             @Override
             public void run() {
-                PrintWriter out = null;
+                PrintWriter out    = null;
                 boolean fileOutput = false;
 
                 try {
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java
index e7cc78b..083dfef 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java
@@ -44,11 +44,9 @@
 
 /**
  * This is the main dynamic linker for Nashorn. It is used for linking all {@link ScriptObject} and its subclasses (this
- * includes {@link ScriptFunction} and its subclasses) as well as {@link Undefined}. This linker is exported to other
- * language runtimes by being declared in {@code META-INF/services/jdk.internal.dynalink.linker.GuardingDynamicLinker}
- * file of Nashorn's distribution.
+ * includes {@link ScriptFunction} and its subclasses) as well as {@link Undefined}.
  */
-final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory, ConversionComparator {
+public final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory, ConversionComparator {
     /**
      * Returns true if {@code ScriptObject} is assignable from {@code type}, or it is {@code Undefined}.
      */
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java b/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java
index 16f3bc0..286feec 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java
@@ -243,7 +243,7 @@
      */
     public String getString(final String key) {
         final Option<?> option = get(key);
-        if(option != null) {
+        if (option != null) {
             final String value = (String)option.getValue();
             if(value != null) {
                 return value.intern();
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/DefaultRegExp.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/DefaultRegExp.java
index ecbc8bc..e3157ba 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/DefaultRegExp.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/DefaultRegExp.java
@@ -107,16 +107,16 @@
 
     class DefaultMatcher implements RegExpMatcher {
         final String input;
-        final Matcher matcher;
+        final Matcher defaultMatcher;
 
         DefaultMatcher(final String input) {
             this.input = input;
-            this.matcher = pattern.matcher(input);
+            this.defaultMatcher = pattern.matcher(input);
         }
 
         @Override
         public boolean search(final int start) {
-            return matcher.find(start);
+            return defaultMatcher.find(start);
         }
 
         @Override
@@ -126,37 +126,37 @@
 
         @Override
         public int start() {
-            return matcher.start();
+            return defaultMatcher.start();
         }
 
         @Override
         public int start(final int group) {
-            return matcher.start(group);
+            return defaultMatcher.start(group);
         }
 
         @Override
         public int end() {
-            return matcher.end();
+            return defaultMatcher.end();
         }
 
         @Override
         public int end(final int group) {
-            return matcher.end(group);
+            return defaultMatcher.end(group);
         }
 
         @Override
         public String group() {
-            return matcher.group();
+            return defaultMatcher.group();
         }
 
         @Override
         public String group(final int group) {
-            return matcher.group(group);
+            return defaultMatcher.group(group);
         }
 
         @Override
         public int groupCount() {
-            return matcher.groupCount();
+            return defaultMatcher.groupCount();
         }
     }
 
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java
index 719f6c3..1047221 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java
@@ -121,16 +121,16 @@
 
     class JoniMatcher implements RegExpMatcher {
         final String input;
-        final Matcher matcher;
+        final Matcher joniMatcher;
 
         JoniMatcher(final String input) {
             this.input = input;
-            this.matcher = regex.matcher(input.toCharArray());
+            this.joniMatcher = regex.matcher(input.toCharArray());
         }
 
         @Override
         public boolean search(final int start) {
-            return matcher.search(start, input.length(), Option.NONE) > -1;
+            return joniMatcher.search(start, input.length(), Option.NONE) > -1;
         }
 
         @Override
@@ -140,27 +140,27 @@
 
         @Override
         public int start() {
-            return matcher.getBegin();
+            return joniMatcher.getBegin();
         }
 
         @Override
         public int start(final int group) {
-            return group == 0 ? start() : matcher.getRegion().beg[group];
+            return group == 0 ? start() : joniMatcher.getRegion().beg[group];
         }
 
         @Override
         public int end() {
-            return matcher.getEnd();
+            return joniMatcher.getEnd();
         }
 
         @Override
         public int end(final int group) {
-            return group == 0 ? end() : matcher.getRegion().end[group];
+            return group == 0 ? end() : joniMatcher.getRegion().end[group];
         }
 
         @Override
         public String group() {
-            return input.substring(matcher.getBegin(), matcher.getEnd());
+            return input.substring(joniMatcher.getBegin(), joniMatcher.getEnd());
         }
 
         @Override
@@ -168,13 +168,13 @@
             if (group == 0) {
                 return group();
             }
-            final Region region = matcher.getRegion();
+            final Region region = joniMatcher.getRegion();
             return input.substring(region.beg[group], region.end[group]);
         }
 
         @Override
         public int groupCount() {
-            final Region region = matcher.getRegion();
+            final Region region = joniMatcher.getRegion();
             return region == null ? 0 : region.numRegs - 1;
         }
     }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java
index e651c44..956a99d 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java
@@ -65,7 +65,7 @@
     /** Are we currently inside a negated character class? */
     private boolean inNegativeClass = false;
 
-    private static final String NON_IDENT_ESCAPES = "$^*+(){}[]|\\.?";
+    private static final String NON_IDENT_ESCAPES = "$^*+(){}[]|\\.?-";
 
     private static class Capture {
         /**
@@ -934,7 +934,7 @@
         return true;
     }
 
-    private void unicode(final int value, final StringBuilder buffer) {
+    private static void unicode(final int value, final StringBuilder buffer) {
         final String hex = Integer.toHexString(value);
         buffer.append('u');
         for (int i = 0; i < 4 - hex.length(); i++) {
@@ -944,7 +944,7 @@
     }
 
     // Convert what would have been a backreference into a unicode escape, or a number literal, or both.
-    private void octalOrLiteral(final String numberLiteral, final StringBuilder buffer) {
+    private static void octalOrLiteral(final String numberLiteral, final StringBuilder buffer) {
         final int length = numberLiteral.length();
         int octalValue = 0;
         int pos = 0;
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties
index 2b52e8b..4717319 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties
@@ -247,6 +247,12 @@
     desc="Print bytecode."    \
 }
 
+nashorn.option.print.mem.usage = {                            \
+    name="--print-mem-usage",                                 \
+    is_undocumented=true,                                     \
+    desc="Print memory usage of IR after each compile stage." \
+}
+
 nashorn.option.print.no.newline = {                     \
     name="--print-no-newline",                          \
     is_undocumented=true,                               \
@@ -288,12 +294,12 @@
     dependency="--anon-functions=true"  \
 }
 
-nashorn.option.timezone = {                    \
-    name="-timezone",                          \
-    short_name="-t",                           \
-    params="<timezone>",                       \
-    desc="Set timezone for script execution.", \
-    type=TimeZone                              \
+nashorn.option.specialize.calls = {                                                \
+    name="--specialize-calls",                                                     \
+    is_undocumented=true,                                                          \
+    type=String,                                                                   \
+    params="[=function_1,...,function_n]",                                         \
+    desc="Specialize all or a set of method according to callsite parameter types" \
 }
 
 nashorn.option.stdout = {                                               \
@@ -312,6 +318,14 @@
     desc="Redirect stderr to a filename or to another tty, e.g. stdout" \
 }
 
+nashorn.option.timezone = {                    \
+    name="-timezone",                          \
+    short_name="-t",                           \
+    params="<timezone>",                       \
+    desc="Set timezone for script execution.", \
+    type=TimeZone                              \
+}
+
 nashorn.option.trace.callsites = {                                              \
     name="--trace-callsites",                                                   \
     short_name="-tcs",                                                          \
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/bootstrap.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/bootstrap.js
index 97b01a08..b78ebbc 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/bootstrap.js
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/bootstrap.js
@@ -35,8 +35,6 @@
     init: function() {
         // Java FX packages and classes must be defined here because
         // they may not be viable until launch time due to clinit ordering.
-
-        load("fx:base.js");
     },
 
     // Overridden javafx.application.Application.start(Stage stage);
diff --git a/nashorn/src/jdk/nashorn/internal/scripts/JO.java b/nashorn/src/jdk/nashorn/internal/scripts/JO.java
index 4441236..d698a26 100644
--- a/nashorn/src/jdk/nashorn/internal/scripts/JO.java
+++ b/nashorn/src/jdk/nashorn/internal/scripts/JO.java
@@ -32,12 +32,11 @@
  * Empty object class.
  */
 public class JO extends ScriptObject {
-
     /**
      * Constructor
      */
     public JO() {
-        super();
+        super(PropertyMap.newMap(JO.class));
     }
 
     /**
diff --git a/nashorn/src/jdk/nashorn/tools/Shell.java b/nashorn/src/jdk/nashorn/tools/Shell.java
index 22d879f..708fecc 100644
--- a/nashorn/src/jdk/nashorn/tools/Shell.java
+++ b/nashorn/src/jdk/nashorn/tools/Shell.java
@@ -173,9 +173,9 @@
 
         if (env._fx) {
             return runFXScripts(context, global, files);
-        } else {
-            return runScripts(context, global, files);
         }
+
+        return runScripts(context, global, files);
     }
 
     /**
@@ -270,7 +270,7 @@
                 }
 
                 //null - pass no code installer - this is compile only
-                new Compiler(env, functionNode).compile();
+                new Compiler(env).compile(functionNode);
             }
         } finally {
             env.getOut().flush();
@@ -343,7 +343,7 @@
      * @return error code
      * @throws IOException when any script file read results in I/O error
      */
-    private int runFXScripts(final Context context, final ScriptObject global, final List<String> files) throws IOException {
+    private static int runFXScripts(final Context context, final ScriptObject global, final List<String> files) throws IOException {
         final ScriptObject oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
         try {
diff --git a/hotspot/src/share/tools/launcher/jli_util.h b/nashorn/test/script/basic/JDK-8013729.js
similarity index 67%
copy from hotspot/src/share/tools/launcher/jli_util.h
copy to nashorn/test/script/basic/JDK-8013729.js
index 535f7c4..a500602 100644
--- a/hotspot/src/share/tools/launcher/jli_util.h
+++ b/nashorn/test/script/basic/JDK-8013729.js
@@ -1,35 +1,49 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
+ * 
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.
- *
+ * 
  * This code is distributed in the hope that it will be useful, but WITHOUT
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * version 2 for more details (a copy is included in the LICENSE file that
  * accompanied this code).
- *
+ * 
  * You should have received a copy of the GNU General Public License version
  * 2 along with this work; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+ * 
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
-#ifndef _JLI_UTIL_H
-#define _JLI_UTIL_H
+/**
+ * JDK-8013729: SwitchPoint invalidation not working over prototype chain
+ *
+ * @test
+ * @run
+ */
 
-#include <stdlib.h>
+var a = {x: 1};
+var b = Object.create(a, {y: {value: 2, configurable: true, writable: true}});
+var c = Object.create(b);
+var d = Object.create(c);
 
-void *JLI_MemAlloc(size_t size);
-void *JLI_MemRealloc(void *ptr, size_t size);
-char *JLI_StringDup(const char *s1);
-void  JLI_MemFree(void *ptr);
+function p() {
+    print(d.x);
+    print(d.y);
+}
 
-#endif  /* _JLI_UTIL_H */
+p();
+
+// Delete, then redefine properties
+delete a.x;
+delete b.y;
+a.x = 10;
+b.y = 20;
+
+p();
diff --git a/nashorn/test/script/basic/JDK-8013729.js.EXPECTED b/nashorn/test/script/basic/JDK-8013729.js.EXPECTED
new file mode 100644
index 0000000..c9fc4c6
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8013729.js.EXPECTED
@@ -0,0 +1,4 @@
+1
+2
+10
+20
diff --git a/hotspot/src/share/tools/launcher/jli_util.h b/nashorn/test/script/basic/JDK-8013873.js
similarity index 72%
rename from hotspot/src/share/tools/launcher/jli_util.h
rename to nashorn/test/script/basic/JDK-8013873.js
index 535f7c4..dcae75c 100644
--- a/hotspot/src/share/tools/launcher/jli_util.h
+++ b/nashorn/test/script/basic/JDK-8013873.js
@@ -1,35 +1,40 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
+ * 
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.
- *
+ * 
  * This code is distributed in the hope that it will be useful, but WITHOUT
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * version 2 for more details (a copy is included in the LICENSE file that
  * accompanied this code).
- *
+ * 
  * You should have received a copy of the GNU General Public License version
  * 2 along with this work; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+ * 
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
-#ifndef _JLI_UTIL_H
-#define _JLI_UTIL_H
+/**
+ * JDK-8013873: Regexp regression for escaped dash in character class
+ *
+ * @test
+ * @run
+ */
 
-#include <stdlib.h>
+var re = /[a\-c]/;
+print(re.exec("a"));
+print(re.exec("-"));
+print(re.exec("c"));
+print(re.exec("b"));
+print(re.exec("\\"));
 
-void *JLI_MemAlloc(size_t size);
-void *JLI_MemRealloc(void *ptr, size_t size);
-char *JLI_StringDup(const char *s1);
-void  JLI_MemFree(void *ptr);
-
-#endif  /* _JLI_UTIL_H */
+re = /^\-$/;
+print(re.exec("-"));
+print(re.exec("\\-"));
diff --git a/nashorn/test/script/basic/JDK-8013873.js.EXPECTED b/nashorn/test/script/basic/JDK-8013873.js.EXPECTED
new file mode 100644
index 0000000..7131993
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8013873.js.EXPECTED
@@ -0,0 +1,7 @@
+a
+-
+c
+null
+null
+-
+null
diff --git a/nashorn/test/script/basic/JDK-8013874.js b/nashorn/test/script/basic/JDK-8013874.js
new file mode 100644
index 0000000..4b02b92
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8013874.js
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8013874: Function argument's prototype seem cached and wrongly reused
+ *
+ * @test
+ * @run
+ */
+
+function deepEqual(actual, expected) {
+    print("deepEqual: " + (actual.prop === expected.prop) + ", prop: " + expected.prop);
+}
+
+var proto = {};
+var other = {
+    prop: 0
+};
+
+function NameBuilder(first, last) {
+    this.first = first;
+    this.last = last;
+    return this;
+}
+
+NameBuilder.prototype = proto;
+
+function NameBuilder2(first, last) {
+    this.first = first;
+    this.last = last;
+    return this;
+}
+
+NameBuilder2.prototype = proto;
+
+var nb1 = new NameBuilder('Ryan', 'Dahl');
+var nb2 = new NameBuilder2('Ryan', 'Dahl');
+
+print("In loader, nb1.prop === nb2.prop " + (nb1.prop === nb2.prop));
+deepEqual(nb1, nb2);
+
+NameBuilder2.prototype = other;
+nb2 = new NameBuilder2('Ryan', 'Dahl');
+
+print("In loader, nb1.prop === nb2.prop " + (nb1.prop === nb2.prop));
+deepEqual(nb1, nb2);
diff --git a/nashorn/test/script/basic/JDK-8013874.js.EXPECTED b/nashorn/test/script/basic/JDK-8013874.js.EXPECTED
new file mode 100644
index 0000000..af1d1d6
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8013874.js.EXPECTED
@@ -0,0 +1,4 @@
+In loader, nb1.prop === nb2.prop true
+deepEqual: true, prop: undefined
+In loader, nb1.prop === nb2.prop false
+deepEqual: false, prop: 0
diff --git a/nashorn/test/script/basic/JDK-8013878.js b/nashorn/test/script/basic/JDK-8013878.js
new file mode 100644
index 0000000..81e39f9
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8013878.js
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8013878: ClassCastException in Regex
+ *
+ * @test
+ * @run
+ */
+
+var re = /(a)(b)(c)/;
+var str = 'abc';
+
+print(re.exec(str).length);
+print(re.exec(str).concat(['d', 'e', 'f']));
+print(re.exec(str).join('-'));
+print(re.exec(str).push('d'));
+print(re.exec(str).pop());
+print(re.exec(str).reverse());
+print(re.exec(str).shift());
+print(re.exec(str).sort());
+print(re.exec(str).slice(1));
+print(re.exec(str).splice(1, 2, 'foo'));
+print(re.exec(str).unshift('x'));
+print(re.exec(str).indexOf('a'));
+print(re.exec(str).lastIndexOf('a'));
+print(re.exec(str).every(function(a) {return a.length;}));
+print(re.exec(str).some(function(a) {return a.length;}));
+print(re.exec(str).filter(function(a) {return a.length;}));
+print(re.exec(str).forEach(function(a) {print(a)}));
+print(re.exec(str).map(function(a) {return a.length;}));
+print(re.exec(str).reduce(function(a, b) {return a + b}));
+print(re.exec(str).reduceRight(function(a, b) {return a + b}));
diff --git a/nashorn/test/script/basic/JDK-8013878.js.EXPECTED b/nashorn/test/script/basic/JDK-8013878.js.EXPECTED
new file mode 100644
index 0000000..7dbcf43
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8013878.js.EXPECTED
@@ -0,0 +1,24 @@
+4
+abc,a,b,c,d,e,f
+abc-a-b-c
+5
+c
+c,b,a,abc
+abc
+a,abc,b,c
+a,b,c
+a,b
+5
+1
+1
+true
+true
+abc,a,b,c
+abc
+a
+b
+c
+undefined
+3,1,1,1
+abcabc
+cbaabc
diff --git a/nashorn/test/script/basic/no_line_numbers.js b/nashorn/test/script/basic/no_line_numbers.js
new file mode 100644
index 0000000..bd18e4d
--- /dev/null
+++ b/nashorn/test/script/basic/no_line_numbers.js
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * no_line_numbers.js - make sure that switching off line number generation
+ * doesn't break. Otherwise, this is just NASHORN-73, a unit test particularly
+ * prone to label bugs in CodeGenerator
+ *
+ * @test
+ * @run
+ * @option --debug-lines=false
+ */
+
+print("x = " + x);
+do {
+   break;
+   var x;
+} while (true);
+
+
+print("y = " + y);
+while (true) {
+    break;
+    var y;
+}
+
+print("z = " + z);
+for ( ; ; ) {
+   break;
+   var z;
+   print("THIS SHOULD NEVER BE PRINTED!");
+}
+
+while (true) {
+    break;
+    if (true) { 
+	var s; 
+    }
+}
+
+print("s = "+s);
+
+print("u = "+u);
+for ( ; ; ) {
+    break;
+    while (true) {
+	do {
+	    var u;
+	} while (true);
+    }    
+}
+
+function terminal() {
+    print("r = "+r);
+    print("t = "+t);
+    for (;;) {
+	var r;
+	return;
+	var t;
+	print("THIS SHOULD NEVER BE PRINTED!");
+    }
+    print("NEITHER SHOULD THIS");
+}
+
+terminal();
+
+function terminal2() {
+    print("q = "+q);
+    for (;;) {
+	return;
+	print("THIS SHOULD NEVER BE PRINTED!");
+    }
+    print("NEITHER SHOULD THIS");
+}
+
+try { 
+    terminal2();
+} catch (e) {
+    print(e);
+}
+
+function scope2() {
+    var b = 10;
+    print("b = "+b);
+}
+
+scope2();
+
+try {
+    print("b is = "+b);
+}  catch (e) {
+    print(e);
+}
+	
+
+function disp_a() {
+    var a = 20;
+    print("Value of 'a' inside the function " + a);
+}
+	
+var a = 10;
+
+disp_a();
+
+print("Value of 'a' outside the function " + a);
diff --git a/nashorn/test/script/basic/no_line_numbers.js.EXPECTED b/nashorn/test/script/basic/no_line_numbers.js.EXPECTED
new file mode 100644
index 0000000..4a513f9
--- /dev/null
+++ b/nashorn/test/script/basic/no_line_numbers.js.EXPECTED
@@ -0,0 +1,12 @@
+x = undefined
+y = undefined
+z = undefined
+s = undefined
+u = undefined
+r = undefined
+t = undefined
+ReferenceError: "q" is not defined
+b = 10
+ReferenceError: "b" is not defined
+Value of 'a' inside the function 20
+Value of 'a' outside the function 10
diff --git a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java b/nashorn/test/script/basic/paramspec.js
similarity index 77%
copy from langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
copy to nashorn/test/script/basic/paramspec.js
index 06196c2..c0ea2a5 100644
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java
+++ b/nashorn/test/script/basic/paramspec.js
@@ -1,36 +1,38 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
+ * 
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.
- *
+ * 
  * This code is distributed in the hope that it will be useful, but WITHOUT
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * version 2 for more details (a copy is included in the LICENSE file that
  * accompanied this code).
- *
+ * 
  * You should have received a copy of the GNU General Public License version
  * 2 along with this work; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+ * 
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
 
-import javax.tools.annotation.GenerateNativeHeader;
+/**
+ * paramspec - test that Attr doesn't break parameters when specializing
+ *
+ * @run
+ * @test
+ */
 
-@GenerateNativeHeader
-public class TestClass2 {
-    byte b;
-    short s;
-    int i;
-    long l;
-    float f;
-    double d;
-    Object o;
-    String t;
+function f(a) {
+    var b = ~a;
+    return b == ~17;
 }
+
+print(f("17"));
+print(f(17));
+
diff --git a/nashorn/test/script/basic/paramspec.js.EXPECTED b/nashorn/test/script/basic/paramspec.js.EXPECTED
new file mode 100644
index 0000000..bb101b6
--- /dev/null
+++ b/nashorn/test/script/basic/paramspec.js.EXPECTED
@@ -0,0 +1,2 @@
+true
+true
diff --git a/nashorn/test/script/basic/runsunspider.js b/nashorn/test/script/basic/runsunspider.js
index 7f78797..149bd27 100644
--- a/nashorn/test/script/basic/runsunspider.js
+++ b/nashorn/test/script/basic/runsunspider.js
@@ -86,7 +86,7 @@
 	    changed = true;
 	}
     } catch (e) {
-	print("error: " + e);
+	print("error: " + e.printStackTrace());
 	if (e.toString().indexOf(tests) == 1) {
 	    throw e;
 	}
diff --git a/nashorn/test/script/trusted/logcoverage.js b/nashorn/test/script/currently-failing/logcoverage.js
similarity index 93%
rename from nashorn/test/script/trusted/logcoverage.js
rename to nashorn/test/script/currently-failing/logcoverage.js
index a2cd7a0..18b16aa 100644
--- a/nashorn/test/script/trusted/logcoverage.js
+++ b/nashorn/test/script/currently-failing/logcoverage.js
@@ -90,16 +90,17 @@
 
 function check(str, strs) {
     for each (s in strs) {
-       if (s.indexOf(str) !== -1) {
+       if (str.indexOf(s) !== -1) {
 	   continue;
        }
-       print(method + "not found");
+       print(s + " not found");
        return;
     }
     print("check ok!");
 }
 
 str = runScriptEngine([ "--log=codegen,compiler=finest,methodhandles=finest,fields=finest" ], __DIR__ + "../basic/NASHORN-19.js");
+str += runScriptEngine([ "--log=codegen,compiler=finest,methodhandles=finest,fields=finest" ], __DIR__ + "../basic/varargs.js");
 
 check(str, methodsCalled);
 check(str, ['return', 'get', 'set', '[fields]']);
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/AbstractScriptRunnable.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/AbstractScriptRunnable.java
index 3fd5c21..1d0e6fa 100644
--- a/nashorn/test/src/jdk/nashorn/internal/test/framework/AbstractScriptRunnable.java
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/AbstractScriptRunnable.java
@@ -117,7 +117,7 @@
     // run this test - compile or compile-and-run depending on option passed
     public void runTest() throws IOException {
         log(toString());
-
+        Thread.currentThread().setName(testFile.getPath());
         if (shouldRun) {
             // Analysis of failing tests list -
             // if test is in failing list it must fail
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/ParallelTestRunner.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/ParallelTestRunner.java
index cc0e1cd..d4269fc 100644
--- a/nashorn/test/src/jdk/nashorn/internal/test/framework/ParallelTestRunner.java
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/ParallelTestRunner.java
@@ -25,6 +25,7 @@
 
 package jdk.nashorn.internal.test.framework;
 
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_FAILED_LIST_FILE;
 import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_ENABLE_STRICT_MODE;
 import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_EXCLUDES_FILE;
 import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_EXCLUDE_LIST;
@@ -37,6 +38,7 @@
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.FileReader;
+import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
@@ -324,7 +326,8 @@
         });
     }
 
-    public void run() {
+    @SuppressWarnings("resource")
+    public boolean run() throws IOException {
         final int testCount = tests.size();
         int passCount = 0;
         int doneCount = 0;
@@ -371,23 +374,36 @@
         });
 
         boolean hasFailed = false;
-        for (final ScriptRunnable.Result result : results) {
-            if (!result.passed()) {
-                if (hasFailed == false) {
-                    hasFailed = true;
-                    System.out.println();
-                    System.out.println("FAILED TESTS");
-                }
+        final String failedList = System.getProperty(TEST_FAILED_LIST_FILE);
+        final boolean hasFailedList = failedList != null;
+        final boolean hadPreviouslyFailingTests = hasFailedList && new File(failedList).length() > 0;
+        final FileWriter failedFileWriter = hasFailedList ? new FileWriter(failedList) : null;
+        try {
+            final PrintWriter failedListWriter = failedFileWriter == null ? null : new PrintWriter(failedFileWriter);
+            for (final ScriptRunnable.Result result : results) {
+                if (!result.passed()) {
+                    if (hasFailed == false) {
+                        hasFailed = true;
+                        System.out.println();
+                        System.out.println("FAILED TESTS");
+                    }
 
-                System.out.println(result.getTest());
-                if (result.exception != null) {
-                    final String exceptionString = result.exception instanceof TestFailedError ? result.exception.getMessage() : result.exception.toString();
-                    System.out.print(exceptionString.endsWith("\n") ? exceptionString : exceptionString + "\n");
-                    System.out.print(result.out != null ? result.out : "");
+                    System.out.println(result.getTest());
+                    if(failedFileWriter != null) {
+                        failedListWriter.println(result.getTest().testFile.getPath());
+                    }
+                    if (result.exception != null) {
+                        final String exceptionString = result.exception instanceof TestFailedError ? result.exception.getMessage() : result.exception.toString();
+                        System.out.print(exceptionString.endsWith("\n") ? exceptionString : exceptionString + "\n");
+                        System.out.print(result.out != null ? result.out : "");
+                    }
                 }
             }
+        } finally {
+            if(failedFileWriter != null) {
+                failedFileWriter.close();
+            }
         }
-
         final double timeElapsed = (System.nanoTime() - startTime) / 1e9; // [s]
         System.out.printf("Tests run: %d/%d tests, passed: %d (%.2f%%), failed: %d. Time elapsed: %.0fmin %.0fs.\n", doneCount, testCount, passCount, 100d * passCount / doneCount, doneCount - passCount, timeElapsed / 60, timeElapsed % 60);
         System.out.flush();
@@ -397,12 +413,25 @@
         if (hasFailed) {
             throw new AssertionError("TEST FAILED");
         }
+
+        if(hasFailedList) {
+            new File(failedList).delete();
+        }
+
+        if(hadPreviouslyFailingTests) {
+            System.out.println();
+            System.out.println("Good job on getting all your previously failing tests pass!");
+            System.out.println("NOW re-running all tests to make sure you haven't caused any NEW test failures.");
+            System.out.println();
+        }
+
+        return hadPreviouslyFailingTests;
     }
 
     public static void main(final String[] args) throws Exception {
         parseArgs(args);
 
-        new ParallelTestRunner().run();
+        while(new ParallelTestRunner().run());
     }
 
     private static void parseArgs(final String[] args) {
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/TestConfig.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/TestConfig.java
index cf798f6..05d59dc 100644
--- a/nashorn/test/src/jdk/nashorn/internal/test/framework/TestConfig.java
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/TestConfig.java
@@ -72,4 +72,7 @@
 
     // shared context mode or not
     static final String TEST_JS_SHARED_CONTEXT              = "test.js.shared.context";
+
+    // file for storing last run's failed tests
+    static final String TEST_FAILED_LIST_FILE = "test.failed.list.file";
 }
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/TestFinder.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/TestFinder.java
index a326a59..776c4e7 100644
--- a/nashorn/test/src/jdk/nashorn/internal/test/framework/TestFinder.java
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/TestFinder.java
@@ -31,6 +31,7 @@
 import static jdk.nashorn.internal.test.framework.TestConfig.OPTIONS_EXPECT_RUN_FAIL;
 import static jdk.nashorn.internal.test.framework.TestConfig.OPTIONS_IGNORE_STD_ERROR;
 import static jdk.nashorn.internal.test.framework.TestConfig.OPTIONS_RUN;
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_FAILED_LIST_FILE;
 import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_ENABLE_STRICT_MODE;
 import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_EXCLUDES_FILE;
 import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_EXCLUDE_DIR;
@@ -41,7 +42,9 @@
 import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_ROOTS;
 import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_UNCHECKED_DIR;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileReader;
 import java.io.IOException;
 import java.nio.file.FileSystem;
 import java.nio.file.FileSystems;
@@ -86,6 +89,22 @@
     static <T> void findAllTests(final List<T> tests, final Set<String> orphans, final TestFactory<T> testFactory) throws Exception {
         final String framework = System.getProperty(TEST_JS_FRAMEWORK);
         final String testList = System.getProperty(TEST_JS_LIST);
+        final String failedTestFileName = System.getProperty(TEST_FAILED_LIST_FILE);
+        if(failedTestFileName != null) {
+            File failedTestFile = new File(failedTestFileName);
+            if(failedTestFile.exists() && failedTestFile.length() > 0L) {
+                try(final BufferedReader r = new BufferedReader(new FileReader(failedTestFile))) {
+                    for(;;) {
+                        final String testFileName = r.readLine();
+                        if(testFileName == null) {
+                            break;
+                        }
+                        handleOneTest(framework, new File(testFileName).toPath(), tests, orphans, testFactory);
+                    }
+                }
+                return;
+            }
+        }
         if (testList == null || testList.length() == 0) {
             // Run the tests under the test roots dir, selected by the
             // TEST_JS_INCLUDES patterns